🌲实现记录
要实现记录,这里就用用到IO流相关的知识了
🌲定义记录类
package com.Cx_330.TankGame4;
import java.io.*;
import java.util.Vector;
public class Recorder {
private static int totalTankNums; //记录击中敌人坦克的数量
private static BufferedWriter bw;//字符输出流
private static BufferedReader br;//字符输入流
private static String recordFile="src\\myRecord.txt";//定义要存放的地址
private static Vector<EnemyTank> enemyTanks=new Vector<>();//结束时记录剩余坦克的位置/方向
//如果想继续上局的话,就需先设计一个Vector容器去接收Node对象
private static Vector<Node> nodes=new Vector<>();
public static String getRecordFile() {
return recordFile;
}
//若要继续游戏,从E盘取出上一次结束时坦克的位置方向信息
public static Vector<Node> getTankInfo(){
try {
br=new BufferedReader(new FileReader(recordFile));
String begin=br.readLine();
String[] split = begin.split(":");
totalTankNums=Integer.parseInt(split[1]);
String line="";
while ((line=br.readLine())!=null){
String[] s = line.split(" ");
int x=Integer.parseInt(s[0]);
int y=Integer.parseInt(s[1]);
int direct=Integer.parseInt(s[2]);
Node node = new Node(x, y, direct);
nodes.add(node);
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
try {
br.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return nodes;
}
//当退出游戏时,将剩余坦克坐标存放E盘根目录下
public static void keepRecord(){
try {
bw=new BufferedWriter(new FileWriter(recordFile));
bw.write("您击毁敌人坦克数量为:"+totalTankNums);
bw.newLine();
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
if(enemyTank.leap){
String s=enemyTank.getX()+" "+enemyTank.getY()+" "+enemyTank.getDirect();
bw.write(s+"\r\n");
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
if(bw!=null){
try {
bw.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
//每当击中一个敌坦克,totalTankNums加1
public static void countTankNums(){
totalTankNums++;
}
public static int getTotalTankNums() {
return totalTankNums;
}
public void setTotalTankNums(int totalTankNums) {
totalTankNums = totalTankNums;
}
public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
Recorder.enemyTanks = enemyTanks;
}
}
🌲定义NODE类
package com.Cx_330.TankGame4;
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;
}
}
🌲画板优化最终方案
package com.Cx_330.TankGame4;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.Vector;
public class Mypanel extends JPanel implements KeyListener,Runnable {
//定义一个接收输入流的Vector容器
Vector<Node>nodes=new Vector<>();
//定义我的坦克
Hero hero=null;
//定义敌人坦克
Vector<EnemyTank> enemyTanks=new Vector<>();
//初始化敌人的坦克个数
int enemySize=5;
//定义炸弹集合 当子弹击中坦克存放炸弹
Vector<Boom> booms=new Vector<>();
//定义爆炸的图片
Image image1=null;
Image image2=null;
Image image3=null;
public Mypanel(String choice){
File file = new File(Recorder.getRecordFile());
if(file.exists()){
//接收Vector<Node>容器
nodes = Recorder.getTankInfo();
}else {
System.out.println("该文件不存在,游戏将重新开始");
choice="1";
}
//在最开始的时候就把EnemyTanks集合给Recorder类去记录
Recorder.setEnemyTanks(enemyTanks);
hero = new Hero(800,300);//初始化自己的坦克
hero.setSpeed(10);//设置速度
//做判断 1重开 还是0继续
switch (choice){
case "1":
//初始化敌人坦克 并放入子弹 并开启线程
for (int i = 0; i < enemySize; i++) {
//定义一个坦克
EnemyTank enemyTank=new EnemyTank(100*(i+1),0);
//设置坦克方向
enemyTank.setDirect(2);
//设置敌人坦克速度
enemyTank.setSpeed(1);
//定义一个子弹
Shot shot = new Shot(enemyTank.getX()+20,enemyTank.getY()+60,2);
//开启坦克线程
new Thread(enemyTank).start();
//添加子弹到敌人坦克集合中
enemyTank.shots.add(shot);
//开启子弹线程
new Thread(shot).start();
//添加坦克到敌人坦克集合中
enemyTanks.add(enemyTank);
}
break;
case "0":
//初始化敌人坦克 并放入子弹 并开启线程
for (int i = 0; i < nodes.size(); i++) {
Node node = nodes.get(i);
//定义一个坦克
EnemyTank enemyTank=new EnemyTank(node.getX(),node.getY());
//设置坦克方向
enemyTank.setDirect(node.getDirect());
//设置敌人坦克速度
enemyTank.setSpeed(1);
//定义一个子弹
Shot shot = new Shot(enemyTank.getX()+20,enemyTank.getY()+60,2);
//开启坦克线程
new Thread(enemyTank).start();
//添加子弹到敌人坦克集合中
enemyTank.shots.add(shot);
//开启子弹线程
new Thread(shot).start();
//添加坦克到敌人坦克集合中
enemyTanks.add(enemyTank);
}
break;
default:
System.out.println("选择有误");
System.exit(0);
break;
}
//初始化图片
image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/b1.jpg"));
image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/b3.jpg"));
image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/b3.jpg"));
//指定播放音乐的路径
new AePlayWave("src\\x.wav").start();
}
//绘制简单的界面
public void showInfo(Graphics g){
g.setColor(Color.red);
Font font = new Font("宋体", Font.BOLD, 35);
g.setFont(font);
g.drawString("您累击敌方坦克数目",1024,50);
this.drawTank(1024,90,g,0,1);
//重置颜色 因为在画坦克时画笔颜色改变了
g.setColor(Color.black);
g.drawString(Recorder.getTotalTankNums()+"",1200,130);
}
@Override
public void paint(Graphics g) {
super.paint(g);
//画游戏界面大小
g.fillRect(0,0,1000,750);
//画界面信息
showInfo(g);
//画自己坦克
if(hero.leap){
drawTank(hero.getX(),hero.getY(),g,hero.getDirect(),0);
}
//画出爆炸效果
for (int i = 0; i < booms.size(); i++) {
Boom boom=booms.get(i);
if(boom.life>6){
g.drawImage(image2,boom.x,boom.y,80,80,this);
}
else if (boom.life>3){
g.drawImage(image1,boom.x,boom.y,80,80,this);
}
else {
g.drawImage(image3,boom.x,boom.y,80,80,this);
}
//让炸弹生命值减少 配合动态爆炸效果
boom.lifeTime();
//如果某个炸弹生命值为0 从booms删除
if(boom.life<=0){
booms.remove(boom);
}
}
//画敌人坦克
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
enemyTank.setEnemyTanks(enemyTanks);
if(enemyTank.leap){
//画敌人坦克
drawTank(enemyTank.getX(),enemyTank.getY(),g,enemyTank.getDirect(),1);
//画敌人子弹
for (int j = 0; j < enemyTank.shots.size(); j++) {
//先取子弹
Shot shot=enemyTank.shots.get(j);
//绘制子弹 先判断坐标是否越界 若越界则从shots集合里面去除 否则绘制
if(!shot.isLive){
enemyTank.shots.remove(j);
} else{
g.setColor(Color.green);
g.draw3DRect(shot.x,shot.y,3,3,false);
}
}
}
}
//画己方子弹
for (int i = 0; i < hero.shots.size(); i++) {
Shot shot = hero.shots.get(i);
if(shot!=null&&shot.isLive==true){
g.setColor(Color.cyan);
g.draw3DRect(shot.x,shot.y,3,3,false);
}else {
hero.shots.remove(shot);
}
}
}
/**
*
* @param x 坦克左上角x坐标
* @param y 坦克左上角y坐标
* @param g 画笔
* @param direct 方向
* @param type 坦克类型(自己/敌人)
*/
public void drawTank(int x,int y,Graphics g,int direct,int type){
//0我的坦克 1敌人坦克
switch (type){
case 0:
g.setColor(Color.cyan);
break;
case 1:
g.setColor(Color.green);
break;
}
//方向 (w 0上 1d 2右 s 3下 a左)
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.drawLine(x+20,y,x+20,y+20);//炮筒
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.drawLine(x+60,y+20,x+20,y+20);//炮筒
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.drawLine(x+20,y+20,x+20,y+60);//炮筒
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.drawLine(x,y+20,x+20,y+20);//炮筒
break;
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_W){
if(hero.getY()>0){
hero.moveUp();
}
hero.setDirect(0);
} else if (e.getKeyCode()==KeyEvent.VK_D) {
if(hero.getX()+60<1000){
hero.moveRight();
}
hero.setDirect(1);
}
else if (e.getKeyCode()==KeyEvent.VK_S) {
if (hero.getY()+60<750){
hero.moveDown();
}
hero.setDirect(2);
}else if (e.getKeyCode()==KeyEvent.VK_A) {
if (hero.getX()>0){
hero.moveLeft();
}
hero.setDirect(3);
}
if (e.getKeyCode()==KeyEvent.VK_J){
hero.shotEnemyTank();
}
this.repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
public void EnemyHitMyTank(Shot shot,Hero hero){
switch (hero.getDirect()){
case 0:
case 2:
if(shot.x>hero.getX()&&shot.x<hero.getX()+40
&&shot.y>hero.getY()&&shot.y<hero.getY()+60){
shot.isLive=false;
Boom boom=new Boom(hero.getX(),hero.getY());
if(hero.leap){
booms.add(boom);
hero.leap=false;
}
}
break;
case 1:
case 3:
if(shot.x>hero.getX()&&shot.x<hero.getX()+60
&&shot.y>hero.getY()&&shot.y<hero.getY()+40){
shot.isLive=false;
Boom boom=new Boom(hero.getX(),hero.getY());
if(hero.leap){
booms.add(boom);
hero.leap=false;
}
}
break;
}
}
//判断子弹是否击中坦克
public void hitEnemyTank(Shot shot, EnemyTank enemyTank){
switch (enemyTank.getDirect()){
case 0:
case 2:
if(shot.x>enemyTank.getX()&&shot.x<enemyTank.getX()+40
&&shot.y>enemyTank.getY()&&shot.y<enemyTank.getY()+60){
shot.isLive=false;
enemyTank.leap=false;
enemyTanks.remove(enemyTank);
hero.shots.remove(shot);
Recorder.countTankNums();
Boom boom=new Boom(enemyTank.getX(),enemyTank.getY());
booms.add(boom);
}
break;
case 1:
case 3:
if(shot.x>enemyTank.getX()&&shot.x<enemyTank.getX()+60
&&shot.y>enemyTank.getY()&&shot.y<enemyTank.getY()+40){
shot.isLive=false;
enemyTank.leap=false;
enemyTanks.remove(enemyTank);
hero.shots.remove(shot);
Recorder.countTankNums();
Boom boom=new Boom(enemyTank.getX(),enemyTank.getY());
booms.add(boom);
}
break;
}
}
@Override
public void run() {
while (true){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
//判断自己的子弹集合是否击中敌人坦克
for (int i = 0; i < hero.shots.size(); i++) {
Shot shot = hero.shots.get(i);
if(shot!=null && shot.isLive){
for (int j = 0; j < enemyTanks.size(); j++) {
EnemyTank enemyTank=enemyTanks.get(j);
hitEnemyTank(shot,enemyTank);
}
}
}
//判断敌人的子弹集合是否击中己方坦克
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
for (int j = 0; j < enemyTank.shots.size(); j++) {
Shot shot = enemyTank.shots.get(j);
if(shot!=null && shot.isLive){
EnemyHitMyTank(shot,hero);
}
}
}
this.repaint();
}
}
}
🌲框架的最终优化
package com.Cx_330.TankGame4;
import sun.awt.WindowClosingListener;
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;
public class TankGame03 extends JFrame {
private Mypanel mp=null;
public static void main(String[] args) {
TankGame03 tankGame01 = new TankGame03();
}
Scanner scanner=new Scanner(System.in);
public TankGame03() {
System.out.println("请做出你的选择 1--重开 0--继续上局");
String choice=scanner.next();
//启动画板线程
mp=new Mypanel(choice);
Thread thread = new Thread(mp);
thread.start();
//在框架中添加画板
this.add(mp);
//在框架中添加键盘监听事件
this.addKeyListener(mp);
//初始化框架的大小
this.setSize(1500,810);
//设置在关闭的时候自动结束JVM虚拟机
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//使画板画出来的图形可视化
this.setVisible(true);
//添加关闭窗口的处理
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
Recorder.keepRecord();
System.exit(0);
}
});
}
}