java坦克大战1.0——敌人坦克发射子弹+敌人消失+爆炸

目录

1.敌人坦克发射子弹

1.功能分析

 2.代码:

1.EnemyTank类:

2.MyPanel类 

2.敌人消失

1.功能分析:

2.代码 

1.EnemyTank类:

2.MyPanel类

3.Shot类

3.爆炸效果

1.功能分析

2.代码

1.Bomb类

2.MyPanel类

最终代码:

1.MyPanel类

2.Bomb类

3.Shot类

4.EnemyTank类


1.敌人坦克发射子弹

1.功能分析

让敌人的坦克也能够发射多颗子弹

  1. 在敌人坦克类,使用Vector保存多个Shot
  2. 当每创建一个敌人坦克对象,给该敌人对象初始化一个Shot对象,同时启动Shot
  3. 在绘制敌人坦克时,需要变量敌人坦克对象Vertor,绘制所有的子弹,当子弹isLive==false时就从Vertor移除

 2.代码:

1.EnemyTank类:
public class EnemyTank extends Tank {Vector<Shot> shots=new Vector<>();boolean isLive=true;public EnemyTank(int x, int y) {super(x, y);}
}

我们在敌人tank类里面增加了一组Vector集合用于存shot类,以及设置一个标记为了识别子弹是否被销毁。

2.MyPanel类 
 for (int e = 0; e < enemyTankSize; e++) {EnemyTank enemyTank=new EnemyTank(100*(e+1),0);enemyTank.setDirect(3);Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());enemyTank.shots.add(shot);new Thread(shot).start();enemyTanks.add(enemyTank);}

我们在初始化敌人坦克的时候,我们加入一颗子弹。并开启子弹的线程。 

for (int i=0;i<enemyTanks.size();i++) {EnemyTank enemyTank = enemyTanks.get(i);draw_tank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);//画出子弹for (int j = 0; j < enemyTank.shots.size(); j++) {//取出子弹Shot shot = enemyTank.shots.get(j);//绘制if(shot.isLive()){g.fill3DRect(shot.getX(),shot.getY(),2,2,false);}else {enemyTank.shots.remove(shot);}}}}

我们在MyPanel类里面的 paint方法里面加了判断子弹,以及绘制子弹动画并移除的语句。

2.敌人消失

1.功能分析:

  1. 敌人消失,就是让子弹在遇到坦克的时候让enemytank和子弹的标记为false
  2. 然后在绘制坦克的时候判断标记。

2.代码 

1.EnemyTank类:
public class EnemyTank extends Tank {Vector<Shot> shots=new Vector<>();boolean isLive=true;public EnemyTank(int x, int y) {super(x, y);}
}

 在类里面加一行:

boolen isLive=true;

这里变量类型你可以自己设置,对于这种我们一般建议用default。

2.MyPanel类
public void hitTank(Shot s, EnemyTank enemyTank){switch (enemyTank.getDirect()){case 0:case 2:if(s.getX()>enemyTank.getX()&&s.getX()<enemyTank.getX()+40&&s.getY()>enemyTank.getY()&&s.getY()<enemyTank.getY()+60){s.setLive(false);enemyTank.isLive=false;enemyTanks.remove(enemyTank);}break;case 1:case 3:if (s.getX()>enemyTank.getX()&&s.getX()<enemyTank.getX()+60&&s.getY()>enemyTank.getY()&&s.getY()<enemyTank.getY()+40) {s.setLive(false);enemyTank.isLive=false;enemyTanks.remove(enemyTank);}break;}}

因为我们设置的坦克是矩形的也就说他是一个规则的形状,那么在判断子弹和坦克的接触时,我们可以判断坦克的方向获得坦克的坐标然后和子弹的坐标相匹配。从而得到子弹是否进入了我们坦克的区域然后标记我们的坦克和子弹,并将坦克移除集合。

