IO流 - 应用到坦克大战
一、坦克大战6.0版
1、防止坦克重叠运动
当前坦克向上
时:当左上角
和右上角
进入敌方坦克区域,则视为重叠
当前坦克向左
时:当左上角
和左下角
进入敌方坦克区域,则视为重叠
当前坦克向下
时:当左下角
和右下角
进入敌方坦克区域,则视为重叠
当前坦克向右
时:当右上角
和右下角
进入敌方坦克区域,则视为重叠
变化:
EnemyTank:
- 增加成员Vector enemys ,用于接收myPanel的Vector
- 编写方法isTouchEnemyTank,判断当前这个敌人的坦克,是否和 anemyTanks 中的其他坦克发生重叠或者碰撞
- 修改run中敌人移动的代码,在移动前判断是否重叠。重叠则不移动
MyPanel:
- 每创建一个enemy,就将enemyTanks对象传入EnemyTank类中(由于MyPanel是一个线程,run中有循环,所以会不断调用构造器)
EnemyTank类
public class EnemyTank extends Tank implements Runnable{
//1. 增加成员,EnemyTank 可以得到敌人坦克的Vector
private Vector<EnemyTank> enemyTanks = new Vector<>();
//2. 编写方法,判断当前这个敌人的坦克,是否和 anemyTanks 中的其他坦克发生重叠或者碰撞
public boolean isTouchEnemyTank(){
//判断当前敌人坦克的方向(this)方向
switch (this.getDirect()){
case 0://上
//让当前坦克和所有的敌人坦克比较
for (int i = 0; i < enemyTanks.size(); i++) {
//从vector取出一个坦克来
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比较
if (enemyTank != this){
//如果敌人坦克是上下
//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
// y:[anemyTank.getY(), nemyTank.getY() + 60]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
//敌人坦克左上坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 40
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 60) {
return true;
}
//敌人坦克右下的坐标
if (this.getX() + 40 >= enemyTank.getX()
&& this.getX() + 40 <= enemyTank.getX() + 40
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 60) {
return true;
}
}
//如果敌人的坦克是左右
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
//敌人坦克左上坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 60
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 40) {
return true;
}
//敌人坦克左下的坐标
if (this.getX() + 40 >= enemyTank.getX()
&& this.getX() + 40 <= enemyTank.getX() + 60
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 40) {
return true;
}
}
}
}
case 1: //右
//让当前坦克和所有的敌人坦克比较
for (int i = 0; i < enemyTanks.size(); i++) {
//从vector取出一个坦克来
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比较
if (enemyTank != this){
//如果敌人坦克是上下
//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
// y:[anemyTank.getY(), nemyTank.getY() + 60]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
//敌人坦克右上坐标
if (this.getX() + 60 >= enemyTank.getX()
&& this.getX() + 60 <= enemyTank.getX() + 40
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 60) {
return true;
}
//敌人坦克右下的坐标
if (this.getX() + 60 >= enemyTank.getX()
&& this.getX() + 60 <= enemyTank.getX() + 40
&& this.getY() + 40 >= enemyTank.getY()
&& this.getY() + 40 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敌人的坦克是左右
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
//敌人坦克右上边坐标
if (this.getX() + 60 >= enemyTank.getX()
&& this.getX() +60 <= enemyTank.getX() + 60
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 40) {
return true;
}
//敌人坦克右下的坐标
if (this.getX() + 60 >= enemyTank.getX()
&& this.getX() + 60 <= enemyTank.getX() + 60
&& this.getY() + 40 >= enemyTank.getY()
&& this.getY() + 40 <= enemyTank.getY() + 40) {
return true;
}
}
}
}
case 2: //下
//让当前坦克和所有的敌人坦克比较
for (int i = 0; i < enemyTanks.size(); i++) {
//从vector取出一个坦克来
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比较
if (enemyTank != this){
//如果敌人坦克是上下
//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
// y:[anemyTank.getY(), nemyTank.getY() + 60]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
//敌人坦克左下坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 40
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() + 60 <= enemyTank.getY() + 60) {
return true;
}
//敌人坦克右下的坐标
if (this.getX() + 40 >= enemyTank.getX()
&& this.getX() + 40 <= enemyTank.getX() + 40
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() + 60 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敌人的坦克是左右
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
//敌人坦克左边坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 60
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() + 60 <= enemyTank.getY() + 40) {
return true;
}
//敌人坦克右边的坐标
if (this.getX() + 40 >= enemyTank.getX()
&& this.getX() + 40 <= enemyTank.getX() + 60
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() + 60 <= enemyTank.getY() + 40) {
return true;
}
}
}
}
case 3: //左
//让当前坦克和所有的敌人坦克比较
for (int i = 0; i < enemyTanks.size(); i++) {
//从vector取出一个坦克来
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比较
if (enemyTank != this){
//如果敌人坦克是上下
//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
// y:[anemyTank.getY(), nemyTank.getY() + 60]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
//敌人坦克左上坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 40
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 60) {
return true;
}
//敌人坦克左下的坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 40
&& this.getY() + 40 >= enemyTank.getY()
&& this.getY() + 40 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敌人的坦克是左右
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
//敌人坦克左上坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 60
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 40) {
return true;
}
//敌人坦克左下的坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 60
&& this.getY() + 40 >= enemyTank.getY()
&& this.getY() + 40 <= enemyTank.getY() + 40) {
return true;
}
}
}
}
}
return false;
}
//在移动时调用isTouchEnemyTank(),判断是否重叠
@Override
public void run() {
while(true) {
//...
switch (getDirect()) {
case 0: //向上
for (int i = 0; i < 30; i++) { //移动30步再变化方向
//4. 移动前判断是否重叠
if((getY() > 0) && !isTouchEnemyTank()){ //在画布范围内移动
moveUp();
}
//休眠...
}
break;
case 1: //向左
for (int i = 0; i < 30; i++) { //移动30步再变化方向
if((getX() > 0) && !isTouchEnemyTank()) {
moveLeft();
}
//休眠...
}
break;
case 2: //向下
for (int i = 0; i < 30; i++) { //移动30步再变化方向
if ((getY() + 60 < 750) && !isTouchEnemyTank()) {
moveDown();
}
//休眠...
}
break;
case 3: //向右
for (int i = 0; i < 30; i++) { //移动30步再变化方向
if((getX() + 60 < 1000) && !isTouchEnemyTank()) {
moveRight();
}
//休眠...
}
break;
}
//...
}
}
}
MyPanel类
public MyPanel(){
//...
//初始化敌人坦克
for (int i = 0; i < 5; i++) {
//创建一个敌人坦克
EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);
//把敌方坦克集合传给Enemy类
enemyTank.setEnemyTanks(enemyTanks);
//...
}
//...
}
2、记录上局游戏信息,存盘退出【IO流】
创建一个Recorder类,记录相关信息,用于和文件交互
Recorder类
- 定义IO、文件路径
- 实现保存信息方法(keepRecord)
MyPanel类
- 给Recorder传入enemyTanks集合
TankGame类
- 在关闭窗口时调用Recorder的KeepRecord方法保存信息
Recorder类
/**
* 该类记录文件信息和文件交互
*/
public class Recorder {
//定义变量记录我方击毁敌人坦克数
private static int hitTankNums = 0;
//定义IO对象
private static BufferedWriter bw = null;
private static BufferedReader br = null;
private static String recordFile = "d:\\myRecord.txt";
private static Vector<EnemyTank> enemyTanks = null;
//添加一个方法,当游戏退出时,将hitTankNums 保存到 recordFile;
public static void keepRecord(){
try {
bw = new BufferedWriter(new FileWriter(recordFile));
//记录每个存活的敌方坦克
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (enemyTank.isLive()){
bw.write(enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirect() + "\r\n");
}
}
bw.write(hitTankNums + "\r\n");
} catch (IOException e) {
e.printStackTrace();
}finally {
if (bw != null){
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static int getHitTankNums() {
return hitTankNums;
}
public static Vector<EnemyTank> getAnemyTanks() {
return enemyTanks;
}
public static void setAnemyTanks(Vector<EnemyTank> enemyTanks) {
Recorder.enemyTanks = enemyTanks;
}
public static void setHitTankNums(int hitTankNums) {
Recorder.hitTankNums = hitTankNums;
}
public static void addHitTankNums(){
Recorder.hitTankNums++;
}
}
MyPanel类
public MyPanel(){
//1. 传入 anemyTanks 并记录
Recorder.setAnemyTanks(enemyTanks);
//...
}
TankGame类
public class TankGame extends JFrame {
//...
public TankGame(){
mp = new MyPanel();
//...
//1. 在JFrame 中增加相应关闭窗口的处理
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
Recorder.keepRecord();
System.exit(0);
}
});
}
}
3、玩游戏时,可以选择是开新游戏还是继续上局游戏
Recorder类
- 定义一个node 的Vector,用于恢复信息
- 实现读取信息方法:getNodesAndEnemyNums
MyPanel类
- 定义nodes,接收从Recorder读取到的上局敌人信息
- 重新定义构造器,接收参数key,判断是重新开始还是继续上局游戏
- (1)重新开始:用enemyTanks,重新遍历创建敌人
- (2)继续上局:用nodes,获取敌人信息并调用EnemyTank构造器创建敌人
TankGame类
- 给MyPanel传入参数key
Recorder类
//1.定义一个node 的Vector,用于恢复信息
private static Vector<Node> nodes = new Vector<>();
//2. 添加一个方法,用于读取recordFile,恢复相关的信息
public static Vector<Node> getNodesAndEnemyNums(){
try {
br = new BufferedReader(new FileReader(recordFile));
//循环读取文件,生成 nodes 集合
String line = "";//255 40 0
while ((line = br.readLine()) != null){
String[] s = line.split(" ");
if (s.length == 3){
Node node = new Node(Integer.parseInt(s[0]), Integer.parseInt(s[1]), Integer.parseInt(s[2]));
nodes.add(node);
}else if (s.length == 1){
line = s[0];
int hitTankNums = Integer.parseInt(line);
setHitTankNums(hitTankNums);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return nodes;
}
MyPanel类
//1. 定义一个存放 Node对象的 Vector,用来存放继续游戏时的坦克
Vector<Node> nodes = null;
//2. 接收一个key,用于判断是重新开始,还是继续游戏
public MyPanel(String key){
//判断是重新开始,还是继续游戏
switch (key){
case "1": //重新开始,重置击毁敌人数,使用enemyTanks集合创建敌人坦克
//重置击毁敌人数
Recorder.setHitTankNums(0);
//初始化敌人坦克
for (int i = 0; i < 5; i++) {
//创建一个敌人坦克
EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);
//把敌方坦克集合传给Enemy类
enemyTank.setEnemyTanks(enemyTanks);
//设置方向
enemyTank.setDirect(2);
//启动敌方坦克
Thread thread = new Thread(enemyTank);
thread.start();
//给anemyTank加入一个子弹
Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
//加入enemyTank的Vector成员
enemyTank.getShots().add(shot);
//启动shot对象
new Thread(shot).start();
enemyTanks.add(enemyTank);
}
break;
case "2": //继续游戏,使用nodes集合创建敌人坦克
nodes = Recorder.getNodesAndEnemyNums();
for (int i = 0; i < nodes.size(); i++) {
Node node = nodes.get(i);
//创建一个敌人坦克
EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY());
//将 anemyTanks设置个AnemyTank
enemyTank.setEnemyTanks(enemyTanks);
//设置方向
enemyTank.setDirect(node.getDirect());
//启动敌方坦克
Thread thread = new Thread(enemyTank);
thread.start();
//给anemyTank加入一个子弹
Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
//加入enemyTank的Vector成员
enemyTank.getShots().add(shot);
//启动shot对象
new Thread(shot).start();
enemyTanks.add(enemyTank);
}
break;
default:
System.out.println("你输入的有误:");
}
}
TankGame类
public class TankGame extends JFrame {
//...
static Scanner scanner = new Scanner(System.in);
//...
public TankGame(){
System.out.println("请输入选择: 1.新游戏 2.继续上局");
String key = scanner.next();
mp = new MyPanel(key);
//...
}
}
4、游戏开始时,播放经典的坦克大战音乐
创建工具类AePlayWave,导入音频文件(注意必须是wav格式,而且不能直接通过改后缀改变音频格式)—》 用格式工厂
AePlayWave类
/**
* 播放音乐
*/
public class AePlayWave extends Thread {
private String filename;
public AePlayWave(String wavfile) { //构造器 , 指定文件
filename = wavfile;
}
public void run() {
File soundFile = new File(filename);
AudioInputStream audioInputStream = null;
try {
audioInputStream = AudioSystem.getAudioInputStream(soundFile);
} catch (Exception e1) {
e1.printStackTrace();
return;
}
AudioFormat format = audioInputStream.getFormat();
SourceDataLine auline = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
try {
auline = (SourceDataLine) AudioSystem.getLine(info);
auline.open(format);
} catch (Exception e) {
e.printStackTrace();
return;
}
auline.start();
int nBytesRead = 0;
//这是缓冲
byte[] abData = new byte[512];
try {
while (nBytesRead != -1) {
nBytesRead = audioInputStream.read(abData, 0, abData.length);
if (nBytesRead >= 0)
auline.write(abData, 0, nBytesRead);
}
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
auline.drain();
auline.close();
}
}
}
MyPanel类
public MyPanel(String key){
//...
// 播放音乐,调用start方法
new AePlayWave("src\\start.wav").start();
}
5、修正下文文件存储的位置
将存盘数据保存到项目中(src下)
-
新建一个myRecord.txt,因为第一次开始游戏的时候,会读取这个文件,如果没有会报错
-
修改Recorder类
public class Recorder {
private static String recordFile = "src\\myRecord.txt";
}
6、处理文件相关异常
假如没有记录文件,就直接开启上局游戏,会因为读取不到而报错
那么在判断是开启上局还是开启新游戏之前,就应该先判断文件是否存在
Recorder类
//新增方法
public static String getRecordFile() {
return recordFile;
}
MyPanel类
public MyPanel(String key){
//判断文件是否存在
if(new File(Recorder.getRecordFile()).exists()) {
//读文件
nodes = Recorder.getNodesAndEnemyNums();
} else {
System.out.println("文件不存在,只能开启新游戏");
key = "1";
}
//...
switch(key) {
case "1":
//...
case "2":
//这里不用再Recorder.getNodesAndEnemyNums();
//...
}
//...
}
7、完整版
1)Tank类
package com.rxli.game;
/**
* 坦克类
*/
public class Tank {
private int x;//坦克的横坐标
private int y;//坦克的纵坐标
private int direct;//坦克的方向
private boolean life = true;//坦克是否存活
public Tank(int x, int y) {
this.x = x;
this.y = y;
}
public boolean isLife() {
return life;
}
public void setLife(boolean life) {
this.life = life;
}
//坦克移动
//上移
public void moveUp(){
if (getY() > 0){
y-=3;
}
}
//下移
public void moveDown(){
if (getY() + 60 < 700) {
y+=3;
}
}
//左移
public void moveLeft(){
if (getX() > 0) {
x-=3;
}
}
//右移
public void moveRight(){
if (getX() + 60 < 800){
x+=3;
}
}
public int getDirect() {
return direct;
}
public void setDirect(int direct) {
this.direct = direct;
}
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;
}
}
2)Hero类
package com.rxli.game;
import java.util.Vector;
/**
* 这个是我们的坦克
*/
public class Hero extends Tank {
//定义一个Shot对象,表示一个射击行为(线程)
private Shot shot = null;
//可以发射多颗子弹
private Vector<Shot> shots = new Vector<>();
private boolean life = true;
public boolean isLife() {
return life;
}
public void setLife(boolean life) {
this.life = life;
}
public Hero(int x, int y) {
super(x, y);
}
public Shot getShot() {
return shot;
}
public void setShot(Shot shot) {
this.shot = shot;
}
public Vector<Shot> getShots() {
return shots;
}
public void setShots(Vector<Shot> shots) {
this.shots = shots;
}
public void shotEnemyTank(){
//只能存储五颗子弹,如果子弹数目大于5就不再存贮
if (getShots().size() == 5){
return;
}
//创建Shot对象,根据当前Hero对象的位置和方向来创建shot
//只有当当前子弹消亡才能再次发射子弹
switch (getDirect()){
case 0://向上
shot = new Shot(getX() + 18, getY(), 0);
break;
case 1://向右
shot = new Shot(getX() + 60, getY() + 18, 1);
break;
case 2://向下
shot = new Shot(getX() + 18,getY() + 60, 2);
break;
case 3://向左
shot = new Shot(getX(), getY() + 18, 3);
break;
}
//把新建的shot放入到集合中
shots.add(shot);
//启动我们的shot线程
new Thread(shot).start();
}
}
3)EnemyTank类
package com.rxli.game;
import java.util.Vector;
public class EnemyTank extends Tank implements Runnable{
private boolean isLive = true;
//炮弹
private Vector<Shot> shots = new Vector<>();
//获取所有的敌人的坦克
private Vector<EnemyTank> enemyTanks = new Vector<>();
public EnemyTank(int x, int y) {
super(x, y);
}
public Vector<Shot> getShots() {
return shots;
}
public boolean isLive() {
return isLive;
}
public void setLive(boolean live) {
isLive = live;
}
public void setShots(Vector<Shot> shots) {
this.shots = shots;
}
public Vector<EnemyTank> getAnemyTanks() {
return enemyTanks;
}
//这里提供一个方法,可以将 Mypanel 的成员 anemyTanks 成员变量设置到本类
public void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
this.enemyTanks = enemyTanks;
}
//编写方法,判断当前这个敌人的坦克,是否和 anemyTanks 中的其他坦克发生重叠或者碰撞
public boolean isTouchEnemyTank(){
//判断当前敌人坦克的方向(this)方向
switch (this.getDirect()){
case 0://上
//让当前坦克和所有的敌人坦克比较
for (int i = 0; i < enemyTanks.size(); i++) {
//从vector取出一个坦克来
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比较
if (enemyTank != this){
//如果敌人坦克是上下
//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
// y:[anemyTank.getY(), nemyTank.getY() + 60]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
//敌人坦克左上坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 40
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 60) {
return true;
}
//敌人坦克右下的坐标
if (this.getX() + 40 >= enemyTank.getX()
&& this.getX() + 40 <= enemyTank.getX() + 40
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 60) {
return true;
}
}
//如果敌人的坦克是左右
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
//敌人坦克左上坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 60
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 40) {
return true;
}
//敌人坦克左下的坐标
if (this.getX() + 40 >= enemyTank.getX()
&& this.getX() + 40 <= enemyTank.getX() + 60
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 40) {
return true;
}
}
}
}
case 1:
//让当前坦克和所有的敌人坦克比较
for (int i = 0; i < enemyTanks.size(); i++) {
//从vector取出一个坦克来
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比较
if (enemyTank != this){
//如果敌人坦克是上下
//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
// y:[anemyTank.getY(), nemyTank.getY() + 60]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
//敌人坦克右上坐标
if (this.getX() + 60 >= enemyTank.getX()
&& this.getX() + 60 <= enemyTank.getX() + 40
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 60) {
return true;
}
//敌人坦克右下的坐标
if (this.getX() + 60 >= enemyTank.getX()
&& this.getX() + 60 <= enemyTank.getX() + 40
&& this.getY() + 40 >= enemyTank.getY()
&& this.getY() + 40 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敌人的坦克是左右
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
//敌人坦克右上边坐标
if (this.getX() + 60 >= enemyTank.getX()
&& this.getX() +60 <= enemyTank.getX() + 60
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 40) {
return true;
}
//敌人坦克右下的坐标
if (this.getX() + 60 >= enemyTank.getX()
&& this.getX() + 60 <= enemyTank.getX() + 60
&& this.getY() + 40 >= enemyTank.getY()
&& this.getY() + 40 <= enemyTank.getY() + 40) {
return true;
}
}
}
}
case 2:
//让当前坦克和所有的敌人坦克比较
for (int i = 0; i < enemyTanks.size(); i++) {
//从vector取出一个坦克来
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比较
if (enemyTank != this){
//如果敌人坦克是上下
//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
// y:[anemyTank.getY(), nemyTank.getY() + 60]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
//敌人坦克左下坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 40
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() + 60 <= enemyTank.getY() + 60) {
return true;
}
//敌人坦克右下的坐标
if (this.getX() + 40 >= enemyTank.getX()
&& this.getX() + 40 <= enemyTank.getX() + 40
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() + 60 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敌人的坦克是左右
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
//敌人坦克左边坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 60
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() + 60 <= enemyTank.getY() + 40) {
return true;
}
//敌人坦克右边的坐标
if (this.getX() + 40 >= enemyTank.getX()
&& this.getX() + 40 <= enemyTank.getX() + 60
&& this.getY() + 60 >= enemyTank.getY()
&& this.getY() + 60 <= enemyTank.getY() + 40) {
return true;
}
}
}
}
case 3:
//让当前坦克和所有的敌人坦克比较
for (int i = 0; i < enemyTanks.size(); i++) {
//从vector取出一个坦克来
EnemyTank enemyTank = enemyTanks.get(i);
//不和自己比较
if (enemyTank != this){
//如果敌人坦克是上下
//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]
// y:[anemyTank.getY(), nemyTank.getY() + 60]
if (enemyTank.getDirect() == 0 || enemyTank.getDirect() == 2){
//敌人坦克左上坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 40
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 60) {
return true;
}
//敌人坦克左下的坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 40
&& this.getY() + 40 >= enemyTank.getY()
&& this.getY() + 40 <= enemyTank.getY() + 60) {
return true;
}
}
//如果敌人的坦克是左右
if (enemyTank.getDirect() == 1 || enemyTank.getDirect() == 3){
//敌人坦克左上坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 60
&& this.getY() >= enemyTank.getY()
&& this.getY() <= enemyTank.getY() + 40) {
return true;
}
//敌人坦克左下的坐标
if (this.getX() >= enemyTank.getX()
&& this.getX() <= enemyTank.getX() + 60
&& this.getY() + 40 >= enemyTank.getY()
&& this.getY() + 40 <= enemyTank.getY() + 40) {
return true;
}
}
}
}
}
return false;
}
@Override
public void run() {
while(true){
//如果一个子弹都没有就new一个
//并启动
if (isLive && getShots().size() < 2){
Shot s = null;
switch (getDirect()){
case 0:
s = new Shot(getX() + 20, getY(), 0);
break;
case 1:
s = new Shot(getX() + 60, getY() + 20, 1);
break;
case 2:
s = new Shot(getX() + 20, getY() + 60, 2);
break;
case 3:
s = new Shot(getX() - 60, getY() + 20, 3);
break;
}
getShots().add(s);
new Thread(s).start();
}
//根据坦克的方向继续移动
switch (getDirect()){
case 0://向上
for (int i = 0; i < 30; i++) {
if (getY() > 0 && !isTouchEnemyTank() ) {
moveUp();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 1://向右
for (int i = 0; i < 30; i++) {
if (getX() + 60 < 800 && !isTouchEnemyTank()){
moveRight();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 2://向下
for (int i = 0; i < 30; i++) {
if (getY() + 60 < 700 && !isTouchEnemyTank()) {
moveDown();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 3://向左
for (int i = 0; i < 30; i++) {
if (getX() > 0 && !isTouchEnemyTank()){
moveLeft();
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
}
//休眠50毫秒
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//然后随机的改变
setDirect((int)(Math.random() * 4));
//写多线程时,一定要考虑到线程什么时候结束
if (!isLive){
break;
}
}
}
}
4)Shot类
package com.rxli.game;
/**
* 子弹类
*/
public class Shot implements Runnable{
private int x;//子弹的横坐标
private int y;//子弹的纵坐标
private int direct;//子弹的方向
private int speed = 5;//子弹的速度
private boolean isLive = true;//子弹是否成活
public Shot(int x, int y, int direct) {
this.x = x;
this.y = y;
this.direct = direct;
}
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 int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public boolean isLive() {
return isLive;
}
public void setLive(boolean live) {
isLive = live;
}
@Override
public void run() {
while(true){
//休眠100毫秒
try {
Thread.sleep(100);
} 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;
}
//System.out.println("子弹的x=" + x + "y=" + y);
//当子弹移动到边界的时候我们就应该销毁
//当子弹碰到敌人的坦克时,线程也应该退出
if (!(x >= 0 && x <= 800 && y >= 0 && y <= 750 && isLive)){
isLive = false;
//System.out.println("子弹的线程退出");
break;
}
}
}
}
5)Bomb类
package com.rxli.game;
public class Bomb {
private int x, y;//炸弹的坐标
private int life = 9;//炸弹的生命周期
private boolean isLife = true;
public Bomb(int x, int y) {
this.x = x;
this.y = y;
}
//减少生命值
public void lifeDown(){
if(life > 0){
life--;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
isLife = false;
}
}
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 getLife() {
return life;
}
public void setLife(int life) {
this.life = life;
}
public boolean isLife() {
return isLife;
}
public void setLife(boolean life) {
isLife = life;
}
}
6)Recorder类
package com.rxli.game;
import java.io.*;
import java.util.Vector;
/**
* 该类记录文件信息和文件交互
*/
public class Recorder {
//定义变量记录我方击毁敌人坦克数
private static int hitTankNums = 0;
//定义IO对象
private static BufferedWriter bw = null;
private static BufferedReader br = null;
private static String recordFile = "src\\myRecord.txt";
private static Vector<EnemyTank> enemyTanks = null;
//定义一个node 的Vector,用于恢复信息
private static Vector<Node> nodes = new Vector<>();
//添加一个方法,用于读取recordFile,恢复相关的信息
public static Vector<Node> getNodesAndEnemyNums() {
try {
br = new BufferedReader(new FileReader(recordFile));
//循环读取文件,生成 nodes 集合
String line = "";//255 40 0
while ((line = br.readLine()) != null) {
String[] s = line.split(" ");
if (s.length == 3) {
Node node = new Node(Integer.parseInt(s[0]), Integer.parseInt(s[1]), Integer.parseInt(s[2]));
nodes.add(node);
} else if (s.length == 1) {
line = s[0];
int hitTankNums = Integer.parseInt(line);
setHitTankNums(hitTankNums);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return nodes;
}
//添加一个方法,当游戏退出时,将hitTankNums 保存到 recordFile;
public static void keepRecord() {
try {
bw = new BufferedWriter(new FileWriter(recordFile));
//记录每个存活的敌方坦克
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (enemyTank.isLive()) {
bw.write(enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirect() + "\r\n");
}
}
bw.write(hitTankNums + "\r\n");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static String getRecordFile() {
return recordFile;
}
public static int getHitTankNums() {
return hitTankNums;
}
public static Vector<EnemyTank> getAnemyTanks() {
return enemyTanks;
}
public static void setAnemyTanks(Vector<EnemyTank> enemyTanks) {
Recorder.enemyTanks = enemyTanks;
}
public static void setHitTankNums(int hitTankNums) {
Recorder.hitTankNums = hitTankNums;
}
public static void addHitTankNums() {
Recorder.hitTankNums++;
}
}
7)Node类
package com.rxli.game;
public class Node {
private int x;
private int y;
private int direct;
public Node(int x, int y, int direct) {
this.x = x;
this.y = y;
this.direct = direct;
}
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;
}
}
8)AePlayerWave类
package com.rxli.game;
import javax.sound.sampled.*;
import java.io.File;
import java.io.IOException;
/**
* 播放音乐
*/
public class AePlayWave extends Thread {
private String filename;
public AePlayWave(String wavfile) { //构造器 , 指定文件
filename = wavfile;
}
public void run() {
File soundFile = new File(filename);
AudioInputStream audioInputStream = null;
try {
audioInputStream = AudioSystem.getAudioInputStream(soundFile);
} catch (Exception e1) {
e1.printStackTrace();
return;
}
AudioFormat format = audioInputStream.getFormat();
SourceDataLine auline = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
try {
auline = (SourceDataLine) AudioSystem.getLine(info);
auline.open(format);
} catch (Exception e) {
e.printStackTrace();
return;
}
auline.start();
int nBytesRead = 0;
//这是缓冲
byte[] abData = new byte[512];
try {
while (nBytesRead != -1) {
nBytesRead = audioInputStream.read(abData, 0, abData.length);
if (nBytesRead >= 0)
auline.write(abData, 0, nBytesRead);
}
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
auline.drain();
auline.close();
}
}
}
9)MyPanel类
package com.rxli.game;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.Vector;
/**
* 坦克大战的绘图区域
*/
//为了监听键盘事件,实现KeyLister
public class MyPanel extends JPanel implements KeyListener, Runnable {
//定义我的坦克
private int hitNums;
private Hero hero = null;
private Boolean flag = false;
//定义敌人的坦克
Vector<EnemyTank> enemyTanks = new Vector<>();
//定义一个存放 Node对象的 Vector,用来存放继续游戏时的坦克
Vector<Node> nodes = null;
//定义Vector用于存放炸弹
//说明,当子弹击中坦克时,加入Bomb对象到Bombs
Vector<Bomb> bombs = new Vector<>();
//定义三张图片用于爆炸效果
Image image1 = null;
Image image2 = null;
Image image3 = null;
public MyPanel(String key){
//判断文件是否存在
if(new File(Recorder.getRecordFile()).exists()) {
//读文件
nodes = Recorder.getNodesAndEnemyNums();
} else {
System.out.println("文件不存在,只能开启新游戏");
key = "1";
}
//传入 anemyTanks 并记录
Recorder.setAnemyTanks(enemyTanks);
//初始化自己坦克
hero = new Hero(50,600);
// 判断是重新开始,还是继续游戏
switch (key){
case "1"://重新开始
Recorder.setHitTankNums(0);
//初始化敌人坦克
for (int i = 0; i < 5; i++) {
//创建一个敌人坦克
EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);
//把敌方坦克集合传给Enemy类
enemyTank.setEnemyTanks(enemyTanks);
//设置方向
enemyTank.setDirect(2);
//启动敌方坦克
Thread thread = new Thread(enemyTank);
thread.start();
//给anemyTank加入一个子弹
Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
//加入enemyTank的Vector成员
enemyTank.getShots().add(shot);
//启动shot对象
new Thread(shot).start();
enemyTanks.add(enemyTank);
}
break;
case "2"://继续游戏
for (int i = 0; i < nodes.size(); i++) {
Node node = nodes.get(i);
//创建一个敌人坦克
EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY());
//将 anemyTanks设置个AnemyTank
enemyTank.setEnemyTanks(enemyTanks);
//设置方向
enemyTank.setDirect(node.getDirect());
//启动敌方坦克
Thread thread = new Thread(enemyTank);
thread.start();
//给anemyTank加入一个子弹
Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());
//加入enemyTank的Vector成员
enemyTank.getShots().add(shot);
//启动shot对象
new Thread(shot).start();
enemyTanks.add(enemyTank);
}
break;
default:
System.out.println("你输入的有误:");
}
//初始化图片对象
image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/baozha1.png"));
image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/baozha2.png"));
image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/baozha3.png"));
// 播放音乐
new AePlayWave("src\\start.wav").start();
}
//编写方法,显示我方击落敌方坦克的信息
public void showHitInfo(Graphics g){
//画出玩家的总成绩
g.setColor(Color.black);
Font font = new Font("宋体", Font.BOLD, 18);
g.setFont(font);
g.drawString("你累计击败敌方坦克", 810,30 );
drawTank(820, 60, g, 0, 0);//画出个敌方坦克
g.setColor(Color.black);//这里需要重新获取黑色
g.drawString(String.valueOf(Recorder.getHitTankNums()), 900, 100);
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0,0,800, 750);//填充矩形,默认黑色
showHitInfo(g);
if (hero != null && hero.isLife()){
//画出坦克--封装方法
drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);
}
//将hero中的shots集合遍历取出绘制,发射多颗子弹
for (int i = 0; i < hero.getShots().size(); i++) {
Shot shot = hero.getShots().get(i);
if (shot != null && shot.isLive()){
g.setColor(Color.yellow);
g.fill3DRect(shot.getX()-1,shot.getY()-1, 5, 5, false);
}else {//如果子弹已经失效,移除
hero.getShots().remove(shot);
}
}
//画出敌人的坦克
for (int i = 0; i < enemyTanks.size(); i++){
//取出坦克
EnemyTank enemyTank = this.enemyTanks.get(i);
//判断当前的坦克是否存活
if (enemyTank.isLive()){//当敌人坦克是存活的
drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 0);
//取出enemyTank所有子弹
for (int j = 0; j < enemyTank.getShots().size(); j++){
//取出子弹准备绘制
Shot shot = enemyTank.getShots().get(j);
//绘制
if (shot.isLive()){//isLive == true;
g.fill3DRect(shot.getX()-1, shot.getY()-1, 5, 5, false);
}else {
//移除子弹
enemyTank.getShots().remove(shot);
}
}
}
}
//如果bombs集合中有对象,就画出
for (int i = 0; i < bombs.size(); i++) {
//取出炸弹
Bomb bomb = bombs.get(i);
//根据当前bomb对象的life去画出对应的图像
if (bomb.getLife() > 6){
g.drawImage(image1, bomb.getX(), bomb.getY(), 60, 60, this);
}else if (bomb.getLife() > 3){
g.drawImage(image2, bomb.getX(), bomb.getY(), 60, 60, this);
}else {
g.drawImage(image3, bomb.getX(), bomb.getY(), 60, 60, this);
}
//让这个炸弹的生命值减少
bomb.lifeDown();
//如果bomb life为0,就从bombs的集合中删除
if (bomb.getLife() == 0){
bombs.remove(bomb);
}
}
}
//边写方法画出坦克
public void drawTank(int x, int y, Graphics g, int direct, int type){
//根据不同的坦克类型设置不同的颜色
switch (type){
case 0: //敌人的坦克
g.setColor(Color.CYAN);
break;
case 1: //我们的坦克
g.setColor(Color.YELLOW);
break;
}
//根据坦克方向来绘制坦克
//direct表示方向(0:向上 1:向右 2:向下 3:向左)
//
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.fill3DRect(x+18,y,4,20,false);
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.fill3DRect(x+30,y+18,30,4,false);
break;
case 2://表示向下
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.fill3DRect(x+18,y+30,4,30,false);
break;
case 3://表示向左
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.fill3DRect(x,y+18,30,4,false);
break;
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W) { //向上
//改变我方tank1方向
hero.setDirect(0);
if(hero.getY() > 0) { //控制移动范围
hero.moveUp();
}
} else if(e.getKeyCode() == KeyEvent.VK_A){//向左
hero.setDirect(3);
if(hero.getX() > 0){
hero.moveLeft();
}
} else if(e.getKeyCode() == KeyEvent.VK_S){//向下
hero.setDirect(2);
if(hero.getY() + 60 < 700) {
hero.moveDown();
}
} else if(e.getKeyCode() == KeyEvent.VK_D){//向右
hero.setDirect(1);
if(hero.getX() + 60 < 800) {
hero.moveRight();
}
}
//如果用户用户按下的是J,就发射
if (e.getKeyCode() == KeyEvent.VK_J){
//发射多颗子弹
hero.shotEnemyTank();
}
this.repaint();
}
//判断敌方坦克打到我方坦克
public void hitMyTank(){
//遍历所有的敌方坦克
for (int i = 0; i < enemyTanks.size(); i++) {
//取出敌方坦克
EnemyTank enemyTank = enemyTanks.get(i);
//遍历他的所有子弹
for(int j = 0; j < enemyTank.getShots().size(); j++){
Shot s = enemyTank.getShots().get(j);
//判断shot是否击中我方的坦克
if(hero.isLife() && s.isLive()){
hitTank(s, hero);
}
}
}
}
//如果我们可以发射多颗子弹
//在判断我方的坦克是否命中敌人时,需要把所有子弹遍历出来,挨个判断
//编写方法,判断我方的坦克是否命中目标
//什么时候判断我方坦克击中敌方的坦克
public void hitTank(Shot s, Tank tank){
switch (tank.getDirect()){
case 0://方向为上
if (s.getX() > tank.getX() && s.getX() < tank.getX() + 40
&& s.getY() > tank.getY() && s.getY() <= tank.getY() + 60
){
s.setLive(false);
tank.setLife(false);
//当我的子弹击中敌人的坦克后,将tank拿掉就可以了
enemyTanks.remove(tank);
//当我方击毁一个敌方坦克时,进行数据更改
if (tank instanceof EnemyTank){
Recorder.addHitTankNums();
}
//创建Bomb对象,加入到Bombs集合中来
Bomb bomb = new Bomb(tank.getX(),tank.getY());
bombs.add(bomb);
}
break;
case 1://方向为右
if (s.getX() > tank.getX() && s.getX() < tank.getX() + 60
&& s.getY() > tank.getY() && s.getY() < tank.getY() + 40
){
s.setLive(false);
tank.setLife(false);
//当我的子弹击中敌人的坦克后,将tank拿掉就可以了
enemyTanks.remove(tank);
//当我方击毁一个敌方坦克时,进行数据更改
if (tank instanceof EnemyTank){
Recorder.addHitTankNums();
}
//创建Bomb对象,加入到Bombs集合中来
Bomb bomb = new Bomb(tank.getX(),tank.getY());
bombs.add(bomb);
}
break;
case 2://方向为下
if (s.getX() > tank.getX() && s.getX() < tank.getX() + 60
&& s.getY() > tank.getY() && s.getY() <= tank.getY() + 40
){
s.setLive(false);
tank.setLife(false);
//当我的子弹击中敌人的坦克后,将tank拿掉就可以了
enemyTanks.remove(tank);
//当我方击毁一个敌方坦克时,进行数据更改
if (tank instanceof EnemyTank){
Recorder.addHitTankNums();
}
//创建Bomb对象,加入到Bombs集合中来
Bomb bomb = new Bomb(tank.getX(),tank.getY());
bombs.add(bomb);
}
break;
case 3:
if (s.getX() > tank.getX() && s.getX() < tank.getX() + 40
&& s.getY() > tank.getY() && s.getY() < tank.getY() + 60
){
s.setLive(false);
tank.setLife(false);
//当我的子弹击中敌人的坦克后,将tank拿掉就可以了
enemyTanks.remove(tank);
//当我方击毁一个敌方坦克时,进行数据更改
if (tank instanceof EnemyTank){
Recorder.addHitTankNums();
}
//创建Bomb对象,加入到Bombs集合中来
Bomb bomb = new Bomb(tank.getX(),tank.getY());
bombs.add(bomb);
}
break;
}
}
public void hitAnemyTank(){
for (int i = 0; i < hero.getShots().size(); i++) {
Shot shot = hero.getShots().get(i);
//判断是否击中敌人的坦克
if (shot != null && shot.isLive()) {//当我的子弹还活着
//遍历敌人所有的坦克
for (int j = 0; j < enemyTanks.size(); j++) {
EnemyTank enemyTank = enemyTanks.get(j);
hitTank(shot, enemyTank);
}
}
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void run() {
//每隔100毫秒,重绘区域
while (true){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//判断我方子弹是否击中敌方的 坦克
hitAnemyTank();
hitMyTank();
this.repaint();
}
}
}
10)TankGame类
package com.rxli.game;
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;
public class TankGame extends JFrame {
//定义一个MyPanel
private MyPanel mp = null;
static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
TankGame TankGame = new TankGame();
}
public TankGame(){
System.out.println("请输入选择: 1.新游戏 2.继续上局");
String key = scanner.next();
mp = new MyPanel(key);
//开启多线程
Thread thread = new Thread(mp);
thread.start();
this.add(mp);//绘图区域
this.setSize(1000,750);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.addKeyListener(mp);
//在JFrame 中增加相应关闭窗口的处理
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
Recorder.keepRecord();
System.exit(0);
}
});
}
}