b站韩顺平老师的坦克大战

一.主要的几个类

  1. Mypanel  
  2. WwyTankGame01
  3. AnemyTank //写代码时候把单词拼错了哈哈不好意思
  4. Bomb
  5. Recorder
  6. Node
  7. Shot
  8. Tank
  9. 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();}}

学习时间不长里面很多的内容实现的不是很好,希望勿喷 

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

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

相关文章

Linux的入门全解

基于Ubuntu的Linux入门指南 写在前面浅谈LinuxWindows与LinuxLinux起源与发展初学者的学习方式 虚拟机与Ubuntu的安装虚拟机的安装与配置Linux系统的安装与配置 软件的安装与使用Windows与Linux的文件传输工具&#xff1a;VMToolsUbuntu下的软件商城&#xff1a;snap文本编辑器…

校园社交平台(SpringBoot+React前后端分离项目)

项目已开源&#xff0c;欢迎star&#xff01;&#xff01;&#xff01; 项目gitee地址&#xff1a;校园社交平台: ⭐基于ReactSpring Boot的前后端分离项目。校园社交平台&#xff0c;旨在为大学校园提供一个社交平台&#xff0c;通过发布动态为校园学生提供分享校园生活&…

chatgpt赋能python:Python建立文本文件:一步步学习

Python建立文本文件&#xff1a;一步步学习 什么是文本文件&#xff1f; 在计算机领域&#xff0c;文本文件&#xff08;Text file&#xff09;是一种使用纯文本格式编码的文件&#xff0c;其中存储的是基本的ASCII字符或Unicode字符编码。文本文件是计算机中最常见的文件类型…

零基础如何开始学习 Python?看完这篇小白变大牛!

Python是一门面向对象的编程语言&#xff0c;该语言语法简单清晰、具有丰富和强大的库&#xff0c;简单易读、容易维护&#xff0c;受到了大家的喜欢和追捧&#xff0c;同时用途也非常广泛&#xff0c;无论是0基础还是初学者&#xff0c;学Python都是非常不错的选择。那么Pytho…

密码学和加密数字货币的简介

所有货币都需要一些方法来控制供应&#xff0c;并强制执行各种安全属性以防止作弊。在法定货币方面&#xff0c;像中央银行这样的组织控制货币供应量&#xff0c;并对实体货币增加防伪功能。这些安全功能提高了对攻击者的防范能力&#xff0c;但是他们不可能不赚钱地进行伪造。…

数字货币钱包 - 助记词 及 HD 钱包密钥原理

转载&#xff1a;https://zhuanlan.zhihu.com/p/34184347 分类 区块链相关的话题持续发酵之时&#xff0c;应该不少人知道加密货币钱包&#xff0c;钱包是普通用户与加密货币系统交互的入口&#xff0c;各种形态的钱百花齐放&#xff0c;手机钱包、桌面钱包、硬件钱包、网页钱…

中国对数字货币的态度及政策

一、关于数字货币官方最早发表的一份通告是2013年&#xff1a; 北京时间2013年12月5日央行网站消息&#xff0c;为保护社会公众的财产权益&#xff0c;保障人民币的法定货币地位&#xff0c;防范洗钱风险&#xff0c;维护金融稳定&#xff0c;中国人民银行、工业和信息化部、中…

UiBot 浏览器输入

拖拉组件”启动新的浏览器”&#xff0c;该组件有多种参数输入方式&#xff0c;如图&#xff1a; 执行流程&#xff0c;结果如图&#xff0c;IE浏览器已经打开rpazj网站 拖拉组件”启动新的浏览器”&#xff0c;该组件有多种参数输入方式&#xff0c;如图&#xff1a;执行流程&…

完美解决浏览器主页被hao123劫持,打开浏览器时自动进入hao123主页怎么办

完美解决浏览器主页被hao123劫持 首先使用排除法&#xff1a; 第一步&#xff0c;先查看浏览器快捷方式&#xff0c;右键—>属性&#xff0c;看看文件位置最后面有没有被篡改成别的路径&#xff0c;如果有&#xff0c;删掉后面的路径就行 如果位置路径是正常的&#xff0c;那…

浏览器主页被hao123劫持的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

破除谷歌浏览器Google Chrome启动时打开hao123,2345等流氓网页

