坦克大战5.0
新增功能内容:(加入IO流内容)
- 防止敌坦克间重叠
- 击杀数显示
- 保存上局游戏进度–>两种开局方式
- 加入开局音乐
- 修复记录文件丢失后的异常
5.0版本为最终版
提示:爆炸图片需自行按路径放在工程文件的out文件夹对应的包下
以及适当位置安放开局音乐文件,否则会报空指针异常
画框
package com.hspedu.tankgame06;
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;
/**
* @ClassName
* @Description
* @Author zxk
* @DateTime 2022-01-21-20:33
* @Version
* 第六版:开局音乐->修复记录文件丢失后的异常
*/
public class ZxkTankGame06 extends JFrame {//画框
MyPanel mp = null;//定义画板
Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
ZxkTankGame06 zxkTankGame01 = new ZxkTankGame06();//初始化画框
}
public ZxkTankGame06(){
System.out.println("请选择:1.开始新游戏/2.继续上局游戏");
String key = scanner.next();
setSize(1300,950);//画框大小
mp = new MyPanel(key);//新建画板
new Thread(mp).start();
this.add(mp);//添加画板自动重画线程为了子弹和敌坦克的移动
addKeyListener(mp);//监听画板的键盘
setDefaultCloseOperation(EXIT_ON_CLOSE);//关闭操作
setVisible(true);//可视化
//画板中增加相应的关闭窗口的处理
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("监听到关闭窗口");
Recorder.keepRecord();
System.exit(0);
}
});
}
}
画板
package com.hspedu.tankgame06;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.Vector;
/**
* @ClassName
* @Description
* @Author zxk
* @DateTime 2022-01-21-20:32
* @Version
*///画板
public class MyPanel extends JPanel implements KeyListener, Runnable {
Hero hero = null;//定义我的坦克
Vector<EnemyTank> enemyTanks = new Vector<>();//创建敌坦克集合
Vector<Bomb> bombs = new Vector<>();//创建炸弹集合
Vector<Node> nodes = null;//用于接收上局敌坦克信息
//定义三张爆炸图片
Image image1 = null;
Image image2 = null;
Image image3 = null;
public MyPanel(String key) {
String recordFile = Recorder.getRecordFile();
File file = new File(recordFile);
if (!file.exists() ) {//文件丢失->强制开新游戏
System.out.println("没有上局记录,选择重开游戏!");
key = "1";
}
//初始化Hero
hero = new Hero(400, 400, 'a', 10);
nodes = Recorder.getInfo();//接收上局敌坦克信息
switch (key) {
case "1"://新游戏
//初始化敌坦克及其子弹
for (int i = 0; i < 3; i++) {
EnemyTank enemyTank = new EnemyTank(100 + i * 100, 0, 's', 1);
new Thread(enemyTank).start();
enemyTanks.add(enemyTank);
Bullet ammo = new Bullet(enemyTank.getX() + 20, enemyTank.getY() + 60, 's');
new Thread(ammo).start();
enemyTank.ammos.add(ammo);
}
break;
case "2"://继续上局
for (int i = 0; i < nodes.size(); i++) {
Node node = nodes.get(i);
EnemyTank enemyTank = new EnemyTank(node.getX(), node.getY(), node.getDirect(), 1);
new Thread(enemyTank).start();
enemyTanks.add(enemyTank);
Bullet ammo = new Bullet(enemyTank.getX() + 20, enemyTank.getY() + 30, enemyTank.getDirection());
new Thread(ammo).start();
enemyTank.ammos.add(ammo);
}
break;
}
//敌坦克集合传递给Recorder属性
Recorder.setEnemyTanks(enemyTanks);
//加载图片
image1 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif"));
image2 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif"));
image3 = Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif"));//必须用"/"
//开局音效
new AePlayWave("chapter20\\src\\111.wav").start();
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillRect(0, 0, 1000, 750);//填满画板
//绘制Hero
if (hero.alive) {
drawTank(hero.getX(), hero.getY(), g, hero.getDirection(), true);
}
//绘制Hero的子弹
if (hero.bullets != null) {
for (int i = 0; i < hero.bullets.size(); i++) {
Bullet bullet = hero.bullets.get(i);//从弹夹取出子弹
if (bullet != null && bullet.alive) {
g.draw3DRect(bullet.x, bullet.y, 1, 1, false);
} else {
hero.bullets.remove(bullet);//移除已消亡的子弹
}
}
}
//绘制敌坦克及其子弹
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (enemyTank.alive) {
drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirection(), false);
enemyTank.setEnemyTanks(enemyTanks);//敌坦克集合赋值给敌坦克的属性
} else {
enemyTanks.remove(enemyTank);
}
for (int j = 0; j < enemyTank.ammos.size(); j++) {
//取出子弹绘制
Bullet ammo = enemyTank.ammos.get(j);
if (ammo != null && ammo.alive) {
g.draw3DRect(ammo.x, ammo.y, 1, 1, false);
} else {
enemyTank.ammos.remove(ammo);
}
}
}
//绘制爆炸
for (int i = 0; i < bombs.size(); i++) {
Bomb bomb = bombs.get(i);
if (bomb.life > 6) {
g.drawImage(image1, bomb.x, bomb.y, 60, 60, this);
} else if (bomb.life > 3) {
g.drawImage(image2, bomb.x, bomb.y, 60, 60, this);
} else {
g.drawImage(image3, bomb.x, bomb.y, 60, 60, this);
}
bomb.lifeDown();
if (!bomb.alive) {
bombs.remove(bomb);
}
}
showInfo(g);
}
//编写方法:显示我方击毁敌方坦克信息
public void showInfo(Graphics g){
g.setColor(Color.BLACK);
Font font = new Font("宋体", Font.BOLD, 25);
g.setFont(font);
g.drawString("您累计击毁敌方坦克", 1020, 30);
drawTank(1020, 60, g, 'w', false);
g.setColor(Color.BLACK);//重设颜色为黑
g.drawString(Recorder.getAllEnemyTankNum()+"",1080,100);
}
//封装坦克绘制方法
public void drawTank(int x, int y, Graphics g, char direction, boolean type) {
if (type) {//敌我坦克颜色
g.setColor(Color.YELLOW);
} else {
g.setColor(Color.cyan);
}
//由方向绘制坦克各部分位置
switch (direction) {
case 'w':
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 's':
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;
case 'a':
g.fill3DRect(x - 10, y + 10, 60, 10, false);//上车轮
g.fill3DRect(x - 10, y + 40, 60, 10, false);//下车轮
g.fill3DRect(x, y + 20, 40, 20, false);//车底
g.fillOval(x + 10, y + 20, 20, 20);//圆盖不变
g.drawLine(x + 20, y + 30, x - 10, y + 30);//炮筒
break;
case 'd':
g.fill3DRect(x - 10, y + 10, 60, 10, false);//上车轮
g.fill3DRect(x - 10, y + 40, 60, 10, false);//下车轮
g.fill3DRect(x, y + 20, 40, 20, false);//车底
g.fillOval(x + 10, y + 20, 20, 20);//圆盖不变
g.drawLine(x + 20, y + 30, x + 50, y + 30);//炮筒
break;
}
}
//判断方法:子弹是否击中坦克->坦克消亡,子弹消亡->新建爆炸对象
/*public void hitEnemyTank(Bullet bullet, EnemyTank enemyTank){
switch (enemyTank.getDirection()) {
case 'w':
case 's':
if (bullet.x >= enemyTank.getX() && bullet.x <= enemyTank.getX() + 40
&& bullet.y >= enemyTank.getY() && bullet.y <= enemyTank.getY() + 60) {
bombs.add(new Bomb(enemyTank.getX(), enemyTank.getY()));
enemyTank.alive = false;
bullet.alive = false;
}
break;
case 'a':
case 'd':
if (bullet.x >= enemyTank.getX() - 10 && bullet.x <= enemyTank.getX() + 50
&& bullet.y >= enemyTank.getY() + 10 && bullet.y <= enemyTank.getY() + 50) {
bombs.add(new Bomb(enemyTank.getX()-10, enemyTank.getY()+10));
enemyTank.alive = false;
bullet.alive = false;
}
break;
}
}*/
//判断的参数类型为Tank (父类),返回坦克的存活布尔值
public boolean hitTank(Bullet bullet, Tank tank) {
switch (tank.getDirection()) {
case 'w':
case 's':
if (bullet.x >= tank.getX() && bullet.x <= tank.getX() + 40
&& bullet.y >= tank.getY() && bullet.y <= tank.getY() + 60) {
bombs.add(new Bomb(tank.getX(), tank.getY()));
// enemyTank.alive = false;
bullet.alive = false;
return false;
}
break;
case 'a':
case 'd':
if (bullet.x >= tank.getX() - 10 && bullet.x <= tank.getX() + 50
&& bullet.y >= tank.getY() + 10 && bullet.y <= tank.getY() + 50) {
bombs.add(new Bomb(tank.getX() - 10, tank.getY() + 10));
// enemyTank.alive = false;
bullet.alive = false;
return false;
}
break;
}
return true;
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {//重写按键事件
//按键控制移动
if (e.getKeyCode() == KeyEvent.VK_W) {
hero.setDirection('w');
hero.moveUp();
}
if (e.getKeyCode() == KeyEvent.VK_S) {
hero.setDirection('s');
hero.moveDown();
}
if (e.getKeyCode() == KeyEvent.VK_A) {
hero.setDirection('a');
hero.moveLeft();
}
if (e.getKeyCode() == KeyEvent.VK_D) {
hero.setDirection('d');
hero.moveRight();
}
//j键hero射击
if (e.getKeyCode() == KeyEvent.VK_J) {
/*if (hero.bullet == null || !hero.bullet.alive) {
hero.shot();
}*/
hero.shot();
}
this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(100);//定时自动重画为显示自动移动的对象
} catch (InterruptedException e) {
e.printStackTrace();
}
if (hero.bullet != null) {//定时判断是否击中敌坦克
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);//取出敌坦克
for (int j = 0; j < hero.bullets.size(); j++) {
Bullet bullet = hero.bullets.get(j);//取出Hero子弹
if (enemyTank.alive) {//判断存活的坦克是否被击中
enemyTank.alive = hitTank(bullet, enemyTank);
if (!enemyTank.alive) {//如果被击中则记录下来
Recorder.addEnemyTankNum();
}
}
}
}
}
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);//取出敌坦克
for (int j = 0; j < enemyTank.ammos.size(); j++) {
Bullet ammo = enemyTank.ammos.get(j);//取出其子弹
if (hero.alive) {//保证hero存活才判断,hero消亡如果调用则会复活
hero.alive = hitTank(ammo, hero);
}
}
}
repaint();
}
}
}
Tank类
package com.hspedu.tankgame06;
/**
* @ClassName
* @Description
* @Author zxk
* @DateTime 2022-01-21-20:32
* @Version
*///坦克类
public class Tank {
private int x;
private int y;
private char direction;
private int speed;
public Tank(int x, int y, char direction, int speed) {
this.x = x;
this.y = y;
this.direction = direction;
this.speed = speed;
}
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 char getDirection() {
return direction;
}
public void setDirection(char direction) {
this.direction = direction;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
//坦克四个移动方法
public void moveUp(){
if (y > 0) {
y -= speed;
}
}
public void moveDown(){
if (y+60< 750) {
y += speed;
}
}
public void moveLeft(){
if (x -10> 0) {
x -= speed;
}
}
public void moveRight(){
if (x +50< 1000) {
x += speed;
}
}
}
Hero类
package com.hspedu.tankgame06;
import java.util.Vector;
/**
* @ClassName
* @Description
* @Author zxk
* @DateTime 2022-01-21-20:32
* @Version
*///我方坦克
public class Hero extends Tank {
boolean alive = true;
Bullet bullet = null;//空弹
Vector<Bullet> bullets = new Vector<>();
public Hero(int x, int y, char direction, int speed) {
super(x, y, direction, speed);
}
public void shot(){//射击时填弹
if (bullets.size() >= 5) {
return;
}
switch (getDirection()) {
case 'w':
bullet = new Bullet(getX() + 20, getY(), 'w');
break;
case 's':
bullet = new Bullet(getX() + 20, getY()+60, 's');
break;
case 'a':
bullet = new Bullet(getX() -10, getY()+30, 'a');
break;
case 'd':
bullet = new Bullet(getX() +50, getY()+30, 'd');
break;
}
bullets.add(bullet);
new Thread(bullet).start();//启动该子弹线程控制轨迹
/*for (int i = 0; i < bullets.size(); i++) {
Bullet bullet = bullets.get(i);
new Thread(bullet).start();
}*/
}
}
EnemyTank类
package com.hspedu.tankgame06;
import java.util.Vector;
/**
* @ClassName
* @Description
* @Author zxk
* @DateTime 2022-01-21-20:32
* @Version
* 敌坦克线程:自由移动
*/
public class EnemyTank extends Tank implements Runnable{
boolean alive = true;
Bullet ammo = null;
Vector<Bullet> ammos = new Vector<>();//敌坦克弹夹
Vector<EnemyTank> enemyTanks = new Vector<>();//用以防止重叠的敌坦克集合属性
public EnemyTank(int x, int y, char direction, int speed) {
super(x, y, direction, speed);
}
public void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
this.enemyTanks = enemyTanks;
}
//判断当前坦克与其他坦克是否重叠true/不重叠false
//当前坦克必须分四个方向,其他坦克可以反向归为一类
public boolean isTouch() {
switch (getDirection()) {
//当前坦克方向为:w
case 'w':
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (this != enemyTank) {
//其他坦克方向为:w/s --> x属于[x,x+40],y属于[y,y+60]
if (enemyTank.getDirection() == 'w' || enemyTank.getDirection() == 's') {
//当前坦克左上角点(x,y)进入其他坦克
if (getX() >= enemyTank.getX() && getX() <= enemyTank.getX() + 40
&& getY() >= enemyTank.getY() && getY() <= enemyTank.getY() + 60) {
return true;
}
//当前坦克右上角点(x+40,y)进入其他坦克
if (getX() +40>= enemyTank.getX() && getX() +40<= enemyTank.getX() + 40
&& getY() >= enemyTank.getY() && getY() <= enemyTank.getY() + 60) {
return true;
}
}
//其他坦克方向为:a/d --> x属于[x-10,x+50],y属于[y+10,y+50]
if (enemyTank.getDirection() == 'a' || enemyTank.getDirection() == 'd') {
//当前坦克左上角点(x,y)进入其他坦克
if (getX() >= enemyTank.getX()-10 && getX() <= enemyTank.getX() + 50
&& getY() >= enemyTank.getY()+10 && getY() <= enemyTank.getY() + 50) {
return true;
}
//当前坦克右上角点(x+40,y)进入其他坦克
if (getX() +40>= enemyTank.getX()-10 && getX() +40<= enemyTank.getX() + 50
&& getY() >= enemyTank.getY() +10&& getY() <= enemyTank.getY() + 50) {
return true;
}
}
}
}
break;
//当前坦克方向为:s
case 's':
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (this != enemyTank) {
//其他坦克方向为:w/s --> x属于[x,x+40],y属于[y,y+60]
if (enemyTank.getDirection() == 'w' || enemyTank.getDirection() == 's') {
//当前坦克左下角点(x,y+60)进入其他坦克
if (getX() >= enemyTank.getX() && getX() <= enemyTank.getX() + 40
&& getY()+60 >= enemyTank.getY() && getY()+60 <= enemyTank.getY() + 60) {
return true;
}
//当前坦克右下角点(x+40,y+60)进入其他坦克
if (getX() +40>= enemyTank.getX() && getX()+40 <= enemyTank.getX() + 40
&& getY()+60 >= enemyTank.getY() && getY()+60 <= enemyTank.getY() + 60) {
return true;
}
}
//其他坦克方向为:a/d --> x属于[x-10,x+50],y属于[y+10,y+50]
if (enemyTank.getDirection() == 'a' || enemyTank.getDirection() == 'd') {
//当前坦克左下角点(x,y+60)进入其他坦克
if (getX() >= enemyTank.getX() -10 && getX()<= enemyTank.getX() + 50
&& getY()+60 >= enemyTank.getY()+10 && getY()+60 <= enemyTank.getY() + 50) {
return true;
}
//当前坦克右下角点(x+40,y+60)进入其他坦克
if (getX() +40>= enemyTank.getX() -10&& getX()+40 <= enemyTank.getX() + 50
&& getY()+60 >= enemyTank.getY()+10 && getY()+60 <= enemyTank.getY() + 50) {
return true;
}
}
}
}
break;
//当前坦克方向为:a
case 'a':
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (this != enemyTank) {
//其他坦克方向为:w/s --> x属于[x,x+40],y属于[y,y+60]
if (enemyTank.getDirection() == 'w' || enemyTank.getDirection() == 's') {
//当前坦克左上角点(x-10,y+10)进入其他坦克
if (getX() -10>= enemyTank.getX() && getX() -10<= enemyTank.getX() + 40
&& getY() +10>= enemyTank.getY() && getY()+10 <= enemyTank.getY() + 60) {
return true;
}
//当前坦克左下角点(x-10,y+50)进入其他坦克
if (getX() -10>= enemyTank.getX() && getX() -10<= enemyTank.getX() + 40
&& getY()+50 >= enemyTank.getY() && getY()+50 <= enemyTank.getY() + 60) {
return true;
}
}
//其他坦克方向为:a/d --> x属于[x-10,x+50],y属于[y+10,y+50]
if (enemyTank.getDirection() == 'a' || enemyTank.getDirection() == 'd') {
//当前坦克左上角点(x-10,y+10)进入其他坦克
if (getX() -10>= enemyTank.getX()-10 && getX() -10<= enemyTank.getX() + 50
&& getY() +10>= enemyTank.getY()+10 && getY()+10 <= enemyTank.getY() + 50) {
return true;
}
//当前坦克左下角点(x-10,y+50)进入其他坦克
if (getX() -10>= enemyTank.getX() -10 && getX()-10<= enemyTank.getX() + 50
&& getY()+50 >= enemyTank.getY()+10 && getY()+50 <= enemyTank.getY() + 50) {
return true;
}
}
}
}
break;
//当前坦克方向为:d
case 'd':
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if (this != enemyTank) {
//其他坦克方向为:w/s --> x属于[x,x+40],y属于[y,y+60]
if (enemyTank.getDirection() == 'w' || enemyTank.getDirection() == 's') {
//当前坦克右上角点(x+50,y+10)进入其他坦克
if (getX() +50>= enemyTank.getX() && getX() +50<= enemyTank.getX() + 40
&& getY() +10>= enemyTank.getY() && getY()+10 <= enemyTank.getY() + 60) {
return true;
}
//当前坦克右下角点(x+50,y+50)进入其他坦克
if (getX() +50>= enemyTank.getX() && getX()+50 <= enemyTank.getX() + 40
&& getY()+50 >= enemyTank.getY() && getY()+50 <= enemyTank.getY() + 60) {
return true;
}
}
//其他坦克方向为:a/d --> x属于[x-10,x+50],y属于[y+10,y+50]
if (enemyTank.getDirection() == 'a' || enemyTank.getDirection() == 'd') {
//当前坦克右上角点(x+50,y+10)进入其他坦克
if (getX() +50>= enemyTank.getX()-10 && getX() +50<= enemyTank.getX() + 50
&& getY() +10>= enemyTank.getY() +10&& getY() +10<= enemyTank.getY() + 50) {
return true;
}
//当前坦克右下角点(x+50,y+50)进入其他坦克
if (getX() +50>= enemyTank.getX() -10&& getX()+50 <= enemyTank.getX() + 50
&& getY()+50 >= enemyTank.getY()+10 && getY()+50 <= enemyTank.getY() + 50) {
return true;
}
}
}
}
break;
}
return false;
}
@Override
public void run() {
while (true) {//敌坦克子弹消亡立即填弹并开启子弹线程
switch (getDirection()) {
case 'w':
ammo = new Bullet(getX() + 20, getY(), 'w');
break;
case 's':
ammo = new Bullet(getX() + 20, getY()+60, 's');
break;
case 'a':
ammo = new Bullet(getX() -10, getY()+30, 'a');
break;
case 'd':
ammo = new Bullet(getX() +50, getY()+30, 'd');
break;
}
if (ammos.size() == 0) {
ammos.add(ammo);
new Thread(ammo).start();
}
switch (getDirection()) {//按随机生成的方向移动30次(50ms一次)
case 'w':
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!isTouch()) {
moveUp();
}
}
break;
case 's':
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!isTouch()) {
moveDown();
}
}
break;
case 'a':
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!isTouch()) {
moveLeft();
}
}
break;
case 'd':
for (int i = 0; i < 30; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (!isTouch()) {
moveRight();
}
}
break;
}
int direct = (int)(Math.random() * 4);//生成随机方向
switch (direct) {
case 0:
setDirection('w');
break;
case 1:
setDirection('s');
break;
case 2:
setDirection('a');
break;
case 3:
setDirection('d');
break;
}
}
}
}
Bullet类
package com.hspedu.tankgame06;
/**
* @ClassName
* @Description
* @Author zxk
* @DateTime 2022-01-21-21:49
* @Version
*/
public class Bullet implements Runnable{
int x;
int y;
char direction;
boolean alive = true;
public Bullet(int x, int y, char direction) {
this.x = x;
this.y = y;
this.direction = direction;
}
@Override
public void run() {
while (true) {
switch (direction) {
case 'w':
y -= 5;
break;
case 's':
y += 5;
break;
case 'a':
x -= 5;
break;
case 'd':
x += 5;
break;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
//子弹脱离画板或消亡(击中)终止线程
if (x <= 0 || x >= 1000 || y <= 0 || y >= 750||!alive) {
System.out.println("子弹线程终止");
alive = false;//此时不画子弹
break;
}
}
}
}
Bomb类
package com.hspedu.tankgame06;
/**
* @ClassName
* @Description
* @Author zxk
* @DateTime 2022-01-20-10:46
* @Version
*/
public class Bomb {
int x, y;
int life = 9;
boolean alive = true;
public Bomb(int x, int y) {
this.x = x;
this.y = y;
}
//减少生命值
public void lifeDown() {
if (life > 0) {
life--;
} else {
alive = false;
}
}
}
Recorder类
package com.hspedu.tankgame06;
import java.io.*;
import java.util.Vector;
/**
* @ClassName
* @Description
* @Author zxk
* @DateTime 2022-01-29-21:03
* @Version 该类用于记录相关信息, 和文件交互
*/
public class Recorder {
private static int allEnemyTankNum = 0;
private static Vector<EnemyTank> enemyTanks = null;
private static Vector<Node> nodes = new Vector<>();//用于存放读到的坦克信息到结点
private static String recordFile = "chapter20\\src\\myRecord.txt";//保存到src下
//读取上局坦克信息到结点
public static Vector<Node> getInfo() {
BufferedReader br = null;
String line;
try {
File file = new File(recordFile);
if (file.exists()) {//健壮性判断:文件找不到异常
br = new BufferedReader(new FileReader(recordFile));
allEnemyTankNum = Integer.parseInt(br.readLine());//String->int存活数
while ((line = br.readLine()) != null) {
String[] s = line.split(" ");
Node node = new Node(Integer.parseInt(s[0]), Integer.parseInt(s[1]), s[2].charAt(0));//位置
nodes.add(node);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return nodes;
}
//记录上局游戏的杀敌数,敌人属性
public static void keepRecord() {
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(recordFile));
//写入杀敌数
bw.write(allEnemyTankNum + "");//方法形参没有int类型
bw.newLine();
//写入敌人退出时的属性
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
bw.write(enemyTank.getX() + " " + enemyTank.getY() + " " + enemyTank.getDirection());
bw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (bw != null) {
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//提供获取文件路径的方法
public static String getRecordFile() {
return recordFile;
}
public static void setAllEnemyTankNum(int allEnemyTankNum) {
Recorder.allEnemyTankNum = allEnemyTankNum;
}
public static int getAllEnemyTankNum() {
return allEnemyTankNum;
}
public static Vector<EnemyTank> getEnemyTanks() {
return enemyTanks;
}
public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
Recorder.enemyTanks = enemyTanks;
}
public static void addEnemyTankNum() {
++allEnemyTankNum;
}
}
Node类
package com.hspedu.tankgame06;
/**
* @ClassName
* @Description
* @Author zxk
* @DateTime 2022-01-30-0:00
* @Version
记录坦克信息到结点
*/
public class Node {
private int x;
private int y;
private char direct;
public Node(int x, int y, char 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 char getDirect() {
return direct;
}
public void setDirect(char direct) {
this.direct = direct;
}
}
AePlayWave类
package com.hspedu.tankgame06;
import javax.sound.sampled.*;
import java.io.File;
import java.io.IOException;
/**
* @author 韩顺平
* @version 1.0
* 该类用于开局播放音乐
*/
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();
}
}
}