一.主要的几个类
- Mypanel
- WwyTankGame01
- AnemyTank //写代码时候把单词拼错了哈哈不好意思
- Bomb
- Recorder
- Node
- Shot
- Tank
- Hero
二.功能实现的思路
1.画出敌我坦克
2.实现发射子弹
3.击中时坦克爆炸和消失
4.解决出界问题
5.解决碰撞问题
三.功能的实现
1. Mypanel
这个类是坦克的大战的绘图区域,实现功能最也最为的复杂,这个类用到了java的绘图
简单的学习这个绘图原理的使用
public class DrawCircle extends JFrame{//JFrame对应的窗口,可以理解为一个画框//定义一个面板private MyPanel mp = null;public static void main(String[] args) {new DrawCircle();}public DrawCircle(){//初始化面板mp = new MyPanel();//构造器//把我们的面板放入我们的窗口this.add(mp);//设置窗口的大小this.setSize(400,300);//可以显示this.setVisible(true);//当点击窗口的小x,程序完全退出this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}
}
//1.首先定义一个面板MyPanel,继承JPanel类,画图形,就在面板上画
class MyPanel extends JPanel{//说明://1.MyPanel 对象就是一个画板//2.Graphics g 把g理解为一个画笔//3.Graphics 提供了很多绘图的方法@Overridepublic void paint(Graphics g){//绘图方法super.paint(g);//画出一个圆g.drawOval(10,10,10,100);}
}
package tankgame3;import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
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<AnemyTank> anemyTanks = new Vector<>();//定义一个存放 Node对象的 Vector,用来存放继续游戏时的坦克Vector<Node> nodes = Recorder.getNodesAndAanemyNums();//定义Vector用于存放炸弹//说明,当子弹击中坦克时,加入Bomb对象到BombsVector<Bomb> bombs = new Vector<>();//定义三张图片用于爆炸效果Image image1 = null;Image image2 = null;Image image3 = null;public MyPanel(String key){//传入 anemyTanks 并记录Recorder.setAnemyTanks(anemyTanks);//初始化自己坦克hero = new Hero(50,600);// 判断是重新开始,还是继续游戏switch (key){case "1"://重新开始//Recorder.setHitTankNums(0);//初始化敌人坦克for (int i = 0; i < 5; i++) {//创建一个敌人坦克AnemyTank anemyTank = new AnemyTank((100 * (i + 1)), 0);//将 anemyTanks设置个AnemyTankanemyTank.setAnemyTanks(anemyTanks);//设置方向anemyTank.setDirect(2);//启动敌方坦克Thread thread = new Thread(anemyTank);thread.start();//给anemyTank加入一个子弹Shot shot = new Shot(anemyTank.getX() + 20, anemyTank.getY() + 60, anemyTank.getDirect());//加入enemyTank的Vector成员anemyTank.getShots().add(shot);//启动shot对象new Thread(shot).start();anemyTanks.add(anemyTank);}break;case "2"://继续游戏for (int i = 0; i < nodes.size(); i++) {Node node = nodes.get(i);//创建一个敌人坦克AnemyTank anemyTank = new AnemyTank(node.getX(), node.getY());//将 anemyTanks设置个AnemyTankanemyTank.setAnemyTanks(anemyTanks);//设置方向anemyTank.setDirect(node.getDireact());//启动敌方坦克Thread thread = new Thread(anemyTank);thread.start();//给anemyTank加入一个子弹Shot shot = new Shot(anemyTank.getX() + 20, anemyTank.getY() + 60, anemyTank.getDirect());//加入enemyTank的Vector成员anemyTank.getShots().add(shot);//启动shot对象new Thread(shot).start();anemyTanks.add(anemyTank);}break;default:System.out.println("你输入的有误:");}//初始化图片对象image1 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/3.png"));image2 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/2.png"));image3 = Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/1.png"));}//编写方法,显示我方击落敌方坦克的信息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);}@Overridepublic voidpaint(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.blue);g.fill3DRect(shot.getX(),shot.getY(), 10, 10, false);}else {//如果子弹已经失效,移除hero.getShots().remove(shot);}}//画出敌人的坦克for (int i = 0; i < anemyTanks.size(); i++){//取出坦克AnemyTank anemyTank = this.anemyTanks.get(i);//判断当前的坦克是否存活if (anemyTank.isLive()){//当敌人坦克是存活的drawTank(anemyTank.getX(), anemyTank.getY(), g, anemyTank.getDirect(), 0);//取出enemyTank所有子弹for (int j = 0; j < anemyTank.getShots().size(); j++){//取出子弹准备绘制Shot shot = anemyTank.getShots().get(j);//绘制if (shot.isLive()){//isLive == true;g.draw3DRect(shot.getX(), shot.getY(), 5, 5, false);}else {//移除子弹anemyTank.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;}}@Overridepublic void keyTyped(KeyEvent e) {}@Overridepublic void keyPressed(KeyEvent e) {if (e.getKeyCode() == KeyEvent.VK_W){hero.setDirect(0);hero.moveUp();}else if (e.getKeyCode() == KeyEvent.VK_D){hero.setDirect(1);hero.moveRight();}else if (e.getKeyCode() == KeyEvent.VK_S){hero.setDirect(2);hero.moveDown();}else if (e.getKeyCode() == KeyEvent.VK_A){hero.setDirect(3);hero.moveLeft();}//如果用户用户按下的是J,就发射if (e.getKeyCode() == KeyEvent.VK_J){System.out.println("用户按下了J,开始射击");
// 发射一颗子弹
// if (hero.getShot() == null || !hero.getShot().isLive()){
// hero.shotEnemyTank();
// }//发射多颗子弹hero.shotEnemyTank();}this.repaint();}//判断敌方坦克打到我方坦克public void hitMyTank(){//遍历所有的敌方坦克for (int i = 0; i < anemyTanks.size(); i++) {//取出敌方坦克AnemyTank anemyTank = anemyTanks.get(i);//遍历他的所有子弹for(int j = 0; j < anemyTank.getShots().size(); j++){Shot s = anemyTank.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拿掉就可以了anemyTanks.remove(tank);//当我方击毁一个敌方坦克时,进行数据更改if (tank instanceof AnemyTank){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拿掉就可以了anemyTanks.remove(tank);//当我方击毁一个敌方坦克时,进行数据更改if (tank instanceof AnemyTank){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拿掉就可以了anemyTanks.remove(tank);//当我方击毁一个敌方坦克时,进行数据更改if (tank instanceof AnemyTank){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拿掉就可以了anemyTanks.remove(tank);//当我方击毁一个敌方坦克时,进行数据更改if (tank instanceof AnemyTank){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 < anemyTanks.size(); j++) {AnemyTank anemyTank = anemyTanks.get(j);hitTank(shot, anemyTank);}}}}@Overridepublic void keyReleased(KeyEvent e) {}@Overridepublic void run() {//每隔100毫秒,重绘区域while (true){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//判断我方子弹是否击中敌方的 坦克hitAnemyTank();hitMyTank();this.repaint();}}
}
2.WwyTankGame01
package tankgame3;import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;public class WwyTankGame1 extends JFrame {//定义一个MyPanelprivate MyPanel mp = null;static Scanner scanner = new Scanner(System.in);public static void main(String[] args) {WwyTankGame1 wwyTankGame = new WwyTankGame1();}public WwyTankGame1(){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() {@Overridepublic void windowClosing(WindowEvent e) {super.windowClosing(e);Recorder.keepRecord();System.exit(0);}});}
}
3.AnemyTank
package tankgame3;import java.util.Vector;public class AnemyTank extends Tank implements Runnable{private boolean isLive = true;//炮弹private Vector<Shot> shots = new Vector<>();//获取所有的敌人的坦克private Vector<AnemyTank> anemyTanks = new Vector<>();public AnemyTank(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<AnemyTank> getAnemyTanks() {return anemyTanks;}//这里提供一个方法,可以将 Mypanel 的成员 anemyTanks 成员变量设置到本类public void setAnemyTanks(Vector<AnemyTank> anemyTanks) {this.anemyTanks = anemyTanks;}//编写方法,判断当前这个敌人的坦克,是否和 anemyTanks 中的其他坦克发生重叠或者碰撞public boolean isTouchAnemyTank(){//判断当前敌人坦克的方向(this)方向switch (this.getDirect()){case 0://上//让当前坦克和所有的敌人坦克比较for (int i = 0; i < anemyTanks.size(); i++) {//从vector取出一个坦克来AnemyTank anemyTank = anemyTanks.get(i);//不和自己比较if (anemyTank != this){//如果敌人坦克是上下//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]// y:[anemyTank.getY(), nemyTank.getY() + 60]if (anemyTank.getDirect() == 0 || anemyTank.getDirect() == 2){//敌人坦克左上坐标if (this.getX() >= anemyTank.getX()&& this.getX() <= anemyTank.getX() + 40&& this.getY() >= anemyTank.getY()&& this.getY() <= anemyTank.getY() + 60) {return true;}//敌人坦克右下的坐标if (this.getX() + 40 >= anemyTank.getX()&& this.getX() + 40 <= anemyTank.getX() + 40&& this.getY() >= anemyTank.getY()&& this.getY() <= anemyTank.getY() + 60) {return true;}}//如果敌人的坦克是左右if (anemyTank.getDirect() == 1 || anemyTank.getDirect() == 3){//敌人坦克左上坐标if (this.getX() >= anemyTank.getX()&& this.getX() <= anemyTank.getX() + 60&& this.getY() >= anemyTank.getY()&& this.getY() <= anemyTank.getY() + 40) {return true;}//敌人坦克左下的坐标if (this.getX() + 40 >= anemyTank.getX()&& this.getX() + 40 <= anemyTank.getX() + 60&& this.getY() >= anemyTank.getY()&& this.getY() <= anemyTank.getY() + 40) {return true;}}}}case 1://让当前坦克和所有的敌人坦克比较for (int i = 0; i < anemyTanks.size(); i++) {//从vector取出一个坦克来AnemyTank anemyTank = anemyTanks.get(i);//不和自己比较if (anemyTank != this){//如果敌人坦克是上下//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]// y:[anemyTank.getY(), nemyTank.getY() + 60]if (anemyTank.getDirect() == 0 || anemyTank.getDirect() == 2){//敌人坦克右上坐标if (this.getX() + 60 >= anemyTank.getX()&& this.getX() + 60 <= anemyTank.getX() + 40&& this.getY() >= anemyTank.getY()&& this.getY() <= anemyTank.getY() + 60) {return true;}//敌人坦克右下的坐标if (this.getX() + 60 >= anemyTank.getX()&& this.getX() + 60 <= anemyTank.getX() + 40&& this.getY() + 40 >= anemyTank.getY()&& this.getY() + 40 <= anemyTank.getY() + 60) {return true;}}//如果敌人的坦克是左右if (anemyTank.getDirect() == 1 || anemyTank.getDirect() == 3){//敌人坦克右上边坐标if (this.getX() + 60 >= anemyTank.getX()&& this.getX() +60 <= anemyTank.getX() + 60&& this.getY() + 60 >= anemyTank.getY()&& this.getY() <= anemyTank.getY() + 40) {return true;}//敌人坦克右下的坐标if (this.getX() + 60 >= anemyTank.getX()&& this.getX() + 60 <= anemyTank.getX() + 60&& this.getY() + 40 >= anemyTank.getY()&& this.getY() + 40 <= anemyTank.getY() + 40) {return true;}}}}case 2://让当前坦克和所有的敌人坦克比较for (int i = 0; i < anemyTanks.size(); i++) {//从vector取出一个坦克来AnemyTank anemyTank = anemyTanks.get(i);//不和自己比较if (anemyTank != this){//如果敌人坦克是上下//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]// y:[anemyTank.getY(), nemyTank.getY() + 60]if (anemyTank.getDirect() == 0 || anemyTank.getDirect() == 2){//敌人坦克左下坐标if (this.getX() >= anemyTank.getX()&& this.getX() <= anemyTank.getX() + 40&& this.getY() + 60 >= anemyTank.getY()&& this.getY() + 60 <= anemyTank.getY() + 60) {return true;}//敌人坦克右下的坐标if (this.getX() + 40 >= anemyTank.getX()&& this.getX() + 40 <= anemyTank.getX() + 40&& this.getY() + 60 >= anemyTank.getY()&& this.getY() + 60 <= anemyTank.getY() + 60) {return true;}}//如果敌人的坦克是左右if (anemyTank.getDirect() == 1 || anemyTank.getDirect() == 3){//敌人坦克左边坐标if (this.getX() >= anemyTank.getX()&& this.getX() <= anemyTank.getX() + 60&& this.getY() + 60 >= anemyTank.getY()&& this.getY() + 60 <= anemyTank.getY() + 40) {return true;}//敌人坦克右边的坐标if (this.getX() + 40 >= anemyTank.getX()&& this.getX() + 40 <= anemyTank.getX() + 60&& this.getY() + 60 >= anemyTank.getY()&& this.getY() + 60 <= anemyTank.getY() + 40) {return true;}}}}case 3://让当前坦克和所有的敌人坦克比较for (int i = 0; i < anemyTanks.size(); i++) {//从vector取出一个坦克来AnemyTank anemyTank = anemyTanks.get(i);//不和自己比较if (anemyTank != this){//如果敌人坦克是上下//敌人的位置坐标x:[anemyTank.getX(), anemyTank.getX() + 40]// y:[anemyTank.getY(), nemyTank.getY() + 60]if (anemyTank.getDirect() == 0 || anemyTank.getDirect() == 2){//敌人坦克左上坐标if (this.getX() >= anemyTank.getX()&& this.getX() <= anemyTank.getX() + 40&& this.getY() >= anemyTank.getY()&& this.getY() <= anemyTank.getY() + 60) {return true;}//敌人坦克左下的坐标if (this.getX() >= anemyTank.getX()&& this.getX() <= anemyTank.getX() + 40&& this.getY() + 40 >= anemyTank.getY()&& this.getY() + 40 <= anemyTank.getY() + 60) {return true;}}//如果敌人的坦克是左右if (anemyTank.getDirect() == 1 || anemyTank.getDirect() == 3){//敌人坦克左上坐标if (this.getX() >= anemyTank.getX()&& this.getX() <= anemyTank.getX() + 60&& this.getY() >= anemyTank.getY()&& this.getY() <= anemyTank.getY() + 40) {return true;}//敌人坦克左下的坐标if (this.getX() >= anemyTank.getX()&& this.getX() <= anemyTank.getX() + 60&& this.getY() + 40 >= anemyTank.getY()&& this.getY() + 40 <= anemyTank.getY() + 40) {return true;}}}}}return false;}@Overridepublic 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 && !isTouchAnemyTank() ) {moveUp();}try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}break;case 1://向右for (int i = 0; i < 30; i++) {if (getX() < 800 && !isTouchAnemyTank()){moveRight();}try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}break;case 2://向下for (int i = 0; i < 30; i++) {if (getY() < 750 && !isTouchAnemyTank()) {moveDown();}try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}break;case 3://向左for (int i = 0; i < 30; i++) {if (getX() > 0 && !isTouchAnemyTank())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.Bomb
package tankgame3;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;}
}
5.Recorder
package tankgame3;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 = "d:\\xiangmu\\abc\\a.txt";private static Vector<AnemyTank> anemyTanks = null;//定义一个node 的Vector,用于恢复信息private static Vector<Node> nodes = new Vector<>();//添加一个方法,用于读取recordFile,恢复相关的信息public static Vector<Node> getNodesAndAanemyNums(){try {br = new BufferedReader(new FileReader(recordFile));//循环读取文件,生成 nodes 集合String line = "";//255 40 0while ((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 < anemyTanks.size(); i++) {AnemyTank anemyTank = anemyTanks.get(i);if (anemyTank.isLive()){bw.write(anemyTank.getX() + " " +anemyTank.getY() + " " + anemyTank.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<AnemyTank> getAnemyTanks() {return anemyTanks;}public static void setAnemyTanks(Vector<AnemyTank> anemyTanks) {Recorder.anemyTanks = anemyTanks;}public static void setHitTankNums(int hitTankNums) {Recorder.hitTankNums = hitTankNums;}public static void addHitTankNums(){Recorder.hitTankNums++;}
}
6.Node
package tankgame3;/*** 用来记录上次游戏结束的坦克的信息,用来实现继续游戏*/
public class Node {private int x;private int y;private int direact;public Node(int x, int y, int direact) {this.x = x;this.y = y;this.direact = direact;}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 getDireact() {return direact;}public void setDireact(int direact) {this.direact = direact;}
}
7.Shot
package tankgame3;/*** 子弹类*/
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;}@Overridepublic void run() {while(true){//休眠500毫秒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;}}}
}
8.Tank
package tankgame3;/*** 坦克类*/
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-=1;}}//下移public void moveDown(){if (getY() < 800) {y+=1;}}//左移public void moveLeft(){if (getX() > 0) {x-=1;}}//右移public void moveRight(){if (getX() < 750){x+=1;}}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;}}
9.Hero
package tankgame3;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() + 30, getY() + 18, 1);break;case 2://向下shot = new Shot(getX() + 18,getY() + 30, 2);break;case 3://向左shot = new Shot(getX(), getY() + 18, 3);break;}//把新建的shot放入到集合中shots.add(shot);//启动我们的shot线程new Thread(shot).start();}}