当前位置:网站首页>实现可以继续上局
实现可以继续上局
2022-06-11 18:19:00 【C_x_330】
实现记录
要实现记录,这里就用用到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);
}
});
}
}
边栏推荐
- Force deduction questions -- create a string based on a binary tree
- 2022成年礼,致每一位高考学子
- [c language] shift elements after sorting elements of an array
- Several commands related to domain name
- Balanced search binary tree -- AVL tree
- Combination sum of 39 questions
- [C语言]用结构体把输入的指定分数范围内的学生输出
- . Net core redis hyperloglog type
- Why is ti's GPMC parallel port more often used to connect FPGA and ADC? I give three reasons
- Niuke's brush question -- judgment of legal bracket sequence
猜你喜欢

Force deduction 23 questions, merging K ascending linked lists

Why is ti's GPMC parallel port more often used to connect FPGA and ADC? I give three reasons

On the sequence traversal of binary tree Ⅱ

TI AM64x——最新16nm处理平台,专为工业网关、工业机器人而生

labelme进行图片数据标注
![[c language] output the students within the specified score range with the structure](/img/40/cbd7fe5aafbaeb6237e6d257455e5e.png)
[c language] output the students within the specified score range with the structure
![[C语言]限制查找次数,输出次数内查找到的最大值](/img/e6/cbb8dd54b49ade453251a70c8455e8.png)
[C语言]限制查找次数,输出次数内查找到的最大值
![[c language] output the average score and the student data below or equal to the average score with the structure](/img/c4/263301a22b61c86a3e0df6ad2596f1.png)
[c language] output the average score and the student data below or equal to the average score with the structure

H. 264 concept

Why is ti's GPMC parallel port more often used to connect FPGA and ADC? I give three reasons
随机推荐
判断是否为平衡二叉树
Niu Ke's questions -- two sorting methods
[untitled]
Map and set
TR-069 protocol introduction
Some thoughts on how to do a good job of operation and maintenance management
*Use of jetpack notes room
Monitoring loss functions using visdom
全志科技T3開發板(4核ARM Cortex-A7)——MQTT通信協議案例
力扣33题,搜索旋转排序数组
Various poses for text modification using sed
[c language] output the students with the highest scores with a structure. There can be multiple highest scores
01.电信_领域业务经验
async导致函数结果出乎意料,改变原来代码的意图;await is only valid in async functions and the top level bodies of modules
HashSet集合存储学生对象并遍历
H.264概念
vim常用命令
牛客刷题——把字符串转换成整数
[c language] output the students within the specified score range with the structure
牛客刷题——合法括号序列判断