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;}@Overridepublic 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()方法
@Overridepublic 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);}//画出敌人的坦克,遍历Vectorfor (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 为 trueg.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 保存多个ShotVector<Shot> shots = new Vector<>();boolean isLive = true;public EnemyTank(int x, int y) {super(x, y);}@Overridepublic 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 - 3setDirect((int) (Math.random() * 4));//如果坦克被击中线程终止if (!isLive) {break;}}}
}
Java基础 - 坦克大战(第五章,坦克移动、与被击中效果功能)相关推荐
- Java基础教程【第五章:Java数组】
章节目录 1. 数组的创建和声明 1.1定义 1.2特征 1.3数组的声明 1.4创建数组空间 2. 数组的初始化和元素 2.1数组元素 2.2数组初始化 3. 一维数组 4. 二维数组 4.1静态初 ...
- 学习 Python 之 Pygame 开发坦克大战(五)
学习 Python 之 Pygame 开发坦克大战(五) 坦克大战完善地图 1. 创建砖墙 2. 给砖墙增加子弹击中的碰撞效果 3. 给砖墙添加坦克不能通过的碰撞效果 4. 添加石墙 5. 添加玩家基 ...
- 微信小游戏制作坦克大战(五)敌方坦克可以发射炮弹
微信小游戏制作坦克大战(五)敌方坦克可以发射炮弹 在资源管理器中复制炮弹,重命名为敌人坦克的炮弹. 修改敌方坦克的积木 给敌方坦克炮弹添加事件 现在,敌方坦克已经可以自动发射炮弹啦. 下一篇文章:微信 ...
- Java基础学习——第十四章 网络编程
Java基础学习--第十四章 网络编程 一.网络编程概述 计算机网络: 把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大.功能强的网络系统,从而使众多的计算机可以方便地互相传递信 ...
- android坦克大战源代码,android的坦克大战 - 源码下载|源代码 - 源码中国
压缩包 : TankWar坦克大战.rar 列表 TankWar坦克大战\TankWar\.classpath TankWar坦克大战\TankWar\.project TankWar坦克大战\Tan ...
- Java基础学习系列--(五)【迭代器,数据结构,List,Set ,TreeSet集合,Collections工具类】
第一章 Iterator迭代器 1.1 Iterator接口 在程序开发中,经常需要遍历集合中的所有元素.针对这种需求,JDK专门提供了一个接口java.util.Iterator. 想要遍历Coll ...
- Java基础学习——第十六章 Java8新特性
Java基础学习--第十六章 Java8 新特性 Java8(JDK8.0)较 JDK7.0 有很多变化或者说是优化,比如 interface 里可以有静态方法和默认方法,并且可以有方法体,这一点就颠 ...
- 【爆肝更新】Python基础教程:第五章_Python函数
原创:公众号 数据说话 [爆肝更新]Python基础教程:第五章_Python函数 函数介绍 学习目标: 快速体验一下函数的使用 了解函数的作用. 函数:是组织好的,可重复使用的,用来实现特定功能的代 ...
- 【Java】Java基础飞机大战小游戏完整代码
Java基础飞机大战小游戏完整代码 先来展示一下代码实现结果图 主函数ShootGame 初始化游戏原始背景图片,游戏人物图片,游戏开始结束图片:构建产生敌人算法:产生英雄机算法:发射子弹算法:判断是 ...
- photoshop第十五章:制作商业卡片场景效果
第十五章:制作商业卡片场景效果 1.制作证件寸照效果 素材: 效果: (1)Ctrl+N新建文件->名称:证件寸照->宽度:14厘米->高度:14厘米->分辨率:300像素/英 ...
最新文章
- Oracle发布多语种虚拟机平台GraalVM 1.0
- 【译】来看看WebWindow,一个跨平台的.NET Core webview 库
- 在微信小程序中引入 Iconfont 阿里巴巴图标库
- 接口不能被实例化的吗?接口引用是什么?
- git修改本地仓库和远程仓库名称
- 通过SQL语句删除重复记录
- 麻将游戏简介firefly游戏框架介绍
- java程序设计课后答案 刘慧宁_【单选题】建筑立面图中,室外地坪轮廓线应用( )。...
- linux中如何修改只读文件
- 结巴 python_结巴中文分词使用学习(python)
- urllib3爬取网页源代码(爬虫)
- AVPro批量制作视频缩略图
- 什么是Pythonic?
- ROS-talker,listener
- Linux上安装MySQl超详细教程(CentOS系统)
- python 下载pip命令
- Java项目:基于java的医院挂号预约系统(计算机毕业设计)
- 浅尝辄止MongoDB:基础
- 论文阅读笔记(五)CLIP4Clip: An Empirical Study of CLIP for End to End Video Clip Retrieval
- geoserver java_GeoServer 安装教程