for (int i=0;i<enemyTanks.size();i++) {EnemyTank enemyTank = enemyTanks.get(i);if(enemyTank.isLive){//确定坦克被击中draw_tank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);//画出子弹for (int j = 0; j < enemyTank.shots.size(); j++) {//取出子弹Shot shot = enemyTank.shots.get(j);//绘制if(shot.isLive()){g.fill3DRect(shot.getX(),shot.getY(),2,2,false);}else {enemyTank.shots.remove(shot);}}}}

 在绘制敌人的坦克的时候我我们加上一层if判断,判断是否还为true,不为true将子弹移除集合。这里我们为了不让子弹线程在移除后继续运行,我们对shot类run方法条件进行修改

3.Shot类
 if (!(x>=0&&x<=1000&&y>=0&&y<=750)&&isLive) {isLive=false;break;}

在判段条件里加了一个isLive,在确定子弹销毁的时候,就结束子弹线程。

3.爆炸效果

1.功能分析

  1. 实现爆炸的动态图,我们可以用一张,或多张图,去绘制同一个爆炸的生命周期。、
  2. 爆炸是紧跟在子弹之后的,所以我们去写hitTank方法。

2.代码

1.Bomb类
public class Bomb {int x,y;int life=16;//炸弹生命周期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;}}
}

我们在这里设置生命周期,以及坐标,和标准位

2.MyPanel类
Vector<Bomb> bombs=new Vector<>();Image image1=null;int enemyTankSize=3;public MyPanel(){hero=new Hero(100,100);hero.setSpeed(1);//初始化敌人的tankfor (int e = 0; e < enemyTankSize; e++) {EnemyTank enemyTank=new EnemyTank(100*(e+1),0);enemyTank.setDirect(3);Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());enemyTank.shots.add(shot);new Thread(shot).start();enemyTanks.add(enemyTank);}//初始化image1=Toolkit.getDefaultToolkit().getImage("./bomb1.gif");}

在初始化的时候,增加了一个bombs集合来存储爆炸的效果,以及设置一次爆炸所需要的gif图片,当然也可以是两个,三个去做这个爆炸效果。

 public void hitTank(Shot s, EnemyTank enemyTank){switch (enemyTank.getDirect()){case 0:case 2:if(s.getX()>enemyTank.getX()&&s.getX()<enemyTank.getX()+40&&s.getY()>enemyTank.getY()&&s.getY()<enemyTank.getY()+60){s.setLive(false);enemyTank.isLive=false;Bomb bomb=new Bomb(enemyTank.getX(), enemyTank.getY());bombs.add(bomb);enemyTanks.remove(enemyTank);}break;case 1:case 3:if (s.getX()>enemyTank.getX()&&s.getX()<enemyTank.getX()+60&&s.getY()>enemyTank.getY()&&s.getY()<enemyTank.getY()+40) {s.setLive(false);enemyTank.isLive=false;Bomb bomb=new Bomb(enemyTank.getX(), enemyTank.getY());bombs.add(bomb);enemyTanks.remove(enemyTank);}break;}}

在hitTank方法里面增加一次bomb效果

 for (int i = 0; i <bombs.size() ; i++) {Bomb bomb = bombs.get(i);//根据bomb对象的life值去画出炸弹if(bomb.life>0){g.drawImage(image1,bomb.x,bomb.y,60,60,this);}bomb.lifeDown();//life为0if(bomb.life==0){bombs.remove(bomb);}}

并在paint去绘制图像,完成一个生命周期的图画绘制。然后移除

最终代码:

1.MyPanel类

package game;import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;//绘图区
//为了监听键盘事件,实现接口KeyListener
//将子弹变成线程使用
public class MyPanel extends JPanel implements KeyListener,Runnable {//定义我的坦克Hero hero=null;//定义敌人的坦克,放入到vector里面Vector<EnemyTank> enemyTanks=new Vector<>();Vector<Bomb> bombs=new Vector<>();Image image1=null;int enemyTankSize=3;public MyPanel(){hero=new Hero(100,100);hero.setSpeed(1);//初始化敌人的tankfor (int e = 0; e < enemyTankSize; e++) {EnemyTank enemyTank=new EnemyTank(100*(e+1),0);enemyTank.setDirect(3);Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());enemyTank.shots.add(shot);new Thread(shot).start();enemyTanks.add(enemyTank);}//初始化image1=Toolkit.getDefaultToolkit().getImage("./bomb1.gif");}@Overridepublic void paint(Graphics g) {super.paint(g);g.fillRect(0,0,1000,750);////画出坦克-封装方法draw_tank(hero.getX(),hero.getY(),g,hero.getDirect(),0);//画出hero射击的子弹if(hero.shot!=null&&hero.shot.isLive()){g.fill3DRect(hero.shot.getX(),hero.shot.getY(),2,2,false);}//画炸弹for (int i = 0; i <bombs.size() ; i++) {Bomb bomb = bombs.get(i);//根据bomb对象的life值去画出炸弹if(bomb.life>0){g.drawImage(image1,bomb.x,bomb.y,60,60,this);}bomb.lifeDown();//life为0if(bomb.life==0){bombs.remove(bomb);}}//画出敌人的坦克for (int i=0;i<enemyTanks.size();i++) {EnemyTank enemyTank = enemyTanks.get(i);if(enemyTank.isLive){//确定坦克被击中draw_tank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 1);//画出子弹for (int j = 0; j < enemyTank.shots.size(); j++) {//取出子弹Shot shot = enemyTank.shots.get(j);//绘制if(shot.isLive()){g.fill3DRect(shot.getX(),shot.getY(),2,2,false);}else {enemyTank.shots.remove(shot);}}}}}//编写方法,画出坦克/**** @param x 坦克左上角x的坐标* @param y 坦克的左上角y的坐标* @param g 画笔* @param direct 坦克方向* @param type 坦克类型*/public void draw_tank(int x,int y,Graphics g,int direct,int type){switch (type){case 0:g.setColor(Color.CYAN);break;case 1:g.setColor(Color.orange);break;}//根据tank的方向绘制//根据坦克的方向绘制对应形象的坦克switch (direct){case 0://表示向上g.fill3DRect( x, y,10,60,false);g.fill3DRect( x+30, y,10,60,false);g.fill3DRect( x+10, y+10,20,40,false);g.fillOval(x+10,y+20,20,20);g.drawLine(x+20,y+30,x+20,y);break;case 1://表示向右g.fill3DRect( x, y,60,10,false);g.fill3DRect( x, y+30,60,10,false);g.fill3DRect( x+10, y+10,40,20,false);g.fillOval(x+20,y+10,20,20);g.drawLine(x+30,y+20,x+60,y+20);break;case 2://表示向左g.fill3DRect( x, y,60,10,false);g.fill3DRect( x, y+30,60,10,false);g.fill3DRect( x+10, y+10,40,20,false);g.fillOval(x+20,y+10,20,20);g.drawLine(x+30,y+20,x,y+20);break;case 3://表示向下g.fill3DRect( x, y,10,60,false);g.fill3DRect( x+30, y,10,60,false);g.fill3DRect( x+10, y+10,20,40,false);g.fillOval(x+10,y+20,20,20);g.drawLine(x+20,y+30,x+20,y+60);break;default:System.out.println("暂时没有处理");}}//编写方法,判断子弹是否击中public void hitTank(Shot s, EnemyTank enemyTank){switch (enemyTank.getDirect()){case 0:case 2:if(s.getX()>enemyTank.getX()&&s.getX()<enemyTank.getX()+40&&s.getY()>enemyTank.getY()&&s.getY()<enemyTank.getY()+60){s.setLive(false);enemyTank.isLive=false;Bomb bomb=new Bomb(enemyTank.getX(), enemyTank.getY());bombs.add(bomb);enemyTanks.remove(enemyTank);}break;case 1:case 3:if (s.getX()>enemyTank.getX()&&s.getX()<enemyTank.getX()+60&&s.getY()>enemyTank.getY()&&s.getY()<enemyTank.getY()+40) {s.setLive(false);enemyTank.isLive=false;Bomb bomb=new Bomb(enemyTank.getX(), enemyTank.getY());bombs.add(bomb);enemyTanks.remove(enemyTank);}break;}}@Overridepublic void keyTyped(KeyEvent e) {}//处理wsad按下的键@Overridepublic void keyPressed(KeyEvent e) {if(e.getKeyCode()==KeyEvent.VK_W){//改变坦克的方向hero.setDirect(0);hero.move_up();} else if (e.getKeyCode()==KeyEvent.VK_D) {hero.setDirect(1);hero.move_right();} else if (e.getKeyCode()==KeyEvent.VK_A) {hero.setDirect(2);hero.move_left();} else if (e.getKeyCode()==KeyEvent.VK_S) {hero.setDirect(3);hero.move_down();}if(e.getKeyCode()==KeyEvent.VK_J) {System.out.println("用户按下j");hero.shotEnemyTank();}this.repaint();}@Overridepublic void keyReleased(KeyEvent e) {}@Overridepublic void run() {while (true) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//判断是否击中敌人坦克if(hero.shot!=null&&hero.shot.isLive()){//遍历敌人所有的坦克for (int i = 0; i < enemyTanks.size(); i++) {EnemyTank enemyTank = enemyTanks.get(i);hitTank(hero.shot,enemyTank);}}this.repaint();}}
}

2.Bomb类

package game;public class Bomb {int x,y;int life=16;//炸弹生命周期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;}}
}

3.Shot类

package game;public class Shot implements Runnable{//子弹的坐标private int x;private int y;private int direct=0;public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public int getDirect() {return direct;}public void setDirect(int direct) {this.direct = direct;}public boolean isLive() {return isLive;}public void setLive(boolean live) {isLive = live;}public int getSpeed() {return speed;}public void setSpeed(int speed) {this.speed = speed;}private boolean isLive=true;public Shot(int x, int y, int direct) {this.x = x;this.y = y;this.direct = direct;}private int speed=2;@Overridepublic void run() {while (true){try {Thread.sleep(50);} catch (InterruptedException e) {throw new RuntimeException(e);}//根据方向改变switch (direct){case 0://上y-=speed;break;case 1://右x+=speed;break;case 2:x-=speed;break;case 3:y+=speed;break;}System.out.println("x="+x+"y="+y);//当子弹碰到敌人坦克时结束线程if (!(x>=0&&x<=1000&&y>=0&&y<=750)&&isLive) {isLive=false;break;}}}
}

4.EnemyTank类

package game;import java.util.Vector;public class EnemyTank extends Tank {Vector<Shot> shots=new Vector<>();boolean isLive=true;public EnemyTank(int x, int y) {super(x, y);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/5128.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【保姆级讲解如何安装与配置Xcode】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

在kuboard中添加k8s集群

1.登录kuboard后&#xff0c;点击添加集群面板 系统会跳转到k8s集群添加页面&#xff0c;按照页面提示输入自身的集群信息即可&#xff0c;此处没有什么难点。 添加成功后&#xff0c;点击集群面板&#xff0c;然后点击集群概要信息&#xff0c;就可以查看集群节点信息。 集群节…

【QEMU系统分析之启动篇(二十)】

系列文章目录 第二十章 QEMU系统仿真设置完成后开放轮询的分析 文章目录 系列文章目录第二十章 QEMU系统仿真设置完成后开放轮询的分析 前言一、QEMU是什么&#xff1f;二、QEMU系统仿真的启动分析1.系统仿真的初始化代码2.主循环数据初始化3. resume_mux_open()get_chardevs_…

ssm092基于Tomcat技术的车库智能管理平台+jsp

车库智能管理平台设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本车库智能管理平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短…

Android14音频进阶之车载音频系统AAOS:VehicleService服务学习<下篇>(六十九)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+AOSP…

Java字符缓冲区

字符缓冲区是在计算机编程中非常重要的一种数据结构&#xff0c;它主要用于存储和高效地操作字符序列。 在 Java 中&#xff0c;StringBuffer类就是典型的字符缓冲区实现。与String类不同&#xff0c;StringBuffer具有动态可变性&#xff0c;这意味着我们可以在原有的字符序列…

springboot集成-mybatis-puls

Spring Boot中集成MyBatis Plus是一个相对简单的过程&#xff0c;MyBatis Plus是一个MyBatis的增强工具&#xff0c;它简化了CRUD操作&#xff0c;并且提供了一些额外的功能&#xff0c;比如性能优化、自动填充等。以下是集成MyBatis Plus的基本步骤&#xff1a; 1.添加依赖&am…

firefox 浏览器常见问题(技巧)总结

目录 问题火狐浏览器firefox 如何取消更新提醒? 待续、更新中 问题 火狐浏览器firefox 如何取消更新提醒? 1、用户在电脑桌面上找到火狐浏览器&#xff0c;接着用鼠标右键点击&#xff0c;在弹出来的右键菜单中&#xff0c;用户选择其中的打开文件所在的位置选项火狐浏览器怎…

Hive数据库base64 加解密字段或字符串

加码&#xff1a; select BASE64([{"name":"晁盖","mid":"002J81Pr09ytag","id":12384782}]) 解码&#xff1a; SELECT string(unbase64(W3sibmFtZSI6IuS4geeoimRqyIsIm1pZCI6IjAwMko4MVByMDl5amFnIiwiaWQiOjE0NTE2OTl9XQ)…

共享模型之不可变——不可变设计、享元模式

文章目录 不可变设计final 的使用保护性拷贝 享元模式简介体现包装类String 串池BigDecimal BigInteger DIY 不可变设计 另一个大家更为熟悉的 String 类也是不可变的&#xff0c;以它为例&#xff0c;说明一下不可变设计的要素 public final class Stringimplements java.io…

设计不外流,保护创意的同时锁住图纸安全!

在设计行业中&#xff0c;图纸和创意文稿的安全至关重要&#xff0c;因为它们体现了企业的创新能力和核心竞争力。华企盾DSC数据防泄密系统提供了一系列功能&#xff0c;可以有效地保护这些珍贵的设计和文档不被外泄。以下是如何利用华企盾DSC系统保障设计图纸安全的关键措施&a…

stable-diffusion教程

下载代码 https://gitee.com/stable_diffusion/stable-diffusion-webui.git 然后执行自动安装环境命令 ./webui.sh

MySQL怎么看死锁记录

这个结果分成三部分&#xff1a; (1) TRANSACTION&#xff0c;是第一个事务的信息&#xff1b; (2) TRANSACTION&#xff0c;是第二个事务的信息&#xff1b; (3)WE ROLL BACK TRANSACTION (1)&#xff0c;是最终的处理结果&#xff0c;表示回滚了第一个事务。 第一个事务的信…

基于飞腾D2000全国产化高速公路一体化收费站解决方案:站数据服务器、站AI服务器、收费系统、监控系统

高速公路一体化收费站解决方案 行业 交通工程及沿路设施作为公路的一个重要组成部分&#xff0c;对城市互联和城市发展具有重要意义&#xff0c;因此围绕高速公路的专用收费 站设计和建设&#xff0c;将有效促进枢纽集散系统与高速公路连通&#xff0c;显著提升城市高速集散能…

ansible-playbook离线升级centos内核

目录 概述实践ansible目录结构关键代码执行效果 结束 概述 内核离线包官网下载地址如下&#xff1a; 地址 实践 ansible目录结构 如对 ansible 不熟悉&#xff0c;离线包下载有问题&#xff0c;请至此地址下载&#xff0c;按本文操作可直接使用。 相关文章链接如下 文章地…

通过共享网络使树莓派4联网

一、问题 尝试配置/boot/dhcpcd.conf文件无效&#xff0c;wifi依然无法联网&#xff0c;且通过桌面选择wifi输入密码后同样无法联网&#xff1b; 二、环境 1、可以通过网线连接电脑&#xff0c;并且可以连接串口&#xff1b; 2、可以通过静态地址通过网线访问树莓派ssh端口&…

交叉调制少样本图像生成用于结直肠组织分类

文章目录 Cross-Modulated Few-Shot Image Generation for Colorectal Tissue Classification摘要方法实验结果 Cross-Modulated Few-Shot Image Generation for Colorectal Tissue Classification 摘要 提出问题&#xff1a; 针对罕见癌症组织的组织病理训练数据稀缺问题&…

【ARMv9 DSU-120 系列 9 -- DSU-120 Debug block】

请阅读【Arm DynamIQ™ Shared Unit-120 专栏 】 请阅读【ARM Coresight SoC-400/SoC-600 专栏导读】 文章目录 ARM DSU-120 Debug BlockCluster debug componentsCache DebugDSU-120 Cache Debug 特性应用场景Terminology处理元素(PE)

maven-idea新建和导入项目

全局配置 新建项目 需要新建的文件夹 src/testsrc/test/javasrc/main/java 注&#xff1a;1、新建Java-class&#xff0c;输入.com.hello.hellomaven 2、快捷键psvm显示 public static void main(String[] args) {.... } package com.hello;public class hellomaven {publ…

K8S Service 常见问题

Service 问题排查 为了演示需要部署以下服务。 apiVersion: apps/v1 kind: Deployment metadata:name: busyboxnamespace: appslabels:app: busybox spec:replicas: 1selector:matchLabels:app: busyboxtemplate:metadata:labels:app: busyboxspec:containers:- name: busybo…