相信都遇到过这样的情况&#xff1a;自己的谷歌浏览器明明已经设置了启动时打开自己设定的特定网页&#xff0c;但是启动时还是打开了hao123&#xff0c;2345等流氓网页&#xff0c;有一个很简单的小技巧可以解决这个烦人的问题&#xff01; 先设置谷歌浏览器启动打开某个特定网…

成功解决“谷歌浏览器打开是毒霸网址大全”问题,亲测有效(同样适用被hao123,或者2345浏览器篡改)

最开始一定要把电脑安装的360和电脑管家之类的退出。 第一步&#xff1a;发现问题的存在 在谷歌网址中输入&#xff1a;chrome://version&#xff0c;再按enter键 如果返回如图&#xff1a; 那说明你的谷歌被hao123浏览器篡改了。&#xff08;如果你返回的蓝色部分是www.dub…

十分好用的跨浏览器测试工具,建议收藏!!!

跨浏览器测试是确保web应用程序的功能在不同浏览器、浏览器版本和操作系统直接保持功能和质量一致的过程&#xff0c;可以为用户提供更好的用户体验&#xff0c;帮助企业通过更易访问的网站获得满意客户&#xff0c;可以使web应用程序在不同平台上兼容。在跨浏览器测试过程中&a…

10个免费的顶级跨浏览器测试工具

1.Browsera Browsera 可以测试和报告在您的网站上的跨浏览器布局的差异和脚本错误。 Browsera不同于其他跨浏览器测试服务。其他服务&#xff0c;如Litmus&#xff0c;Browsershots&#xff0c;BrowserLab&#xff0c;以及 SuperPreview&#xff0c;它们仅仅截取每一个特定的页…

超级浏览器:创建多套UA实现防关联

前面的文章&#xff0c;我们为大家详细介绍了Cookies的功能以及它在防关联过程中的作用需要复习的小伙看这里&#xff1a; 超级浏览器的Cookies实现跨境电商防关联 咱们在前面说过&#xff0c;Cookies相当于用户的网络身份证&#xff0c;里面记录了用户的身份、上网喜好和登录…

10款最佳跨浏览器测试工具,建议收藏

1、前言 跨浏览器测试工具对于检查您的网络应用程序在桌面端、移动端、平板电脑和其他设备类别中是否正常工作至关重要。这些工具检查 UI 不一致、验证代码、跨 Chrome、Firefox、IE、Edge、Safari 和其他浏览器的响应能力。它们有助于跨设备和平台提供一致的用户体验。 什么…

打开谷歌浏览器弹出hao123(俗称被绑架)(SB-hao123)

1.打开google浏览器在地址栏输入&#xff1a;chrome://version 2. 右键谷歌浏览器的快捷方式&#xff0c;打开谷歌浏览器的属性窗口&#xff0c;找到目标里面hao123的网址&#xff0c;直接改为你想启动时打开的网址&#xff08;不加也行&#xff09;&#xff0c;我的就没加&…

Chrome/Firefox浏览器主页被篡改为hao123的终极原因

小弟今天早上起来发现自己电脑的浏览器主页被篡改为hao123了&#xff01;想来我最近也没有下过什么不明软件啊&#xff01;于是开始了一系列搜索&#xff0c;各种查杀、扫描、查看注册表、查看快捷方式属性等等&#xff0c;还按照热门知乎帖子&#xff08;https://www.zhihu.co…

推荐17款最好用的跨浏览器测试工具

市面上有很多不同的浏览器&#xff0c;每种浏览器都有数百万用户。因此&#xff0c;在构建一个网站或 Web 应用程序时&#xff0c;就需要测试它与不同浏览器的兼容性。最好、最方便的方法是使用跨浏览器检查工具。 如果你正在寻找解决方案&#xff0c;可以看看下面这些可靠且全…

跨境群店安全运营神器—超级浏览器

有点跨境电商经验的跨境人都知道&#xff0c;物理隔离是比较安全稳妥的防关联办法。但是多台电脑多条网络的办公方式&#xff0c;不仅设备成本高&#xff0c;人员的费用也高得吓人。 后来大家开始使用VPS来防关联。VPS是一种虚拟专用服务器&#xff0c;它是一种将一台服务器分割…