🚀个人主页:j欢迎访问Ali.S的主页
📆 最近更新:2022年7月12日
⛽ Java框架学习系列:Mybatis框架
⛳ Java基础学习系列:面向对象飞机大战
🏆 通信仿真学习系列:【硬件】【通信】【MATLAB】
🍄 个人简介:通信工程本硕🌈、Java程序员🚴。目前只会CURD😂
💌 点赞 👍 收藏 💗留言 💬 都是我最大的动力💯
文章目录
一、前情回顾
前面已经完成了主页面的编写和敌机的移动,在框架中能够显示出敌机的移动和英雄机、子弹的位置,以及分数和血量的显示。今天在前面的基础上继续完成英雄机、敌机、子弹的操作,前面操作请看上一篇看我如何一步一步做飞机大战(一)
二、主要实现
1.子弹入场
创建子弹对象,完成子弹入场的方法。由于随机生成子弹,并且是一直在游戏结束之前产生,所以这里使用了集合的来声子弹大本营,也可以使用数组来完成,只是数组的长度需要考虑,涉及到数组的扩容和缩容,相对来说数组操作起来稍微麻烦一点,过程是大同小异的。count是用来控制敌机入场的速度的,防止出现密集恐惧页面,不然敌机说我压力太大了。当然还可以设置同时出现多排子弹,通过int dir=0,1,2来设置三排子弹,具体每排子弹怎么移动就是控制在每个方向的速度不同。
int count=0;
protected void FireEnter() {
count++;
if (count>5){
//创建子弹对象
Fire fire=new Fire(hero);
//将子弹加入到大本营中
fs.add(fire);
count=0;
}
}
2.子弹的移动
完成子弹的入场后,就要考虑子弹的移动方式了,具体是怎么动的,可以根据自己的想法来设置,可以是沿直线,也可以是曲线,或者其他的方式,主要是通过不同方向的速度变化来完成想要的效果,要是想要散弹效果,可以设置在x和y方向上speed来实现,这里是写的沿直线运动。注意子弹是向上移动,恰好跟敌机相反。
protected void FireMove() {
//连续产生子弹
for (int i=0;i<fs.size();i++){
fs.get(i).y-=10;
}
}
3.判断子弹击中敌机
当把子弹做好后,子弹库中的子弹发射了,就开始做击中效果判断,看是否击中敌机,因为每一颗子弹都有可能击中敌机,所以要遍历所有敌机。这里判断击中效果是通过边界条件来做的,当击中时,敌机就消失。
private boolean FireShoot(Fire fire) {
//遍历所有敌机
for (int i=0;i<eps.size();i++){
//判断是否击中该敌机
if ((fire.y-eps.get(i).h<=eps.get(i).y)&&
(((eps.get(i).x-fire.x<=fire.w)&&(eps.get(i).x-fire.x>0))||
((fire.x-eps.get(i).x<=eps.get(i).w)&&(fire.x-eps.get(i).x>0)))){
//敌机消失
eps.remove(eps.get(i));
return true;
}
}
return false;
}
4.子弹击中敌机
因为所有子弹都可能击中任意一架敌机,所以遍历所有子弹,如果判断成功,就执行子弹消失,分数增加的操作。
protected void FireHit() {
//遍历所有子弹
for (int i=0;i<fs.size();i++){
//判断子弹是否击中敌机
if (FireShoot(fs.get(i))){
//子弹消失
fs.remove(fs.get(i));
//分数增加
score+=10;
}
}
}
5.判断英雄机与敌机碰撞
通过上面的子弹与敌机的碰撞操作,这里英雄机与敌机的操作是类似的,通过遍历敌机来做判断,碰撞成功,就让敌机消失。
private boolean HeroHitOut(Hero hero) {
//遍历所有敌机
for (int i=0;i< eps.size();i++){
if ((hero.y-eps.get(i).h<=eps.get(i).y)&&
(((eps.get(i).x-hero.x<=hero.w)&&(eps.get(i).x-hero.x>0))||
((hero.x-eps.get(i).x<=eps.get(i).w)&&(hero.x-eps.get(i).x>0)))){
eps.remove(eps.get(i));
return true;
}
}
return false;
}
6.英雄机与敌机碰撞
当英雄机与敌机发生了碰撞,敌机消失后,英雄机血量减少,分数增加,类似子弹与敌机碰撞成功后的操作。
protected void HeroHit() {
//判断是否撞击
if (HeroHitOut(hero)){
//英雄机命数减少
hero.hp--;
//分数增加
score+=5;
}
}
7.判断英雄机死亡
判断英雄机是否死亡,是为了后续做重新开始游戏做准备,如果英雄机血量为0了,就需要重新开始游戏,设置了游戏状态gameover为true。
private boolean isHeroOver() {
if (hero.hp==0){
gameover=true;
return true;
}
return false;
}
8.重新开始游戏
当英雄机的血量下降到0时,就需要重新绘制游戏页面,这里需要将页面上的所有对象都清空,通过鼠标点击事件来完成游戏重新开始。
public void ReStartPaint(Graphics g){
if (gameover){
g.setColor(Color.red);
g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,30));
g.drawString("GAMEOVER",175,300);
g.setColor(Color.yellow);
g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,30));
g.drawString("您本次的游戏得分为:"+score,115,330);
restart=App.getImg("图片路径");
g.drawImage(restart,125,380,null);
}
}
9.鼠标点击事件监听
这里创建了鼠标监听器,用于监听鼠标的点击事件,当鼠标点击游戏结束页面的重新开始图标时,就将所有对象清空,重新开始新的游戏。
//创建鼠标监听对象
MouseAdapter adapter=new MouseAdapter() {
@Override//点击事件
public void mouseClicked(MouseEvent e){
if (gameover){
hero=new Hero();
gameover=false;
score=0;
bg=App.getImg("图片路径");
eps=new ArrayList<>();
fs=new ArrayList<>();
repaint();
}
}
//将鼠标对象加入到监听事件中
addMouseListener(adapter);
addMouseMotionListener(adapter);
}
10.键盘移动事件监听
鼠标监听事件完成了,这里多做了一步键盘监听事件,通过键盘上的不同按键,来完成英雄机的不同操作,注意这里跟鼠标监听事件添加监听的区别 gameFrame.addKeyListener(keyAdapter);需要加到框架中。
//创建键盘监听对象
KeyAdapter keyAdapter=new KeyAdapter() {
//键盘监听事件
@Override
public void keyPressed(KeyEvent e) {
//判断按的不同的键来调用不同的移动方法
if (e.getKeyCode()==KeyEvent.VK_D){
hero.MoveRight();
}else if (e.getKeyCode()==KeyEvent.VK_A){
hero.MoveLeft();
}else if (e.getKeyCode()==KeyEvent.VK_S){
hero.MoveDown();
}else if(e.getKeyCode()==KeyEvent.VK_W){
hero.MoveUp();
}
repaint();
}
};
//将键盘对象加入到窗体监听事件中
gameFrame.addKeyListener(keyAdapter);
11.主线程启动
前面所有准备工作都完成了,最后就要实现主线程操作了,调用前面的方法,逐步实现游戏效果。判断游戏没有结束就执行循环操作。
//主要逻辑实现
public void action(){
//创建线程,控制对象移动
new Thread(() -> {
while(true){
//游戏是否结束
if (!isHeroOver()) {
//敌机入场方法调用
EpEnter();
//敌机移动
EpMove();
//子弹入场方法调用
FireEnter();
//子弹移动
FireMove();
//子弹击中敌机判断
FireHit();
//英雄机撞击敌机
HeroHit();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
//重新绘制页面
repaint();
}
}).start();
}
三、总结
做到这里就完成了飞机大战的基本有操作,简单版的飞机大战就实现了,后面计划继续完善更多的其它功能,后续操作请看下一篇。需要源码请移步:源码