1. Drawcircle类
package JavaSE练习代码.坦克大战;
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;
/**
* 定义出来一个窗口类
*/
class Drawcircle extends JFrame {
//先把面板定义出来
private Mypanel mp=null;
public static void main(String[] args){
Drawcircle drawcircle = new Drawcircle();
}
public Drawcircle(){
System.out.println("1.新游戏 2.继续上局游戏");
Scanner scanner=new Scanner(System.in);
String key= scanner.next();
//初始化面板
mp=new Mypanel(key);
//启动Mypanel类中的重绘线程
new Thread(mp).start();
//1.先把面板加进去
this.add(mp);
this.addKeyListener(mp);
this.setSize(1300,750);
this.setVisible(true);
//意思是:窗口退出时即关闭程序
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//在JFrame中增加相应关闭窗口时的处理
this.addWindowListener(new WindowAdapter() {
@Override//当窗口正在关闭的时候
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
/* Recorder.reCord();*/
System.out.println("监听到窗口关闭了");
System.exit(0);
}
});
}
}
2.Mypanel类
package JavaSE练习代码.坦克大战;
import javax.swing.*;
import java.awt.*;
import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
public class Mypanel extends JPanel implements KeyListener,Runnable {
/**
* 定义一个Mypanel在面板上画图 继承JPanel类,
* 画图形 就在面板上画图
*/
//定义出我方坦克
/**
* 实例化出一个对象引用就是为了后面调用类中的方法或是属性时方便调用
*/
Hero hero=null;
//用Vector存放敌方坦克,避免出现多线程问题
Vector enermyTanks=new Vector<>();
//定义一个Vector,用于存放炸弹
Vector booms=new Vector<>();
//定义一个存放Node对象的Vector,用于恢复敌人坦克的坐标和方向
Vector nodes=new Vector<>();
//定义三张炸弹图片用于爆炸效果
Image image1=null;
Image image2=null;
Image image3=null;
int entankSize=30;
public Mypanel(String key) {
hero = new Hero(500, 100);//初始化我方的坦克
//把敌方坦克的集合给到Recorder类,作记录所用
Recorder.setEnermyTank(enermyTanks);
//把敌方上一局保存的信息找到,并且存入这个类的集合中
nodes = Recorder.getNodesAndEnemyTankRec();
hero.setSpeed(20);
switch (key) {
case "1"://新游戏
for (int i = 0; i < entankSize; i++) {
Enermy enermyTank = new Enermy(100 * (i + 1), 0);
//将enemyTanks设置给enemyTank!!!!
enermyTank.setEnermies(enermyTanks);
//我们想要敌人的炮筒是朝下的,所以我们每一次取出一个对象就set一下,之后再add
enermyTank.setDirec(2);
enermyTanks.add(enermyTank);//传进去的x和y表示初始化位置
//启动敌方坦克线程,让他动起来
new Thread(enermyTank).start();
//给该敌方坦克加上子弹
shot s = new shot(enermyTank.getX() + 20, enermyTank.getY() + 60, enermyTank.getDirec());
//把每一次创建出来的子弹加入到shot类中的集合
//enermy.shots表示拿到这个Vector集合 add表示添加对象进去
enermyTank.shots.add(s);
//启动s对象
new Thread(s).start();
}
break;
case "2"://继续上局游戏
//初始化敌人坦克
for (int i = 0; i < nodes.size(); i++) {
NODe node = nodes.get(i);
//创建一个敌人的坦克
Enermy enermyTank = new Enermy(node.getX(), node.getY());
//将enemyTanks设置给enemyTank!!!!
enermyTank.setEnermies(enermyTanks);
//设置方向
enermyTank.setDirec(node.getDirect());
//启动敌人坦克线程,让他动起来
new Thread(enermyTank).start();
//给该enermyTank加上一颗子弹
shot s = new shot(enermyTank.getX() + 20, enermyTank.getY() + 60, enermyTank.getDirec());
//加入enemyTank的Vector成员
enermyTank.shots.add(s);
//启动s对象
new Thread(s).start();
//加入
enermyTanks.add(enermyTank);
}
break;
}
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"));
}
//编写方法,显示我方击毁敌方坦克的信息
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,30,g,0,0);//画一个敌方的坦克
g.setColor(Color.BLACK);
//Recorder.getAllEnemyTankNum()+"":把整形转换为String类型
/*g.drawString(Recorder.getAllEnemyTankNum()+"",1080,100);*/
}
@Override
public void paint(Graphics g) {
super.paint(g);
//如果不自己填充颜色,我们默认对画板填充的是黑色
g.fillRect(0,0,1000,750);
/**
* 坦克的坐标时刻在改变,所以我们实例化出的对象引用调用属性就派上用场了
*/
if(hero!=null&&hero.isLife) {//当hero坦克存在时,我们才画他
drawTank(hero.getX(), hero.getY(), g, hero.getDirec(), 1);
}
/**
* 画出坦克射出的子弹
* hero.s表示是子弹这个对象
*/
if(hero.s!=null&&hero.s.isLive==true){
System.out.println("子弹被绘制");
g.draw3DRect(hero.s.x,hero.s.y,5,5,false);
}
//将hero子弹集合shots遍历取出
for (int i = 0; i < hero.shots.size(); i++) {
shot s=hero.shots.get(i);
if(s!=null&&s.isLive==true){
g.draw3DRect(s.x,s.y,20,20,false);
} else {
//说明该子弹对象已经无效,所以要从子弹集合中拿出
hero.shots.remove(s);
}
}
//如果booms集合有对象,就画出
for (int i=0;i6) {
g.drawImage(image1,boom.x,boom.y,60,60,this);
} else if(boom.life>3) {
g.drawImage(image2,boom.x,boom.y,60,60,this);
} else {
g.drawImage(image3,boom.x,boom.y,60,60,this);
}
//这个炸弹的生命值减少
boom.lifeDown();
//如果boom对象的life变为0,那么就从炸弹集合中删除
if(boom.life==0) {
booms.remove(boom);
}
}
/**
* 画出敌人的坦克
* 注意一点就是:这个循环次数必须要集合的size来控制,不可以用一个确定的值,
* 因为我们后面会进行打坦克,如果写一个固定的值,那么坦克的数量永远不会改变
*/
for (int i = 0; i < enermyTanks.size(); i++) {
Enermy enermy=enermyTanks.get(i);//取出这个敌方坦克
if(enermy.isLive) {
drawTank(enermy.getX(), enermy.getY(), g, enermy.getDirec(), 0);
//画出enermy所有的子弹
for (int j = 0; j < enermy.shots.size(); j++) {
//取出每一次遍历得到的子弹
shot sh = enermy.shots.get(j);
//绘制
if (sh.isLive) {
g.draw3DRect(sh.x, sh.y, 5, 5, false);
} else {
//从Vector集合中移除已经死掉的子弹
enermy.shots.remove(sh);
}
}
}
}
}
/**
* 如果我方可以发射多颗子弹,那么在判断我方子弹是否击中敌方时就需要把子弹集合中的所有子弹取出来
* 然后和敌人的所有的坦克进行判断
*/
public void hitEnemyTank() {
//遍历我们的子弹
for (int i = 0; i < hero.shots.size(); i++) {
shot s=hero.shots.get(i);
if(s!=null&&s.isLive) {
//说明没有击中敌方
for (int j = 0; j < enermyTanks.size(); j++) {
//遍历敌方坦克
Enermy enermy=enermyTanks.get(i);
hitTank(s,enermy);
}
}
}
}
/**
* 判断敌方是否击中我方坦克
*/
public void hitHero(){
for(int i=0;i enermy.getX() && s.x < enermy.getX() + 40
&& s.y > enermy.getY() && s.y < enermy.getY() + 60) {
s.isLive = false;//敌方子弹死掉
enermy.isLive = false;//敌方坦克死掉
//当敌方坦克死掉之后,我们要把这个坦克删除
enermyTanks.remove(enermy);
if(enermy instanceof Enermy) {
//当击毁的是敌方坦克,那么Recorder记录的击毁数量就要+1
/* Recorder.addAllEnemyTankNum();*/
}
//创建Bomb对象,加入到bombs集合
Boom boom=new Boom(enermy.getX(),enermy.getY());
booms.add(boom);
}
break;
case 1:
case 3://同理
if (s.x > enermy.getX() && s.x < enermy.getX() + 60
&& s.y > enermy.getY() && s.y < enermy.getY() + 40) {
s.isLive = false;//敌方子弹死掉
enermy.isLive = false;//敌方坦克死掉
enermyTanks.remove(enermy);
if(enermy instanceof Enermy) {
//当击毁的是敌方坦克,那么Recorder记录的击毁数量就要+1
/* Recorder.addAllEnemyTankNum();*/
}
//创建Bomb对象,加入bombs集合
Boom boom=new Boom(enermy.getX(),enermy.getY());
booms.add(boom);
}
break;
}
}
/**
* @param x 表示最左上角点的x坐标
* @param y 表示最左上角点的y坐标
* @param g 表示Graphics类可以带有的画笔
* @param direct 表示坦克的方向(上下左右)
* @param type 表示坦克的类型
*/
public void drawTank(int x,int y,Graphics g,int direct,int type){
//根据不同类型的坦克,设置不同的颜色
switch (type){
case 0://0表示我们的坦克
g.setColor(java.awt.Color.cyan);
break;
case 1://1表示敌方的坦克
g.setColor(java.awt.Color.yellow);
break;
}
/**
* direct 表示坦克移动的方向 :
* 0表示向上 1表示向右 2表示向下 3表示向左
*/
switch (direct) {
case 0://表示向上
//1.画出左边的轮子
g.fill3DRect(x,y,10,60,false);
//2.画出右边的轮子
g.fill3DRect(x+30,y,10,60,false);
//3.画出坦克的盖子
g.fill3DRect(x+10,y+10,20,40,false);
//4.画出圆形盖子
g.fillOval(x+10,y+10,20,20);
//5.画出炮筒
g.drawLine(x+20,y+30,x+20,y);
break;
case 1://表示向右
//1.画出上边的轮子
g.fill3DRect(x,y,60,10,false);
//2.画出下边的轮子
g.fill3DRect(x,y+30,60,10,false);
//3.画出坦克的盖子
g.fill3DRect(x+10,y+10,40,20,false);
//4.画出圆形盖子
g.fillOval(x+20,y+10,20,20);
//5.画出炮筒
g.drawLine(x+30,y+20,x+60,y+20);
break;
case 2://表示向下
//1.画出左边的轮子
g.fill3DRect(x,y,10,60,false);
//2.画出右边的轮子
g.fill3DRect(x+30,y,10,60,false);
//3.画出坦克的盖子
g.fill3DRect(x+10,y+10,20,40,false);
//4.画出圆形盖子
g.fillOval(x+10,y+20,20,20);
//5.画出炮筒
g.drawLine(x+20,y+30,x+20,y+60);
break;
case 3://表示向左
//1.画出上边的轮子
g.fill3DRect(x,y,60,10,false);
//2.画出下边的轮子
g.fill3DRect(x,y+30,60,10,false);
//3.画出坦克的盖子
g.fill3DRect(x+10,y+10,40,20,false);
//4.画出圆形盖子
g.fillOval(x+20,y+10,20,20);
//5.画出炮筒
g.drawLine(x+30,y+20,x,y+20);
default:
System.out.println("暂时没有处理");
break;
}
}
@Override
public void keyTyped(KeyEvent e) {
}
/**
* direct 表示坦克移动的方向 :
* 0表示向上 1表示向右 2表示向下 3表示向左
*/
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_W) {
//按下W键 向上
hero.setDirec(0);
if(hero.getY()>=0) {//保证我方坦克不越界
hero.moveUP();
}
} else if(e.getKeyCode()==KeyEvent.VK_D) {
//按下D键 向右
hero.setDirec(1);
if(hero.getX()+60<=1000) {//保证我方坦克不越界
hero.moveRight();
}
} else if(e.getKeyCode()==KeyEvent.VK_S) {
//按下S键 向下
hero.setDirec(2);
if(hero.getY()+60<=750) {//保证我方坦克不越界
hero.moveDown();
}
} else if(e.getKeyCode()==KeyEvent.VK_A) {
//按下A键 向左
hero.setDirec(3);
if(hero.getX()>=0) {//保证我方坦克不越界
hero.moveLeft();
}
}
/**
* 发射子弹,按下J键,应该定义在Mypanel类
*/
if(e.getKeyCode()==KeyEvent.VK_J){
System.out.println("用户按下J键,开始射击");
/*if(hero.s==null||!hero.s.isLive) {//子弹销毁*/
hero.shoted();
/* }*/
}
//让面板重绘
this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
/**
* 我们对于子弹的重绘应该不断地刷新,所以要搞一个线程出来
* 每隔100毫秒进行重绘一次
*/
@Override
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
//判断是否我们的子弹击中了敌人坦克
hitEnemyTank();
//判断敌人子弹是否击中了我们
hitHero();
this.repaint();
}
}
}
3.shot类
package JavaSE练习代码.坦克大战;
/**
* 发射子弹这个过程应该是一个线程去执行
*/
public class shot implements Runnable{
int x;//子弹x坐标
int y;//子弹y坐标
int speed=2;//子弹速度
int direc;//子弹的射击的方向
boolean isLive=true;
public shot(int x,int y,int direc){
this.direc=direc;
this.x=x;
this.y=y;
}
@Override
public void run() {
while (true) {
try {
/**
* 让子弹休息一下【不然太快了看不见】
*/
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
switch (direc) {
case 0://向上
y-=speed;
break;//这里的break表示的意思是:退出switch语句
case 1://向右 顺时针旋转
x+=speed;
break;
case 2://向下
y+=speed;
break;
case 3://向左
x-=speed;
break;
}
//这里输出子弹的坐标
System.out.println(x+"--------"+y);
//1.碰到边界之后,子弹就死了
//2.或者击中坦克的时候,子弹也也死了
if(!(x>=0&&x<=1000&&y>=0&&y<=750)&&isLive) {
isLive=false;
break;
}
}
}
}
4.Enermy类【敌方坦克类】
package JavaSE练习代码.坦克大战;
import java.util.Vector;
/**
* 敌方坦克
*/
@SuppressWarnings({"all"})
class Enermy extends Tank implements Runnable{
/**
*在敌人的坦克建立一个Vector集合【因为多线程的原因,为了保证安全所以用vector】保存多个子弹【shot】类型对象。
*/
Vector shots=new Vector<>();
Vector enemyTanks=new Vector<>();
boolean isLive=true;
//这个方法可以把Mypanel中的enemyTanks设置给Enermy类的成员enemyTanks,便于进行比较
public void setEnermies(Vector enemyTanks) {
this.enemyTanks=enemyTanks;
}
public Enermy(int x, int y) {
super(x, y);
}
/**
* 编写一个方法,让敌人的坦克和敌人自己的坦克不发生重叠现象
*/
public boolean isTouchEnermyTank() {
switch (this.getDirec()) {
case 0: //敌方的一个坦克[this]向上时
//把敌方的一个坦克[this]和除了这个敌方坦克之外的所有敌方坦克进行比较
for(int i=0;i< enemyTanks.size();i++) {
Enermy enermyTank=enemyTanks.get(i);
if(this!=enermyTank) {//不可以是自己[this]
//如果其他的敌人坦克是上/下时
//x范围 [enermyTank.getX(),enermyTank.getX()+40]
// y范围[enermyTank.getY(),enermyTank.getY()+60]
if(enermyTank.getDirec()==0||enermyTank.getDirec()==2) {
//敌方的一个坦克[this]左上角坐标 [this.getX(),this.getY()]
if(this.getX()>=enermyTank.getX()&&this.getX()<=enermyTank.getX()+40
&&this.getY()>=enermyTank.getY()&&this.getY()<=enermyTank.getY()+60) {
return true;
}
//敌方的一个坦克[this]右上角坐标 [this.getX()+40,this.getY()]
if(this.getX()+40>=enermyTank.getX()&&this.getX()+40<=enermyTank.getX()+40
&&this.getY()>=enermyTank.getY()&&this.getY()<=enermyTank.getY()+60) {
return true;
}
}
//如果其他的敌人坦克是左/右时
//x范围 [enermyTank.getX(),enermyTank.getX()+60]
// y范围[enermyTank.getY(),enermyTank.getY()+40]
if(enermyTank.getDirec()==1||enermyTank.getDirec()==3) {
//敌方的一个坦克[this]左上角坐标 [this.getX(),this.getY()]
if(this.getX()>=enermyTank.getX()&&this.getX()<=enermyTank.getX()+60
&&this.getY()>=enermyTank.getY()&&this.getY()<=enermyTank.getY()+40) {
return true;
}
//敌方的一个坦克[this]右上角坐标 [this.getX()+40,this.getY()]
if(this.getX()+40>=enermyTank.getX()&&this.getX()+40<=enermyTank.getX()+60
&&this.getY()>=enermyTank.getY()&&this.getY()<=enermyTank.getY()+40) {
return true;
}
}
}
}
break;
case 1://敌方的一个坦克[this]向右时
//把敌方的一个坦克[this]和除了这个敌方坦克之外的所有敌方坦克进行比较
for(int i=0;i< enemyTanks.size();i++) {
Enermy enermyTank = enemyTanks.get(i);
if (this != enermyTank) {//不可以是自己[this]
//如果其他的敌人坦克是上/下时
//x范围 [enermyTank.getX(),enermyTank.getX()+40]
// y范围[enermyTank.getY(),enermyTank.getY()+60]
if (enermyTank.getDirec() == 0 || enermyTank.getDirec() == 2) {
//敌方的一个坦克[this]右上角坐标 [this.getX()+60,this.getY()]
if (this.getX()+60 >= enermyTank.getX() && this.getX()+60 <= enermyTank.getX() + 40
&& this.getY() >= enermyTank.getY() && this.getY() <= enermyTank.getY() + 60) {
return true;
}
//敌方的一个坦克[this]右下角坐标 [this.getX()+60,this.getY()+40]
if (this.getX() + 60 >= enermyTank.getX() && this.getX() + 60 <= enermyTank.getX() + 40
&& this.getY()+40 >= enermyTank.getY() && this.getY()+40 <= enermyTank.getY() + 60) {
return true;
}
}
//如果其他的敌人坦克是左/右时
//x范围 [enermyTank.getX(),enermyTank.getX()+60]
// y范围[enermyTank.getY(),enermyTank.getY()+40]
if (enermyTank.getDirec() == 1 || enermyTank.getDirec() == 3) {
//敌方的一个坦克[this]右上角坐标 [this.getX()+60,this.getY()]
if (this.getX()+60 >= enermyTank.getX() && this.getX()+60 <= enermyTank.getX() + 60
&& this.getY() >= enermyTank.getY() && this.getY() <= enermyTank.getY() + 40) {
return true;
}
//敌方的一个坦克[this]右下角坐标 [this.getX()+60,this.getY()+40]
if (this.getX() + 60 >= enermyTank.getX() && this.getX() + 60 <= enermyTank.getX() + 60
&& this.getY()+40 >= enermyTank.getY() && this.getY()+40 <= enermyTank.getY() + 40) {
return true;
}
}
}
}
break;
case 2://敌方的一个坦克[this]向下时
//把敌方的一个坦克[this]和除了这个敌方坦克之外的所有敌方坦克进行比较
for(int i=0;i< enemyTanks.size();i++) {
Enermy enermyTank = enemyTanks.get(i);
if (this != enermyTank) {//不可以是自己[this]
//如果其他的敌人坦克是上/下时
//x范围 [enermyTank.getX(),enermyTank.getX()+40]
// y范围[enermyTank.getY(),enermyTank.getY()+60]
if (enermyTank.getDirec() == 0 || enermyTank.getDirec() == 2) {
//敌方的一个坦克[this]左下角坐标 [this.getX(),this.getY()+60]
if (this.getX() >= enermyTank.getX() && this.getX() <= enermyTank.getX() + 40
&& this.getY()+60 >= enermyTank.getY() && this.getY()+60 <= enermyTank.getY() + 60) {
return true;
}
//敌方的一个坦克[this]右下角坐标 [this.getX()+40,this.getY()+60]
if (this.getX() + 40 >= enermyTank.getX() && this.getX() + 40 <= enermyTank.getX() + 40
&& this.getY()+60 >= enermyTank.getY() && this.getY()+60 <= enermyTank.getY() + 60) {
return true;
}
}
//如果其他的敌人坦克是左/右时
//x范围 [enermyTank.getX(),enermyTank.getX()+60]
// y范围[enermyTank.getY(),enermyTank.getY()+40]
if (enermyTank.getDirec() == 1 || enermyTank.getDirec() == 3) {
//敌方的一个坦克[this]左下角坐标 [this.getX(),this.getY()+60]
if (this.getX() >= enermyTank.getX() && this.getX() <= enermyTank.getX() + 60
&& this.getY()+60 >= enermyTank.getY() && this.getY()+60 <= enermyTank.getY() + 40) {
return true;
}
//敌方的一个坦克[this]右下角坐标 [this.getX()+40,this.getY()+60]
if (this.getX() + 40 >= enermyTank.getX() && this.getX() + 40 <= enermyTank.getX() + 60
&& this.getY()+60 >= enermyTank.getY() && this.getY()+60 <= enermyTank.getY() + 40) {
return true;
}
}
}
}
break;
case 3://敌方的一个坦克[this]向左时
//把敌方的一个坦克[this]和除了这个敌方坦克之外的所有敌方坦克进行比较
for(int i=0;i< enemyTanks.size();i++) {
Enermy enermyTank = enemyTanks.get(i);
if (this != enermyTank) {//不可以是自己[this]
//如果其他的敌人坦克是上/下时
//x范围 [enermyTank.getX(),enermyTank.getX()+40]
// y范围[enermyTank.getY(),enermyTank.getY()+60]
if (enermyTank.getDirec() == 0 || enermyTank.getDirec() == 2) {
//敌方的一个坦克[this]左上角坐标 [this.getX(),this.getY()]
if (this.getX() >= enermyTank.getX() && this.getX() <= enermyTank.getX()
&& this.getY() >= enermyTank.getY() && this.getY() <= enermyTank.getY() + 60) {
return true;
}
//敌方的一个坦克[this]左下角坐标 [this.getX(),this.getY()+40]
if (this.getX() >= enermyTank.getX() && this.getX()<= enermyTank.getX() + 40
&& this.getY()+40 >= enermyTank.getY() && this.getY()+40 <= enermyTank.getY() + 60) {
return true;
}
}
//如果其他的敌人坦克是左/右时
//x范围 [enermyTank.getX(),enermyTank.getX()+60]
// y范围[enermyTank.getY(),enermyTank.getY()+40]
if (enermyTank.getDirec() == 1 || enermyTank.getDirec() == 3) {
//敌方的一个坦克[this]左上角坐标 [this.getX(),this.getY()]
if (this.getX() >= enermyTank.getX() && this.getX() <= enermyTank.getX() + 60
&& this.getY() >= enermyTank.getY() && this.getY() <= enermyTank.getY() + 40) {
return true;
}
//敌方的一个坦克[this]左下角坐标 [this.getX(),this.getY()+40]
if (this.getX()>= enermyTank.getX() && this.getX()<= enermyTank.getX() + 60
&& this.getY()+40 >= enermyTank.getY() && this.getY()+40 <= enermyTank.getY() + 40) {
return true;
}
}
}
}
break;
}
return false;
}
@Override
public void run() {
while (true) {
//根据坦克的方向来继续移动
if (isLive && shots.size() < 10) {
shot s = null;
//判断坦克的方向,创建对应的子弹
switch (getDirec()) {
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(), getY() + 20, 3);
break;
}
shots.add(s);
new Thread(s).start();
}
switch (getDirec()) {
case 0://up
for (int i = 0; i < 30; i++) {
if (getY() >= 0) {//保证敌方坦克不越界的情况下才向上移动
moveUP();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 1://right
for (int i = 0; i < 30; i++) {
if (getX() + 60 <= 1000) {//保证敌方坦克不越界
moveRight();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 2://down
for (int i = 0; i < 30; i++) {
if (getY() + 60 <= 750) {//保证敌方坦克不越界
moveDown();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case 3://left
for (int i = 0; i < 30; i++) {
if (getX() >= 0) {//保证敌方坦克不越界
moveLeft();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
}
//然后随机改变坦克的方向 0-3
setDirec((int) (Math.random() * 4));
//写并发程序一定要考虑清楚线程什么时候结束
//当敌方坦克被射击到时,退出线程
if (!isLive) {
break;//退出线程
}
}
}
}
5.Hero类【我方坦克】
package JavaSE练习代码.坦克大战;
import java.util.Vector;
/**
* 继承父类Tank,这是表示我方坦克
*/
class Hero extends Tank{
shot s=null;
Vector shots=new Vector<>();
boolean isLife=true;
public Hero(int x, int y) {
super(x, y);
}
public void shoted(){
//根据hero我方坦克的位置坐标(即是最最左上角的坐标)来创建子弹对象【参数即是给定子弹的初始位置】
switch (getDirec()) {
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(),getY()+20,3);
break;
}
//把新创建的s放到子弹集合中
shots.add(s);
/**
* 启动线程
*/
Thread thread = new Thread(s);
thread.start();
}
}
6.Tank类
package JavaSE练习代码.坦克大战;
/**
* 定义一个父类Tank
*/
class Tank{
private int x;//横坐标
private int y;//纵坐标
private int direc;//方向
//可以使得在实例化出一个对象的时候就可以设置一个速度
private int speed;//速度
boolean isLive=true;
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
/**
* 为了能够让坦克能够动起来,
* 我们封装四个方法,表示向左向右向上向下移动
* 设置为public类型便于外界调用
*/
public void moveUP(){
y-=speed;
}
public void moveDown(){
y+=speed;
}
public void moveLeft(){
x-=speed;
}
public void moveRight(){
x+=speed;
}
public int getDirec() {
return direc;
}
public void setDirec(int direc) {
this.direc = direc;
}
public Tank(int x, int y) {
this.x = x;
this.y = y;
}
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;
}
}
7.Boom类
package JavaSE练习代码.坦克大战;
/**
* 定义一个炸弹类
*/
class Boom{
int x;
int y;//炸弹的坐标
int life=9;//炸弹的生命周期
boolean isLfe=true;//炸弹是否存活
public Boom(int x, int y) {
this.x = x;
this.y = y;
}
//减少生命周期
public void lifeDown(){
if(life>0){
life--;
} else {
isLfe=false;
}
}
}
8.NODe类
package JavaSE练习代码.坦克大战;
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;
}
}
9.Recorder类
package JavaSE练习代码.坦克大战;
import java.io.*;
import java.util.Vector;
@SuppressWarnings({"all"})
public class Recorder {
//定义变量,记录我方击毁敌人坦克数
private static int allEnemyTankNum=0;
//定义IO对象,准备写数据到文件中
private static BufferedWriter bw=null;
private static BufferedReader br=null;
//把Enermy类的敌方坦克的集合通过set方法给到Recorder这里
private static Vector enermyTank=new Vector<>();
private static String recordFile="d:\\leomessi.txt";
private static Vector nodes=new Vector<>();
//增加一个方法,用于读取recordFile,恢复相关信息
//该方法,当我们需要继续上局游戏时,调用即可
public static Vector getNodesAndEnemyTankRec() {
try {
br=new BufferedReader(new FileReader(recordFile));
//读取击毁的坦克数
allEnemyTankNum=Integer.parseInt(br.readLine());
String line="";
while ((line= br.readLine())!=null) {
String[] xyd=line.split(" ");//以空格为分割符,分割之后把其内容存储到这个数组即可
NODe node = new NODe(Integer.parseInt(xyd[0]), Integer.parseInt(xyd[1]), Integer.parseInt(xyd[2]));
nodes.add(node);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(br!=null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return nodes;
}
public static void setEnermyTank(Vector enermyTank) {
Recorder.enermyTank = enermyTank;
}
public static void reCord() {
try {
bw = new BufferedWriter(new FileWriter(recordFile));
bw.write(allEnemyTankNum+"\t\n");
//把退出时,敌方坦克的坐标信息写入到文件中
for (int i = 0; i < enermyTank.size(); i++) {
Enermy enermy=enermyTank.get(i);
if(enermy.isLive) {
String line=enermy.getX()+" "+enermy.getY()+" "+enermy.getDirec();
bw.write(line);
bw.newLine();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bw!=null) {
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static int getAllEnemyTankNum() {
return allEnemyTankNum;
}
public static void setAllEnemyTankNum(int allEnemyTankNum) {
Recorder.allEnemyTankNum = allEnemyTankNum;
}
//当我方坦克击毁一个敌方坦克时,就应当allEnemyTankNum++
public static void addAllEnemyTankNum() {
Recorder.allEnemyTankNum++;
}
}