Java基础 - 坦克大战(第五章,坦克移动、与被击中效果功能)
2022/1/20 22:43:49
本文主要是介绍Java基础 - 坦克大战(第五章,坦克移动、与被击中效果功能),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 坦克大战0.3
- 新建Shot类
- 坦克大战0.4版
- 1.让敌人坦克发射子弹(多颗子弹)
- 思路
- 2.当我方坦克击中敌人坦克时,敌人的坦克就消失
- 3.实现敌人坦克爆炸后消失
- 注意图片位置
- 4.实现敌人坦克自由移动
- 5.实现坦克站规定范围内移动
坦克大战0.3
陆游曾说:纸上得来终觉浅,绝知此事要躬行。前面已经了解Java线程基础知识,现在我们来实际运用一下。
在坦克大战游戏(0.2版)基础上添加如下功能:当玩家按一下j键,就发射一颗子弹。
- 为了能射出子弹,需要把每个子弹做成一个线程,并根据KeyListener事件判断用户输入,之后循环判断子弹位置,repaint()子弹,并要根据坦克的每个方向调整x,y轴
新建Shot类
package tankgame3; /** * Create By 刘鸿涛 * 2022/1/17 5:19 */ public class Shot implements Runnable{ int x; //子弹x坐标 int y; //子弹y坐标 int direct = 0; //子弹方向 int speed = 2; //子弹速度 boolean isLive = true; //子弹是否存活 public Shot(int x, int y, int direct) { this.x = x; this.y = y; this.direct = direct; } @Override public void run() { //射击 while (true){ //子弹休眠 try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } //根据方向来改变x,y坐标 switch (direct){ case 0://上 y -= speed; break; case 1://右 x += speed; break; case 2://下 y += speed; break; case 3://左 x -= speed; break; } //测试,这里我们输出x,y坐标 System.out.println("子弹 x = " + x + " y= " + y); //当子弹移动到面板 if (!(x >= 0 && x <= 1000 && y >= 0 && y <= 750)){ isLive = false; break; } } } }
坦克大战0.4版
- 增加功能
- 让敌人的坦克也能够发射子弹(可以有多颗子弹)
- 当我方坦克击中敌人坦克时,敌人的坦克就消失,如果能做出爆炸效果更好
- 让敌人的坦克也可以自由随机的上下左右移动
- 控制我方的坦克和敌人的坦克在规定的范围移动
- 特别说明
- 只要能实现就行,方法的好坏我们后面评讲
- 完成上面的任务,不会有没有讲过的知识点,这里主要是锻炼大伙灵活运用技术点能力
- 一定要自己先动脑筋想想,试着做做。再听老师的评讲才有意义,时间自己掌控(再次提醒,一定要先自己思考,再听老师讲收获会很大)
1.让敌人坦克发射子弹(多颗子弹)
思路
- 为了使敌方坦克射出子弹,需要把敌方坦克的所有子弹做成一个线程集合里,这里的集合我们用的vector(为了线程安全),敌人坦克是一个独立的集合,敌人子弹也是一个独立的集合,每个子弹线程都被Thread代理,并执行start()。根据判断敌人坦克子弹的状态,判断是否需要移出此线程集合元素,比如是否碰到边缘、是否碰到玩家、是否碰到障碍物
EnemyTank类
Vector<Shot> shots = new Vector<>();
MyPanel类无参构造器
public MyPanel(){ hero = new Hero(500,500); //初始化自己的坦克 hero.setSpeed(50); //初始化坦克速度 //初始化敌人坦克 for (int i = 0; i < enemyTanksSize; i++) { //创建一个敌人的坦克 EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0); //设置方向 enemyTank.setDirect(2); //给该enemyTank 加入一颗子弹 Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect()); //加入enemyTank的Vector 成员 enemyTank.shots.add(shot); //启动 shot 对象 new Thread(shot).start(); //加入坦克 enemyTanks.add(enemyTank); } }
MyPanel类paint()方法
@Override public void paint(Graphics g){ super.paint(g); g.fillRect(0,0,1000,750); //填充矩形,默认黑色 //画出坦克 - 封装方法 //自己的坦克 drawTank(hero.getX(),hero.getY(),g,hero.getDirect(),1); //type坦克类型 //画出hero射击的子弹 if (hero.shot != null && hero.shot.isLive == true){ g.draw3DRect(hero.shot.x,hero.shot.y,5 ,5,false); } //画出敌人的坦克,遍历Vector for (int i = 0; i < enemyTanks.size(); i++) { //取出坦克 EnemyTank enemyTank = enemyTanks.get(i); drawTank(enemyTank.getX(),enemyTank.getY(),g,enemyTank.getDirect(),0); //画出 enemyTank 所有子弹 for (int j = 0; j < enemyTank.shots.size(); j++){ //取出子弹 Shot shot = enemyTank.shots.get(j); //绘制 if (shot.isLive){ //isLive 为 true g.draw3DRect(shot.x,shot.y,2,2,false); }else { //从Vector 移除 enemyTank.shots.remove(shot); } } } }
2.当我方坦克击中敌人坦克时,敌人的坦克就消失
实现子弹击中敌方坦克消失,我们需要写一个方法,判断我方子弹是否碰到敌方坦克,需要考虑敌方坦克面向问题。我们在paint方法中也加入判断语句,如果上面条件为真,则返回敌方坦克isLive属性为false,根据情况paint敌方坦克是否执行。而我们的线程集合每隔100毫秒遍历一次敌方坦克集合,刷新整个游戏区域,实现敌方坦克被击中后消失
hitTank()方法
public static void hitTank(Shot s, EnemyTank enemyTank){ //判断 s 击中坦克 switch (enemyTank.getDirect()){ case 0: //坦克向上 case 2: //坦克向下 if(s.x > enemyTank.getX() && s.x < enemyTank.getX() + 40 && s.y > enemyTank.getY() && s.y < enemyTank.getY() + 60){ s.isLive = false; enemyTank.isLive = false; } break; case 1: //坦克向右 case 3: //坦克向左 if(s.x > enemyTank.getX() && s.x < enemyTank.getX() + 60 && s.y > enemyTank.getY() && s.y < enemyTank.getY() + 40){ s.isLive = false; enemyTank.isLive = false; } break; } }
3.实现敌人坦克爆炸后消失
当敌方坦克被击中后出现爆炸效果,我们新建一个爆炸效果类,这个类需要有x,y大小,需要一个生命周期的方法,来让爆炸效果动态化。当然了,我们的爆炸效果也在一个集合中,也有自己的isLive属性,判断存活时间,我们用Image来初始化三张图片,并路径赋值,在坦克被击中方法里,我们添加执行效果-> 坦克被击中消失后,我们开始执行爆炸类的“生命周期方法”,按条件执行图片放映顺序
新建Bomb类
package tankgame4; /** * Create By 刘鸿涛 * 2022/1/19 4:56 */ public class Bomb { int x, y; //炸弹的坐标 int life = 9; //炸弹的生命周期 boolean isLive = true; //是否还存活 public Bomb(int x, int y){ this.x = x; this.y = y; } //减少生命值 public void lifeDown(){ if(life > 0){ life--; }else { isLive = false; } } }
注意图片位置
当敌方坦克被击中后出现爆炸效果,我们新建一个爆炸效果类,这个类需要有x,y大小,需要一个生命周期的方法,来让爆炸效果动态化。当然了,我们的爆炸效果也在一个集合中,也有自己的isLive属性,判断存活时间,我们用Image来初始化三张图片,并路径赋值,在坦克被击中方法里,我们添加执行效果-> 坦克被击中消失后,我们开始执行爆炸类的“生命周期方法”,按条件执行图片放映顺序
4.实现敌人坦克自由移动
- 因为要求敌人的坦克,可以自由移动,因此需要将敌人坦克当做线程使用
- 因此,我们需要EnemyTank implements Runnable
- 在run方法写上我们相应的业务代码
- 在创建敌人坦克对象时,启动线程
为了使敌方坦克自由活动,我们需要为敌方每个坦克做成一个线程,因此,我们的敌人坦克类要实现Runnable接口,我们的run实现逻辑,通过setDirect封装方法,我们用switch循环加上Math.Random随机生成数,随机生成坦克方向,并按for循环来进行移动,每次朝一个方向移动后休眠50毫秒,体现缓冲效果,当然了,如果此线程坦克被击中,那么我们让此线程while循环break,不再执行
5.实现坦克站规定范围内移动
为了能使敌方坦克在游戏范围内移动,我们只需要在敌方坦克随机循环移动时,加入一个if条件即可,当超过范围,则不执行此次循环
package tankgame4; import java.util.Vector; /** * Create By 刘鸿涛 * 2022/1/13 2:16 */ public class EnemyTank extends Tank implements Runnable { //在敌人坦克类,使用Vector 保存多个Shot Vector<Shot> shots = new Vector<>(); boolean isLive = true; public EnemyTank(int x, int y) { super(x, y); } @Override public void run() { //然后随机的改变坦克方向 while (true) { //根据坦克的方向来继续移动 switch (getDirect()) { case 0://向上 //让坦克保存一个方向,走30步 for (int i = 0; i < 30; i++) { if (getY() > 0) { moveUp(); //休眠50毫秒 try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } } break; case 1://右 for (int i = 0; i < 30; i++) { if (getX() < 902) { moveRight(); //休眠50毫秒 try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } } break; case 2://下 for (int i = 0; i < 30; i++) { if (getY() < 620) { moveDown(); //休眠50毫秒 try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } } break; case 3://左 for (int i = 0; i < 30; i++) { if (getX() > 0) { moveLeft(); //休眠50毫秒 try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } } break; } try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } //随机改变坦克方向0 - 3 setDirect((int) (Math.random() * 4)); //如果坦克被击中线程终止 if (!isLive) { break; } } } }
这篇关于Java基础 - 坦克大战(第五章,坦克移动、与被击中效果功能)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南