您的位置:首页 > 移动开发 > 微信开发

模仿微信打飞机做的程序

2013-09-18 15:40 375 查看
学校请了达内来培训8天(其实是学校和培训机构各取所需),主要学了JPanel类。

上主要代码:

JPanel画板

package com.raikou.practise.plane;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.Timer;
import javax.swing.JPanel;

public class PlaneJPanel extends JPanel implements MouseMotionListener,
MouseListener {

/**
*
*/
private static final long serialVersionUID = -3729222788769506535L;
private int time = 0, timepre = 0;
private List<Enemys> newenemys;
private List<Bullet> newbullet;
private List<PlaneExplode> newPE;
private List<Supplies> newS;
private int px = 180, py = 450; //本机的坐标
private int boomnum = 0;
private int doubleBulletstime = 0;
private boolean isend = false;
private boolean isstart = false;
private boolean issuspend = false;
private boolean isdoubleBullets = false;
private int score = 0;
private Timer timer, timer2, timerpre;
private PlaySound BGM;
private PlaySound BulletM;
private PlaySound ButtonM;
private PlaySound EDM1;
private PlaySound EDM2;
private PlaySound EDM3;
private PlaySound GBM;
private PlaySound GDLM;
private PlaySound UBM;
private int BGy = -252;
private int BGx;
private Image SI;
private Image BGI;
private Font font;

public PlaneJPanel() {

BGx = 150;
// 创建计时器
timerpre = new Timer(1000, new TimerPre());
timer = new Timer(80, new TimerListener());
timer2 = new Timer(80, new Timercounter());
// 初始化各变量
newenemys = new ArrayList<Enemys>();
newbullet = new ArrayList<Bullet>();
newPE = new ArrayList<PlaneExplode>();
newS = new ArrayList<Supplies>();
SI = new ImageIcon("./images/shoot.png").getImage();
BGI = new ImageIcon("./images/shoot_background.png").getImage();

font = new Font("黑体", Font.BOLD, 24);
// 创建音乐线程
MusicInit();
// 添加监听
this.addMouseMotionListener(this);
this.addMouseListener(this);
// 开启游戏线程
startGame();
timerpre.start();
}

public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(10));
g2.setColor(Color.BLACK);
g2.setFont(font);
// 背景图
g.drawImage(BGI, 0, BGy, 480, BGy + 852, 0, 75, 480, 927, null);
g.drawImage(BGI, 0, BGy - 852, 480, BGy, 0, 75, 480, 927, null);
// 欢迎页
if (!isstart) {
g.drawImage(BGI, 22, getHeight() / 2 - 112, 456,
getHeight() / 2 + 113, 484, 702, 918, 927, null);
if (timepre % 3 == 0)
g.drawImage(BGI, 151, getHeight() / 2 + 147, 200,
getHeight() / 2 + 182, 0, 38, 49, 73, null);
else if (timepre % 3 == 1)
g.drawImage(BGI, 151, getHeight() / 2 + 147, 265,
getHeight() / 2 + 182, 0, 0, 114, 35, null);
else
g.drawImage(BGI, 151, getHeight() / 2 + 147, 329,
getHeight() / 2 + 182, 489, 666, 667, 701, null);
// g.drawImage(BGW1, BGx, getHeight()/2+147, null);

} else {

timer.start();
timer2.start();
for (int i = 0; i < newbullet.size(); i++) {
newbullet.get(i).drawBullet(g);
}

for (int i = 0; i < newenemys.size(); i++) {
newenemys.get(i).drawEnemys(g);
}

for (int i = 0; i < newPE.size(); i++) {
newPE.get(i).drawExplode(g);
}

for (int i = 0; i < newS.size(); i++) {
newS.get(i).drawSupplies(g);
}
if (boomnum >= 0) {
g.drawImage(SI, 10, 520, 71, 574, 812, 694, 872, 745, null);
g2.drawString("X" + boomnum, 75, 560);
}
if (!isend) {
g.drawImage(SI, px, py, px + 98, py + 124, 2, 100, 100, 224,
null);

} else
g2.drawString("Game Over", getWidth() / 2 - 50,
getHeight() / 2 - 10);
if (!issuspend)
g.drawImage(SI, 5, 0, 46, 41, 275, 252, 316, 293, null);
else
g.drawImage(SI, 5, 0, 46, 41, 819, 648, 860, 689, null);
g2.drawString("" + score, 60, 30);
}

}

