一、要求:
创建玩家飞机,敌方飞机,均能发子弹,撞击后能移除相应对象。
二、思路:
类的定义以及具体需要实现的功能:
UI//窗体,控制玩家移动的鼠标监听器,刷新窗体的方法,Esc的键盘监听器,游戏的初始化,暂停等
UpdataCenter//刷新窗体的线程
MyPlane//玩家飞机,判断是否被敌人撞,被敌人子弹击中,控制背景移动
Bullet//玩家的子弹,控制自己移动,判断是否和敌方子弹相遇抵消
EnermyPlane//敌方飞机,父类,敌机移动以及出界的相应操作
EnermyPlaneLarge//敌方飞机大号,控制自己移动,判断是否被玩家子弹击中
EnermyPlaneMedium//敌方飞机中号,控制自己移动,判断是否被玩家子弹击中
EnermyPlaneSmall//敌方飞机小号,不发子弹,控制自己移动,判断是否被玩家子弹击中
EnermyThread//创建敌方飞机线程,不定时创建各类敌机的对象
SendShot//随机创建敌方子弹的线程,定时发送子弹攻击玩家
Shot//敌方子弹(自己控制发射)
其它功能:加入分数统计,关卡,生命等数据。
三、具体实现:
UI.java
定义属性:
static ArrayList<Bullet> bulList = new ArrayList<Bullet>();
static ArrayList<Shot> shotList = new ArrayList<Shot>();
static ArrayList<SendShot> ssList = new ArrayList<SendShot>();
static ArrayList<EnermyPlane> enermyList = new ArrayList<EnermyPlane>();
static int score = 0;
static int largeScore = 0;
static int pass = 1;
static int backgroundY = 0;
static boolean pause = false;//当Esc按下的时候暂停所有线程
在窗口上加入JPanel center。重写JPanel的paint()方法,便于重绘。
在paint里面便利队列 绘制所有飞机,子弹,分数等信息。
UpdataCenter.java
重写run()方法,不断center.repaint()。
MyPlane.java
定义属性:
int speed;//飞机移动速度,用键盘控制移动的时候会有用。
int x, y;//飞机当前所在位置,用这个来画,死了之后移到-100,-100。1s后移到xt,yt
int xt, yt;//保存飞机初始时出现的位置
int count = 0, count1 = 0;//用来控制发子弹和背景移动的时间间隔
static int lives = 3;//生命默认3条
int width, height;//飞机图片宽度和高度
boolean canDie = true;//己方每次被撞之后下一条生命有2s无敌时间
draw方法:
public void draw(Graphics g) { g.drawImage(myPlane.getImage(), x, y, width, height, null); }
判断是否被撞的方法以及被撞了之后的处理:
/** * 是否和敌方撞到 */ public void bump() { // 和任何一种飞机相撞 if (canDie) { // 判断是否游戏结束 for (int i = 0; i < UI.enermyList.size() && lives > 0; i++) { EnermyPlane eps = UI.enermyList.get(i); if ((eps.x + eps.width >= x && eps.x <= x + width && eps.y + eps.height / 2 >= y && eps.y <= y + height / 2 - 10) || (eps.x + eps.width / 2 + 20 >= x && eps.x + eps.width / 2 - 20 <= x + width && eps.y + eps.height >= y && eps.y <= y + height)) { UI.enermyList.remove(eps); haveBump(); return; } } // 和敌方子弹相撞 for (int i = 0; i < UI.shotList.size() && lives > 0; i++) { Shot st = UI.shotList.get(i); if (st.x + st.size >= x && st.x <= x + width && st.y + st.size >= y && st.y <= y + height) { UI.shotList.remove(st); haveBump(); } } } } /** * 被撞了 */ public void haveBump() { lives--; explode.play(); if (lives <= 0) { GameOver(); } // 撞到了就移除自己的飞机,过1s再加进来。并且前面2s不会再被撞死 x = -100; y = -100; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } x = xt; y = yt; canDie = false; }
其余方法:
backgroundMove();//控制背景移动
GameOver();//游戏结束的处理
重写run方法:
public void run() {
while (lives > 0) {
try {
if (!UI.pause) {
backgroundMove();
if (!canDie) {
Thread.sleep(2000);
canDie = true;
}//这2s不判断是否被撞
//BUG:这样的话不能发子弹,背景不能移动
bump();
if (count % 5 == 0) {
// 放子弹
Bullet bul = new Bullet(x + width / 2, y);
UI.bulList.add(bul);
new Thread(bul).start();
}
count++;
}
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Bullet.java
定义属性:
int speed;
int x, y;
boolean isLive;
int size = 10;
构造方法中初始化数据:
public Bullet(int x, int y) { speed = 15; this.x = x - size / 2; this.y = y; isLive = true; }
move方法:
void move() { y -= speed; if (y <= 0) { isLive = false; UI.bulList.remove(this); } }
在bump()中判断是否与敌方子弹相撞,重写Thread的run方法,在里面调用move();bump();
while (isLive) {
if (!UI.pause) {
move();
bump();
}
。。。
}
EnermyPlane.java
定义属性:
boolean isLive = true;
Random rd = new Random();
SendShot ss;
int second = rd.nextInt(3000) + 2000;// 发子弹
int x, y,speed;
int width,height;
public void moveDown() {
y += speed;
if (y > centerHeight) {//超过最下面了
isLive = false;
//从队列移除
UI.enermyList.remove(this);
}
}
public void draw(Graphics g){//在子类中实现
}
EnermyPlaneSmall.java(其余两类飞机一样的)
构造方法中初始化数据:
public EnermyPlaneSmall() {
speed = 2 + UI.pass;
isLive = true;
width = enermyPlaneSmall.getIconWidth() / 2;
height = enermyPlaneSmall.getIconHeight() / 2;
x = rd.nextInt(400);
y = -height;
//ss = new SendShot(this);//发子弹
//UI.ssList.add(ss);
//new Thread(ss).start();
}
在bump中判断是否被玩家子弹击中。
EnermyThread.java
run()中的关键代码:
while (MyPlane.lives > 0) {// 我方还存在生命 // 每隔5s出3-6个小的,共出4-6次. if (!UI.pause) { for (int k = 0; k < 2; k++) { for (int j = 0; j < rd.nextInt(4) + 2 && MyPlane.lives > 0; j++) { for (int i = 0; i < rd.nextInt(3) + 3; i++) { EnermyPlaneSmall eps = new EnermyPlaneSmall(); UI.enermyList.add(eps); new Thread(eps).start(); } Thread.sleep(4000); } // 出2个中的 for (int i = 0; i < 2 && MyPlane.lives > 0; i++) { EnermyPlaneMedium epm = new EnermyPlaneMedium(); UI.enermyList.add(epm); new Thread(epm).start(); } Thread.sleep(3000); } // 出来一个Boss if (MyPlane.lives > 0) { EnermyPlaneLarge epl = new EnermyPlaneLarge(); UI.enermyList.add(epl); new Thread(epl).start(); } } }
SendShot.java
在run中生成Shot对象,并Thread.sleep(ep.second);
如果这个飞机被打死了,这个对象就移出队列,且不再生成Shot对象了。
Shot.java
定义属性:
int size = 4;
EnermyPlane ep;
int speed = 8;
int x, y;
boolean isLive = true;
@Override public void run() { while (isLive) { if (!UI.pause) { isLive = ep.isLive; moveDown(); } try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } if (!ep.isLive) {// 清除剩余的子弹 UI.shotList.remove(this); } } void draw(Graphics g) { g.setColor(Color.white); g.fillOval(ep.x + ep.width / 2, y, size, size); } public void moveDown() { y += speed; if (y >= 600) { UI.shotList.remove(this); } }
附上效果图:
当前已知bug:
撞击判断有很大的误差,最高分有时候会比分数小,游戏结束了后还不能重新开始,玩家挂了一次之后2s无敌时间导致不能发子弹而且背景也不动。
相关推荐
java 模拟 微信 浏览器访问web页面.
微信打飞机图片,音效素材!
java仿微信打飞机,Java 版飞机射击游戏 游戏的代码重新写的,和微信关联不大,不过调用了微信打飞机中的图片资源,正是因为调用了这些资源,使用游戏运行过程中不太顺畅,可能是图片资源过大所致。 本源码主要是...
cocos2dx之微信打飞机 ,,,,博客地址:http://blog.csdn.net/kuloveyouwei
纯javascript模仿微信打飞机游戏代码 纯javascript模仿微信打飞机游戏代码
java版的微信打飞机。对于初学Java的还是听有帮助的,里面用了Java简单的图形编程,以及一些接口和抽象类的使用,简单用了下装饰者模式和生产者模式,当然代码还是有很多重用厉害的地方,这也是以后需要不断改进的,...
最新的微信打飞机小游戏素材,包含工程文件,素材图片,音视频资源等。
实训项目,网页版微信打飞机
微信打飞机源码,原生JS手打,扩展性高,前端必学套路
高仿微信打飞机,添加打斗的音乐(原来是无声音的),包括背景音乐,发射子弹的声效,飞机爆炸的声效等等。更像微信的打飞机了。
微信游戏打飞机 项目详细的 java源代码
java模拟微信打飞机游戏,大家参考使用吧
微信打飞机源代码!
编写微信打飞机小游戏图片音效资源,包括用到的图片声音文件
微信公众平台的开发教程,用Java写的,挺有借鉴的意义
完整的微信打飞机游戏,用JavaScript与css div布局写的,注释也非常详细
cocos3.2微信打飞机,亲测可用。
这是一款安卓仿照微信打飞机的源码,基于cocos2d开发,代码比较简单
基于J2EE开发,适合想开发完整微信项目的人学习,非常具有学习参考价值。 功能包含咨询帮助消息、使用帮助、找自习室、公告查询、图书检索、新书通告、图片新闻、动态信息、通知公告、最新校报、听广播、点歌、课表...