public void startGame() {

new Thread() {
public void run() {
try {
sleep(100);
} catch (InterruptedException e1) {
// TODO 自动生成的 catch 块
e1.printStackTrace();
}
while (true) {
while (isstart && !isend && !issuspend) {
BGy++;
if (BGy >= 600)
BGy = -252;
// 判断子弹和敌机的撞击,机型1撞击次数1次,机型2撞击次数6次,机型3撞击次数12次,满次数后敌机爆炸
for (int i = 0; i < newbullet.size(); i++) {
newbullet.get(i).startBullet();
if (newbullet.get(i).getBy() <= 0)
newbullet.remove(i);
else
for (int j = 0; j < newenemys.size(); j++) {
if (newenemys.get(j).getType() == 1) {
if ((newbullet.get(i).getBy()
- newenemys.get(j).getY() <= 36 && newbullet
.get(i).getBy()
- newenemys.get(j).getY() >= 0)
&& (newbullet.get(i).getBx()
- newenemys.get(j)
.getX() >= 0 && newbullet
.get(i).getBx()
- newenemys.get(j)
.getX() <= 39)) {
if (newenemys.get(j).getHit() > 0) {
newenemys.get(j).setHit(
newenemys.get(j)
.getHit() - 1);
}
if (newenemys.get(j).getHit() == 0) {
newPE.add(new PlaneExplode(
newenemys.get(j).getX(),
newenemys.get(j).getY(),
newenemys.get(j)
.getType()));
score += newenemys.get(j)
.getScore();
EDM1.Play();
newenemys.remove(j);

}
newbullet.remove(i);

break;
}
} else if (newenemys.get(j).getType() == 2) {
if ((newbullet.get(i).getBy()
- newenemys.get(j).getY() <= 93 && newbullet
.get(i).getBy()
- newenemys.get(j).getY() >= 0)
&& (newbullet.get(i).getBx()
- newenemys.get(j)
.getX() >= 0 && newbullet
.get(i).getBx()
- newenemys.get(j)
.getX() <= 59)) {
if (newenemys.get(j).getHit() > 0) {
newenemys.get(j).setHit(
newenemys.get(j)
.getHit() - 1);
newenemys.get(j).setHited(
!newenemys.get(j)
.isHited());
}
if (newenemys.get(j).getHit() == 0) {
newPE.add(new PlaneExplode(
newenemys.get(j).getX(),
newenemys.get(j).getY(),
newenemys.get(j)
.getType()));
score += newenemys.get(j)
.getScore();
EDM2.Play();
newenemys.remove(j);

}
newbullet.remove(i);

break;
}
} else {
if ((newbullet.get(i).getBy()
- newenemys.get(j).getY() <= 256 && newbullet
.get(i).getBy()
- newenemys.get(j).getY() >= 0)
&& (newbullet.get(i).getBx()
- newenemys.get(j)
.getX() >= 0 && newbullet
.get(i).getBx()
- newenemys.get(j)
.getX() <= 146)) {
if (newenemys.get(j).getHit() > 0) {
newenemys.get(j).setHit(
newenemys.get(j)
.getHit() - 1);
newenemys.get(j).setHited(
!newenemys.get(j)
.isHited());
}
if (newenemys.get(j).getHit() == 0) {
newPE.add(new PlaneExplode(
newenemys.get(j).getX(),
newenemys.get(j).getY(),
newenemys.get(j)
.getType()));
score += newenemys.get(j)
.getScore();
EDM3.Play();
newenemys.remove(j);

}
newbullet.remove(i);

break;
}
}
}

}
// 本机的爆炸效果
for (int i = 0; i < newenemys.size(); i++) {
newenemys.get(i).startMoving();
if (newenemys.get(i).getY() >= 600)
newenemys.remove(i);
else {
if (newenemys.get(i).getType() == 1) {
if ((newenemys.get(i).getX() - px >= -28 && newenemys
.get(i).getX() - px <= 48)
&& (py - newenemys.get(i).getY() <= 34 && py
- newenemys.get(i).getY() >= -124)) {
newPE.add(new PlaneExplode(px, py, 0));
isend = true;
}
} else if (newenemys.get(i).getType() == 2) {
if ((newenemys.get(i).getX() - px >= -40 && newenemys
.get(i).getX() - px <= 28)
&& (py - newenemys.get(i).getY() <= 93 && py
- newenemys.get(i).getY() >= -124)) {
newPE.add(new PlaneExplode(px, py, 0));
isend = true;
}
} else if (newenemys.get(i).getType() == 3) {
if ((newenemys.get(i).getX() - px >= -90 && newenemys
.get(i).getX() - px <= -68)
&& (py - newenemys.get(i).getY() <= 256 && py
- newenemys.get(i).getY() >= -124)) {
newPE.add(new PlaneExplode(px, py, 0));
isend = true;
}
}
}

}
// 显示完爆炸效果后消失
for (int i = 0; i < newPE.size(); i++) {
if (newPE.get(i).getTime() >= 6)
newPE.remove(i);
}
// 控制补给品
for (int i = 0; i < newS.size(); i++) {
newS.get(i).startMoving();
if ((newS.get(i).getX() - px >= -newS.get(i)
.getWidth() + 10 && newS.get(i).getX() - px <= 88 + newS
.get(i).getWidth())
&& (py - newS.get(i).getY() <= newS.get(i)
.getHeight() && py
- newS.get(i).getY() >= -102)) {
if (newS.get(i).getType() == 1) {
isdoubleBullets = true;
doubleBulletstime = 50;
GDLM.Play();
} else {
GBM.Play();
boomnum++;
}
newS.remove(i);
}
}

try {
sleep(20);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
repaint();
}
repaint();

}
}
}.start();
}

public void setIsstart(boolean isstart) {
this.isstart = isstart;
}

@Override
public void mouseDragged(MouseEvent e) {
// TODO 自动生成的方法存根
// 滑动开始
if (!isstart) {
if ((e.getY() >= getHeight() / 2 + 147 && e.getY() <= getHeight() / 2 + 182)
&& (e.getX() >= 150 && e.getX() <= 285))
BGx = e.getX();
if (BGx >= 283) {
isstart = true;
issuspend = false;
}
}

if (isstart) {
px = e.getX() - 49;
py = e.getY() - 62;

repaint();
}
}

public void MusicInit() {
BGM = new PlaySound(new File("./sound/game_music.mp3"));
BulletM = new PlaySound(new File("./sound/bullet.mp3"));
ButtonM = new PlaySound(new File("./sound/button.mp3"));
EDM1 = new PlaySound(new File("./sound/enemy1_down.mp3"));
EDM2 = new PlaySound(new File("./sound/enemy2_down.mp3"));
EDM3 = new PlaySound(new File("./sound/enemy3_down.mp3"));
GBM = new PlaySound(new File("./sound/get_bomb.mp3"));
GDLM = new PlaySound(new File("./sound/get_double_laser.mp3"));
UBM = new PlaySound(new File("./sound/use_bomb.mp3"));
BGM.Play();
}

@Override
public void mouseMoved(MouseEvent e) {
// TODO 自动生成的方法存根

}

class Timercounter implements ActionListener {

public void actionPerformed(ActionEvent e) {
for (int i = 0; i < newPE.size(); i++) {
newPE.get(i).setTime(newPE.get(i).getTime() + 1);
}
}
}

class TimerPre implements ActionListener {

public void actionPerformed(ActionEvent e) {
timepre++;
}
}

class TimerListener implements ActionListener {

public void actionPerformed(ActionEvent e) {
time++;
if (!isend && isstart && !issuspend) {
if (!isdoubleBullets) {
newbullet.add(new Bullet(px + 48, py, 1));
BulletM.Play();
} else {
if (doubleBulletstime > 0) {
newbullet.add(new Bullet(px + 33, py, 2));
newbullet.add(new Bullet(px + 63, py, 2));
BulletM.Play();
doubleBulletstime--;
} else
isdoubleBullets = false;
}
if (Math.random() > 0.9) {
double typerandom = Math.random();
if (typerandom < 0.85)
newenemys.add(new Enemys((int) (Math.random() * 380),
-36, 1));
else if (typerandom < 0.99)
newenemys.add(new Enemys((int) (Math.random() * 430),
-93, 2));
else
newenemys.add(new Enemys((int) (Math.random() * 285),
-256, 3));
}
if (time > 100 && Math.random() > 0.995) {

double typerandom = Math.random();
if (typerandom < 0.7)
newS.add(new Supplies((int) (Math.random() * 380), 25,
1));
else
newS.add(new Supplies((int) (Math.random() * 380), 25,
2));
}
}
}
}

@Override
public void mouseClicked(MouseEvent e) {
// TODO 自动生成的方法存根
if ((e.getY() >= 0 && e.getY() <= 41)
&& (e.getX() >= 5 && e.getX() <= 46)) {
issuspend = !issuspend;
ButtonM.Play();
}
if (!issuspend)
if ((e.getY() >= 520 && e.getY() <= 574)
&& (e.getX() >= 10 && e.getX() <= 80) && boomnum > 0) {
UBM.Play();
for (int i = 0; i < newenemys.size(); i++) {
newPE.add(new PlaneExplode(newenemys.get(i).getX(),
newenemys.get(i).getY(), newenemys.get(i).getType()));
score += newenemys.get(i).getScore();

}
newenemys.removeAll(newenemys);
}
}

@Override
public void mousePressed(MouseEvent e) {
// TODO 自动生成的方法存根

}

@Override
public void mouseReleased(MouseEvent e) {
// TODO 自动生成的方法存根

}

@Override
public void mouseEntered(MouseEvent e) {
// TODO 自动生成的方法存根

}

@Override
public void mouseExited(MouseEvent e) {
// TODO 自动生成的方法存根

}

}


敌机,子弹,补给品,和飞机爆炸效果4个类都放在集合里,个人感觉在这里用集合比数组方便,因为并不知道会有多少个元素,而且感觉打开程序的速度也有提升(后来加上音乐后又变慢了- -).计时器控制一下如敌机,补给品和子弹的出现频率,还有控制爆炸画面不能太快。敌机和补给品的出现率还有Math.Random()控制,可以根据时间或分数来调整概率。

敌机类(子弹类等类似)

package com.raikou.practise.plane;

import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;

public class Enemys {
private int y;
private int x;
private int type;
private int score;
private int hit;
private boolean isHited = false;
private Image enemyplane;

public Enemys(int x, int y, int type) {
super();
this.y = y;
this.x = x;

this.type = type;
switch (type) {
case 1:
score = 1000;
hit = 1;
break;
case 2:
score = 6000;
hit = 6;
break;
case 3:
score = 30000;
hit = 12;
break;
default:
break;
}
enemyplane = new ImageIcon("./images/shoot.png").getImage();
}

public int getHit() {
return hit;
}

public void setHit(int hit) {
this.hit = hit;
}

public void drawEnemys(Graphics g) {
if (!isHited) {
if (type == 1)
g.drawImage(enemyplane, x, y, x + 49, y + 40, 539, 613, 588,
653, null);
else if (type == 2)
g.drawImage(enemyplane, x, y, x + 69, y + 93, 0, 0, 69, 93,
null);
else if (type == 3)
g.drawImage(enemyplane, x, y, x + 165, y + 256, 338, 750, 503,
1006, null);
} else {
if (type == 1)
g.drawImage(enemyplane, x, y, x + 49, y + 40, 539, 613, 588,
653, null);
else if (type == 2)
g.drawImage(enemyplane, x, y, x + 69, y + 93, 432, 529, 501,
622, null);
else if (type == 3)
g.drawImage(enemyplane, x, y, x + 165, y + 256, 165, 750, 330,
1006, null);

}
}

public boolean isHited() {
return isHited;
}

public void setHited(boolean isHited) {
this.isHited = isHited;
}

public void startMoving() {
if (type == 1)
y += 4;
else if (type == 2)
y += 3;
else
y += 2;
}

public int getScore() {
return score;
}

public int getType() {
return type;
}

public int getY() {
return y;
}

public int getX() {
return x;
}

}


这个类包含敌机的一些基本属性,如何坐标,大小,还有运动轨迹和速度。碰撞的判断写在PlaneJPanel的线程中。

成品:
http://yunpan.cn/QCBrHusDXyHpj 访问密码 80c7

本人新手,欢迎各种建议和讨论,大神勿喷。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: