Java初学笔记28
坦克游戏部分代码0.2
1.Tank
package project.tankgame05;
/**
* @ClassName: Tank
* @Description: 坦克父类
*/
public class Tank {
private int x; //坦克的横坐标
private int y; //坦克的纵坐标
private int direction; //坦克方向 0123 上下左右
private int speed = 3; //坦克速度
/**
* 坦克存活状态
*/
private boolean t_sur = true;
public Tank(int x, int y) {
this.x = x;
this.y = y;
}
/**
* 坦克上移动方法
*/
public void moveUp(){
y -= speed;
}
/**
* 坦克右移动方法
*/
public void moveRight(){
x += speed;
}
/**
* 坦克下移动方法
*/
public void moveDown(){
y += speed;
}
/**
* 坦克左移动方法
*/
public void moveLeft(){
x -= speed;
}
/**
* 坦克开火的方法
*/
public void fire(){
}
public int getDirection() {
return direction;
}
public void setDirection(int direction) {
this.direction = direction;
}
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 getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public boolean isT_sur() {
return t_sur;
}
public void setT_sur(boolean t_sur) {
this.t_sur = t_sur;
}
}
2.MyTank
package project.tankgame05;
import java.util.Vector;
/**
* @ClassName: MyTank
* @Description: 自己的坦克
*/
public class MyTank extends Tank { //继承父类坦克
/**
* 属性:自己的子弹线程
*/
MyBullet myBullet = null;
/**
* Vector集合:存储自己的子弹集合
*/
Vector<MyBullet> myBullets = new Vector<>();
/**
* 自己的坦克-构造器
*/
public MyTank(int x, int y) {
super(x, y);
}
/**
* 方法:自己坦克开火。
* 实例化并启动自己的子弹线程
*/
@Override
public void fire() {
//游戏面板控制自己的子弹最多为8个
if(myBullets.size() == 8){
return;
}
switch (getDirection()){
case 0:
myBullet = new MyBullet(getX()+20,getY(),getDirection());
break;
case 1:
myBullet = new MyBullet(getX()+60,getY()+20,getDirection());
break;
case 2:
myBullet = new MyBullet(getX()+20,getY()+60,getDirection());
break;
case 3:
myBullet = new MyBullet(getX(),getY()+20,getDirection());
break;
}
//将自己的子弹线程加入集合
myBullets.add(myBullet);
//启动子弹线程
new Thread(myBullet).start();
}
}
3.EnemyTank
package project.tankgame05;
import java.util.Vector;
/**
* @ClassName: EnemyTank
* @Description: 敌人的坦克线程
*/
public class EnemyTank extends Tank implements Runnable{
/**
* Vector集合:每个敌人坦克用集合存放自己的多个子弹线程
*/
Vector<EnemyBullet> e_Bullets_Ve = new Vector<>();
/**
* Vector集合:每个敌人坦克用集合存放其他的敌人坦克线程(该集合内也有自己的)
*/
Vector<EnemyTank> enemyTanks = new Vector<>();
/**
* 可以在TankPanel类中调用该方法,在每个敌人内部初始化多个敌人坦克线程
* @param enemyTanks
*/
public void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
this.enemyTanks = enemyTanks;
}
/**
* 判断当前坦克是否与其他坦克重叠
* @return
*/
public boolean isTouchEnemyTank(){
//遍历取出每一个敌人坦克
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
//因为该集合中有自己的的坦克线程,自己坦克不能和自己坦克比较
if(this != enemyTank){
//把每个坦克看成60*60的矩形,判断两个坦克中心是否小于60
double len = Math.sqrt((this.getX() - enemyTank.getX())*(this.getX() - enemyTank.getX())+
(this.getY() - enemyTank.getY())*(this.getY() - enemyTank.getY()));
if(len <= 70){
return true;
}
}
}
return false;
}
/**
* 敌人坦克的构造器
* @param x
* @param y
*/
public EnemyTank(int x, int y) {
super(x, y);
}
@Override
public void run() {
while (true){
//判断此时敌人坦克是否存活,以及坦克里面的子弹线程是否还有
//使敌人坦克可以发射5颗子弹
if(isT_sur() && e_Bullets_Ve.size() < 5){
EnemyBullet bul = null;
//根据此时坦克的位置创建敌人子弹线程
switch (getDirection()){
case 0:
bul = new EnemyBullet(getX()+20,getY(),0);
break;
case 1:
bul = new EnemyBullet(getX()+60,getY()+20,1);
break;
case 2:
bul = new EnemyBullet(getX()+20,getY()+60,2);
break;
case 3:
bul = new EnemyBullet(getX(),getY()+20,3);
break;
}
//将敌人子弹线程加入集合
e_Bullets_Ve.add(bul);
//启动敌人子弹线程
new Thread(bul).start();
}
//敌人坦克随机移动
switch (getDirection()){
case 0:
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(getY() > 0 && !isTouchEnemyTank()){
moveUp();
}
}
break;
case 1:
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(getX() + 60 < 1000 && !isTouchEnemyTank()){
moveRight();
}
}
break;
case 2:
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(getY() + 60 < 750 && !isTouchEnemyTank()){
moveDown();
}
}
break;
case 3:
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(getX() > 0 && !isTouchEnemyTank()){
moveLeft();
}
}
break;
}
//为敌人坦克设置随机方向
setDirection((int)(Math.random()*4));
//敌人坦克死亡,结束线程
if(!isT_sur()){
System.out.println("敌人坦克线程: "+ Thread.currentThread().getName()
+" 已经结束");
break;
}
}
}
}
4.Bullet
package project.tankgame05;
/**
* @Package: project.tankgame03
* @ClassName: Bullet
* @Author: 爱吃凉拌辣芒果
* @CreateTime: 2021/10/28 9:50
* @Description: 子弹父类
*/
public class Bullet {
/**
* 子弹的b_x位置
*/
private int b_x;
/**
* 子弹的b_y位置
*/
private int b_y;
/**
* 子弹的方向 0123 上右下左
*/
private int b_direction;
/**
* 子弹的速度 默认3
*/
private int b_speed = 3;
/**
* 子弹存活状态
*/
private boolean b_sur = true;
/**
* 构造函数:初始化子弹的原始位置以及方向
* @param b_x
* @param b_y
* @param b_direction
*/
public Bullet(int b_x, int b_y, int b_direction) {
this.b_x = b_x;
this.b_y = b_y;
this.b_direction = b_direction;
}
/**
* 获取子弹x坐标
* @return
*/
public int getB_x() {
return b_x;
}
/**
* 设置子弹x坐标
* @return
*/
public void setB_x(int b_x) {
this.b_x = b_x;
}
/**
* 获取子弹y坐标
* @return
*/
public int getB_y() {
return b_y;
}
/**
* 设置子弹y坐标
* @return
*/
public void setB_y(int b_y) {
this.b_y = b_y;
}
/**
* 获取子弹方向
* @return
*/
public int getB_direction() {
return b_direction;
}
/**
* 设置获取子弹方向
* @return
*/
public void setB_direction(int b_direction) {
this.b_direction = b_direction;
}
/**
* 获取子弹速度
* @return
*/
public int getB_speed() {
return b_speed;
}
/**
* 设置子弹速度
* @return
*/
public void setB_speed(int b_speed) {
this.b_speed = b_speed;
}
/**
* 获取子弹存活状态
* @return
*/
public boolean isB_sur() {
return b_sur;
}
/**
* 设置子弹存活状态
* @return
*/
public void setB_sur(boolean b_sur) {
this.b_sur = b_sur;
}
}
5.MyBullet
package project.tankgame05;
/**
* @Package: project.tankgame03
* @ClassName: MyBullet
* @Author: 爱吃凉拌辣芒果
* @CreateTime: 2021/10/28 9:57
* @Description: 我的子弹线程
*/
public class MyBullet extends Bullet implements Runnable{
/**
* 构造函数:初始化我的子弹原始位置以及方向
*
* @param b_x
* @param b_y
* @param b_direction
*/
public MyBullet(int b_x, int b_y, int b_direction) {
super(b_x, b_y, b_direction);
}
@Override
public void run() {
while (true){
//休眠50毫秒
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
//判断自己的子弹方向,沿着这一方向移动
switch (getB_direction()){
case 0:
setB_y(getB_y()-getB_speed());
break;
case 1:
setB_x(getB_x()+getB_speed());
break;
case 2:
setB_y(getB_y()+getB_speed());
break;
case 3:
setB_x(getB_x()-getB_speed());
break;
}
//System.out.println("我的子弹坐标"+getB_x()+" "+getB_y());
//如果自己的子弹超出世界边界,或者生命状态在其他地方被设置成false,则
//设置子弹线程的生命状态为false,并且结束线程
if(!(getB_x()>=0 && getB_x()<=1000 && getB_y()>=0 &&getB_y()<=750)
|| isB_sur() == false){
setB_sur(false);
System.out.println("我的子弹线程 "+ Thread.currentThread().getName() +" 已经结束");
break;
}
}
}
}
6.EnemyBullet
package project.tankgame05;
/**
* @Package: project.tankgame03
* @ClassName: EnemyBullet
* @Author: 爱吃凉拌辣芒果
* @CreateTime: 2021/10/28 14:10
* @Description:
*/
public class EnemyBullet extends Bullet implements Runnable{
/**
* 构造函数:初始化敌人子弹的原始位置以及方向
*
* @param b_x
* @param b_y
* @param b_direction
*/
public EnemyBullet(int b_x, int b_y, int b_direction) {
super(b_x, b_y, b_direction);
}
@Override
public void run() {
while (true){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
//设置敌人子弹朝着某一方向移动
switch (getB_direction()){
case 0:
setB_y(getB_y()-getB_speed());
break;
case 1:
setB_x(getB_x()+getB_speed());
break;
case 2:
setB_y(getB_y()+getB_speed());
break;
case 3:
setB_x(getB_x()-getB_speed());
break;
}
//System.out.println("敌人子弹坐标"+getB_x()+" "+getB_y());
if(!(getB_x()>=0 && getB_x()<=1000 && getB_y()>=0 &&getB_y()<=750)
|| !isB_sur()){
setB_sur(false);
System.out.println("敌人子弹线程 "+ Thread.currentThread().getName() +" 已经结束");
break;
}
}
}
}
7.Bomb
package project.tankgame05;
/**
* @Package: project.tankgame03
* @ClassName: Bomb
* @Author: 爱吃凉拌辣芒果
* @CreateTime: 2021/10/29 9:41
* @Description: 炸弹特效类
*/
public class Bomb {
/**
* 炸弹的X坐标
*/
int x;
/**
* 炸弹的Y坐标
*/
int y;
/**
* 炸弹的生命周期
*/
int life = 9;
/**
* 炸弹的存活状态
*/
boolean isLive = true;
/**
* 炸弹构造器,初始化X,Y坐标
* @param x
* @param y
*/
public Bomb(int x, int y) {
this.x = x;
this.y = y;
}
/**
* 使炸弹图片生命值逐渐减少
*/
public void cutLife(){
if(isLive && life>=0){
life--;
}else{
isLive = false;
}
}
}
8.Recorder
package project.tankgame05;
import java.io.*;
import java.util.Vector;
/**
* @Package: project.tankgame05
* @ClassName: Recorder
* @Author: 爱吃凉拌辣芒果
* @CreateTime: 2021/11/5 11:12
* @Description: 与文件进行交互
*/
public class Recorder {
/**
* 击毁敌人坦克数量
*/
private static int killEneTankNum = 0;
/**
* 定义输出文件对象
*/
private static BufferedWriter bw = null;
/**
* 定义输入文件对象
*/
private static BufferedReader br = null;
/**
* 定义存放敌人数量的文件路径
*/
private static String filePath = "src\\record.txt";
/**
* 定义存放存活敌人的文件路径
*/
private static String filePath1 = "src\\record2.txt";
/**
* 使击毁的敌人坦克数量就加1
*/
public static void addkillEneTankNum(){
Recorder.killEneTankNum++;
}
/**
* 集合:记录敌人坦克信息
*/
private static Vector<EnemyTank> enemyTanks = null;
/**
* 定义我的坦克
*/
private static MyTank mytank = null;
/**
* 集合:记录恢复的坦克信息
*/
private static Vector<Node> nodes = new Vector<>();
/**
* 初始化敌人坦克线程
* @param enemyTanks
*/
public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
Recorder.enemyTanks = enemyTanks;
}
/**
* 初始化自己坦克
* @param mytank
*/
public static void setMytank(MyTank mytank) {
Recorder.mytank = mytank;
}
/**
* 关闭游戏时将击毁敌人坦克的数量写入文件
*/
public static void storekillEneTankNum(){
try {
bw = new BufferedWriter(new FileWriter(filePath));
// bw.write(killEneTankNum+"\r\n");
bw.write(killEneTankNum+"");
bw.newLine();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bw != null){
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 关闭游戏时将存活的敌人与自己的坦克写入文件
*/
public static void storeAliveEneTank(){
try {
bw = new BufferedWriter(new FileWriter(filePath1));
//存入敌人坦克
for (int i = 0; i < enemyTanks.size(); i++) {
//取出每一个坦克
EnemyTank enemyTank = enemyTanks.get(i);
if(enemyTank.isT_sur()){
String str = enemyTank.getX() + " " + enemyTank.getY()
+ " " + enemyTank.getDirection();
//bw.write(str+"\r\n");
bw.write(str);
bw.newLine();
}
}
//存入自己的坦克
if(mytank!= null && mytank.isT_sur()){
String str = mytank.getX() + " " + mytank.getY()
+ " " + mytank.getDirection();
bw.write(str);
bw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(bw!=null){
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 恢复读取已经击杀的敌人坦克数量
* @return
*/
public static void readKillTankNum(){
try {
br = new BufferedReader(new FileReader(filePath));
Recorder.killEneTankNum = Integer.parseInt(br.readLine());
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 恢复坦克位置方向信息
* @return
*/
public static Vector<Node> readTank(){
try {
br = new BufferedReader(new FileReader(filePath1));
String tanks = null;
while ((tanks = br.readLine()) != null){
String[] s = tanks.split(" ");
Node node = new Node(Integer.parseInt(s[0])
, Integer.parseInt(s[1])
, Integer.parseInt(s[2]));
nodes.add(node);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return nodes;
}
}
public static int getKillEneTankNum() {
return killEneTankNum;
}
public static void setKillEneTankNum(int killEneTankNum) {
Recorder.killEneTankNum = killEneTankNum;
}
}
9.Node
package project.tankgame05;
/**
* @Package: project.tankgame05
* @ClassName: Node
* @Author: 爱吃凉拌辣芒果
* @CreateTime: 2021/11/7 9:52
* @Description: Node节点恢复保存的坦克
*/
public class Node {
/**
* 用于保存恢复的坦克的x,y,方法
*/
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;
}
}
10.AePlayWave
package project.tankgame05;
import javax.sound.sampled.*;
import java.io.File;
import java.io.IOException;
/**
* wav音频播放线程
*/
public class AePlayWave extends Thread {
private String filename;
public AePlayWave(String wavfile) {
filename = wavfile;
}
public void run() {
File soundFile = new File(filename);
AudioInputStream audioInputStream = null;
try {
audioInputStream = AudioSystem.getAudioInputStream(soundFile);
} catch (Exception e1) {
e1.printStackTrace();
return;
}
AudioFormat format = audioInputStream.getFormat();
SourceDataLine auline = null;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
try {
auline = (SourceDataLine) AudioSystem.getLine(info);
auline.open(format);
} catch (Exception e) {
e.printStackTrace();
return;
}
auline.start();
int nBytesRead = 0;
//这是缓冲
byte[] abData = new byte[512];
try {
while (nBytesRead != -1) {
nBytesRead = audioInputStream.read(abData, 0, abData.length);
if (nBytesRead >= 0)
auline.write(abData, 0, nBytesRead);
}
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
auline.drain();
auline.close();
}
}
}
11.TankPanel
package project.tankgame05;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.util.Vector;
/**
* @ClassName: TankPanel
* @Description: 坦克游戏区域————“画板”
*/
public class TankPanel extends JPanel implements KeyListener,Runnable{
/**
* 定义我的坦克
*/
MyTank mytank = null;
/**
* Vector集合:集合中存放敌人坦克
*/
Vector<EnemyTank> enemyTanks = new Vector<>();
/**
* Vector集合:集合中存放恢复的坦克
*/
Vector<Node> nodes = new Vector<>();
/**
* 敌人坦克数量
*/
int enemyTankNum = 5;
/**
* Vector集合:存放炸弹特效
* 当自己的子弹击中敌人坦克时,加入一个炸弹
*/
Vector<Bomb> bombs = new Vector<>();
/**
* 声明3个存放炸弹特效的变量image1,image2,image3
*/
Image image1 = null;
Image image2 = null;
Image image3 = null;
/**
* “画板”构造器
*/
public TankPanel(String key){
File file1 = new File("src\\record.txt");
File file2 = new File("src\\record2.txt");
if(!file1.exists() && !file2.exists()){
key = "1";
System.out.println("读取旧游戏失败,开启新游戏");
}
switch (key){
case "1": //1: 开始新游戏
//初始化我的坦克
mytank = new MyTank(100,600);
//初始化敌人坦克,默认朝下
for (int i = 0; i < enemyTankNum; i++) {
EnemyTank enemyTank = new EnemyTank(150 * (i + 1), 0);
//初始化敌人的子弹
EnemyBullet enemyBullet = new EnemyBullet(enemyTank.getX() + 20,
enemyTank.getY() + 60, 2);
//把敌人子弹加入到集合中
enemyTank.e_Bullets_Ve.add(enemyBullet);
//启动敌人子弹线程
new Thread(enemyBullet).start();
enemyTank.setDirection(2);
//把敌人坦克加入到集合中
enemyTanks.add(enemyTank);
//将 enemyTanks集合 赋值给每个敌人坦克
enemyTank.setEnemyTanks(enemyTanks);
//启动敌人坦克
new Thread(enemyTank).start();
}
//将敌人坦克线程初始化到Recorder
Recorder.setEnemyTanks(enemyTanks);
//将自己的坦克初始化到Recorder
Recorder.setMytank(mytank);
break;
case "2": //2: 继续上局游戏
//恢复击杀敌人信息
Recorder.readKillTankNum();
//恢复坦克信息
nodes = Recorder.readTank();
if(nodes == null){
break;
}
//核对坦克数量信息
int hedui = (Recorder.getKillEneTankNum() + nodes.size());
if(hedui != enemyTankNum){
//初始化我的坦克
Node node = nodes.get(this.nodes.size() - 1);
mytank = new MyTank(node.getX(),node.getY());
mytank.setDirection(node.getDirect());
//初始化敌人坦克
for (int i = 0; i < nodes.size()-1; i++) {
//取出敌人坦克节点信息
Node node1 = nodes.get(i);
EnemyTank enemyTank = new EnemyTank(node1.getX(),node1.getY());
//初始化敌人的子弹
EnemyBullet enemyBullet = new EnemyBullet(enemyTank.getX() + 20,
enemyTank.getY() + 60, node1.getDirect());
//把敌人子弹加入到集合中
enemyTank.e_Bullets_Ve.add(enemyBullet);
//启动敌人子弹线程
new Thread(enemyBullet).start();
//设置敌人坦克方向
enemyTank.setDirection(node1.getDirect());
//把敌人坦克加入到集合中
enemyTanks.add(enemyTank);
//将 enemyTanks集合 赋值给每个敌人坦克
enemyTank.setEnemyTanks(enemyTanks);
//启动敌人坦克
new Thread(enemyTank).start();
}
//将敌人坦克线程初始化到Recorder
Recorder.setEnemyTanks(enemyTanks);
//将自己的坦克初始化到Recorder
Recorder.setMytank(mytank);
}else{
//初始化敌人坦克
for (int i = 0; i < nodes.size(); i++) {
//取出敌人坦克节点信息
Node node1 = nodes.get(i);
EnemyTank enemyTank = new EnemyTank(node1.getX(),node1.getY());
//初始化敌人的子弹
EnemyBullet enemyBullet = new EnemyBullet(enemyTank.getX() + 20,
enemyTank.getY() + 60, node1.getDirect());
//把敌人子弹加入到集合中
enemyTank.e_Bullets_Ve.add(enemyBullet);
//启动敌人子弹线程
new Thread(enemyBullet).start();
//设置敌人坦克方向
enemyTank.setDirection(node1.getDirect());
//把敌人坦克加入到集合中
enemyTanks.add(enemyTank);
//将 enemyTanks集合 赋值给每个敌人坦克
enemyTank.setEnemyTanks(enemyTanks);
//启动敌人坦克
new Thread(enemyTank).start();
}
//将敌人坦克线程初始化到Recorder
Recorder.setEnemyTanks(enemyTanks);
//将自己的坦克初始化到Recorder
Recorder.setMytank(mytank);
}
break;
default:
System.out.println("输入有误~~");
}
//初始化炸弹特效图片
image1 = Toolkit.getDefaultToolkit()
.getImage(TankPanel.class.getResource("/bomb_1.gif"));
image2 = Toolkit.getDefaultToolkit()
.getImage(TankPanel.class.getResource("/bomb_2.gif"));
image3 = Toolkit.getDefaultToolkit()
.getImage(TankPanel.class.getResource("/bomb_3.gif"));
//播放音乐
new AePlayWave("src\\111.wav").start();
}
/**
* 显示玩家成绩
*/
public void showInfor(Graphics g){
g.setColor(Color.black);
Font font = new Font("楷体", Font.BOLD, 25);
g.setFont(font);
g.drawString("已击毁敌人坦克",1020,30);
drawTank(1020,60,g,0,1);
g.setColor(Color.black);
g.drawString(Recorder.getKillEneTankNum()+"",1080,100);
}
/**
* paint绘画方法
* @param g
*/
@Override
public void paint(Graphics g) {
super.paint(g);
//默认黑色矩形背景
g.setColor(Color.BLACK);
//默认黑色矩形1000 × 750
g.fillRect(0,0,1000,750);
//绘制成绩
showInfor(g);
//绘制-自己的坦克
if(mytank != null && mytank.isT_sur()){
drawTank(mytank.getX(),mytank.getY(),g,mytank.getDirection(),0);
}
//绘制敌人的坦克
//判断敌人坦克集合不为空
if(enemyTanks != null){
//遍历敌人坦克集合
for (int i = 0; i < enemyTanks.size(); i++) {
//取出每个敌人坦克
EnemyTank enemyTank = enemyTanks.get(i);
//判断每个坦克的生命状态
if(enemyTank.isT_sur()) {
drawTank(enemyTank.getX(), enemyTank.getY(), g,
enemyTank.getDirection(), 1);
}else{
//坦克的生命状态为false,除了不绘画之外,还需要在
//集合中移除
enemyTanks.remove(enemyTank);
}
}
}
//绘制自己的子弹
//遍历自己的子弹集合
if(mytank != null && mytank.myBullets != null){
for (int i = 0; i < mytank.myBullets.size(); i++) {
//取出每个子弹
MyBullet myBullet = mytank.myBullets.get(i);
//判断子弹的生命状态
if(myBullet != null && myBullet.isB_sur()){
g.setColor(Color.RED);
g.fillOval(myBullet.getB_x(),myBullet.getB_y(),5,5);
}else{
mytank.myBullets.remove(myBullet);
}
}
}
//绘制敌人的子弹
//判断敌人坦克集合不为空
if(enemyTanks != null ){
//遍历敌人坦克集合
for (int i = 0; i < enemyTanks.size(); i++) {
//取出每个敌人坦克
EnemyTank enemyTank = enemyTanks.get(i);
//判断敌人坦克的子弹集合不为空
if(enemyTank.e_Bullets_Ve != null){
//遍历敌人坦克的子弹集合
for (int j = 0; j < enemyTank.e_Bullets_Ve.size(); j++) {
//取出每个敌人坦克的子弹
EnemyBullet enemyBullet = enemyTank.e_Bullets_Ve.get(j);
//判断每个敌人子弹的状态
if(enemyBullet.isB_sur()){
g.setColor(Color.yellow);
g.fillOval(enemyBullet.getB_x(), enemyBullet.getB_y(),
5, 5);
}else{
//敌人子弹的生命状态为false,除了不绘画之外
// 还需要在集合中移除
enemyTank.e_Bullets_Ve.remove(enemyBullet);
}
}
}
}
}
//绘制炸弹特效
//遍历炸弹集合
for (int i = 0; i < bombs.size(); i++) {
//取出每一个炸弹
Bomb bomb = bombs.get(i);
if(bomb.isLive){
//分阶段绘制炸弹
if(bomb.life > 6){
g.drawImage(image1,bomb.x,bomb.y,50,50,this);
bomb.cutLife();
}else if(bomb.life > 3){
g.drawImage(image2,bomb.x,bomb.y,50,50,this);
bomb.cutLife();
}else{
g.drawImage(image3,bomb.x,bomb.y,50,50,this);
bomb.cutLife();
}
}else{
bombs.remove(bomb);
}
}
}
/**
* 画坦克的方法
* @param x 坦克左上角的x坐标
* @param y 坦克右上角的x坐标
* @param g 画笔
* @param direct 坦克的方向(上下左右)
* @param type 坦克类型
*/
public void drawTank(int x, int y, Graphics g,int direct,int type){
//根据不同类型的坦克,设置不同的颜色
switch (type){
case 0://我们的坦克
g.setColor(Color.pink);
break;
case 1: //敌人坦克
g.setColor(Color.yellow);
break;
}
//根据坦克方向,绘制不同的坦克
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+30,x+20,y); //坦克炮筒
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+30,y+20,x+60,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+30,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+30,y+20); //坦克炮筒
break;
}
}
/**
* 字符输出事件方法
* @param e
*/
@Override
public void keyTyped(KeyEvent e) {
}
/**
* 键盘按下事件方法
* WDSA 坦克的方向:上右下左
* @param e
*/
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W){
mytank.setDirection(0); //更改坦克的方向
if(mytank.getY()>0){
mytank.moveUp(); //使坦克向上走
}
}else if(e.getKeyCode() == KeyEvent.VK_D){
mytank.setDirection(1);
if(mytank.getX()+60<1000){
mytank.moveRight(); //使坦克向右走
}
}else if(e.getKeyCode() == KeyEvent.VK_S){
mytank.setDirection(2);
if(mytank.getY()+60<750){
mytank.moveDown(); //使坦克向下走
}
}else if(e.getKeyCode() == KeyEvent.VK_A){
mytank.setDirection(3);
if(mytank.getX()>0){
mytank.moveLeft(); //使坦克向左走
}
}
//按下J键 子弹射击
if(mytank != null && mytank.isT_sur()){
if(e.getKeyCode() == KeyEvent.VK_J){
mytank.fire();
}
}
this.repaint();
}
/**
* 键盘弹起事件方法
* @param e
*/
@Override
public void keyReleased(KeyEvent e) {
}
/**
* “画板”刷新
*/
@Override
public void run() {
while (true){
//画板隔0.1秒刷新一次
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
killEnenmy();
killMyTank();
this.repaint();
}
}
/**
* 方法:自己的子弹打敌人坦克
* 设置自己的子弹和敌人坦克的生命状态
* @param myBullet 自己的子弹
* @param enemyTank 敌人坦克
*/
public void bitEnenmy(MyBullet myBullet, EnemyTank enemyTank){
switch (enemyTank.getDirection()){
case 0:
case 2:
if(myBullet.getB_x() >= enemyTank.getX() && myBullet.getB_x() <= enemyTank.getX()+40
&& myBullet.getB_y() >= enemyTank.getY() && myBullet.getB_y() <= enemyTank.getY()+60 ){
//子弹状态:FALSE
myBullet.setB_sur(false);
//坦克状态:FALSE
enemyTank.setT_sur(false);
for (int i = 0; i < enemyTank.e_Bullets_Ve.size(); i++) {
EnemyBullet enemyBullet = enemyTank.e_Bullets_Ve.get(i);
enemyBullet.setB_sur(false);
}
//敌人坦克被击毁的数量加1
Recorder.addkillEneTankNum();
//把炸弹特效放在敌人位置处,并加入集合
bombs.add(new Bomb(enemyTank.getX(),enemyTank.getY()));
}
break;
case 1:
case 3:
if(myBullet.getB_x() >= enemyTank.getX() && myBullet.getB_x() <= enemyTank.getX()+60
&& myBullet.getB_y() >= enemyTank.getY() && myBullet.getB_y() <= enemyTank.getY()+40 ){
//子弹状态:FALSE
myBullet.setB_sur(false);
//坦克状态:FALSE
enemyTank.setT_sur(false);
for (int i = 0; i < enemyTank.e_Bullets_Ve.size(); i++) {
EnemyBullet enemyBullet = enemyTank.e_Bullets_Ve.get(i);
enemyBullet.setB_sur(false);
}
//敌人坦克被击毁的数量加1
Recorder.addkillEneTankNum();
//把炸弹特效放在敌人位置处,并加入集合
bombs.add(new Bomb(enemyTank.getX(),enemyTank.getY()));
}
break;
}
}
/**
* 取出自己的子弹集合与敌人坦克进行遍历看是否击中
*/
public void killEnenmy(){
//遍历自己的坦克子弹,取出每个子弹
for (int i = 0; i < mytank.myBullets.size(); i++) {
MyBullet myBullet = mytank.myBullets.get(i);
//判断自己的子弹打中敌人
for (int j = 0; j < enemyTanks.size(); j++) {
if (enemyTanks != null && myBullet!= null){
EnemyTank enemyTank = enemyTanks.get(j);
bitEnenmy(myBullet,enemyTank);
}
}
}
}
/**
* 方法:敌人的子弹打自己坦克
* 设置敌人的子弹和自己人坦克的生命状态
* @param enemyBullet 敌人的子弹
* @param mytank 自己的坦克
*/
public void bitMyTank(EnemyBullet enemyBullet, MyTank mytank){
if(mytank != null && mytank.isT_sur()) {
switch (mytank.getDirection()) {
case 0:
case 2:
if (enemyBullet.getB_x() >= mytank.getX() && enemyBullet.getB_x() <= mytank.getX() + 40
&& enemyBullet.getB_y() >= mytank.getY() && enemyBullet.getB_y() <= mytank.getY() + 60) {
//子弹状态:FALSE
enemyBullet.setB_sur(false);
//坦克状态:FALSE
mytank.setT_sur(false);
for (int i = 0; i < mytank.myBullets.size(); i++) {
MyBullet myBullet = mytank.myBullets.get(i);
myBullet.setB_sur(false);
}
//把炸弹特效放在自己位置处,并加入集合
bombs.add(new Bomb(mytank.getX(), mytank.getY()));
}
break;
case 1:
case 3:
if (enemyBullet.getB_x() >= mytank.getX() && enemyBullet.getB_x() <= mytank.getX() + 60
&& enemyBullet.getB_y() >= mytank.getY() && enemyBullet.getB_y() <= mytank.getY() + 40) {
//子弹状态:FALSE
enemyBullet.setB_sur(false);
//坦克状态:FALSE
mytank.setT_sur(false);
for (int i = 0; i < mytank.myBullets.size(); i++) {
MyBullet myBullet = mytank.myBullets.get(i);
myBullet.setB_sur(false);
}
//把炸弹特效放在自己位置处,并加入集合
bombs.add(new Bomb(mytank.getX(), mytank.getY()));
}
break;
}
}
}
/**
* 取出敌人的子弹与自己坦克遍历,看是否击中自己的坦克
*/
public void killMyTank(){
//先遍历敌人的坦克
for (int i = 0; i < enemyTanks.size(); i++) {
//取出每个敌人坦克
EnemyTank enemyTank = enemyTanks.get(i);
//遍历每个敌人坦克里面的每个子弹线程
for (int j = 0; j < enemyTank.e_Bullets_Ve.size(); j++) {
EnemyBullet bullet = enemyTank.e_Bullets_Ve.get(j);
bitMyTank(bullet,mytank);
}
}
}
}
12.TankGame05
package project.tankgame05;
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Scanner;
/**
* @ClassName: TankGame05
* @Description: 坦克游戏5.0框架
*/
public class TankGame05 extends JFrame {
TankPanel tankPanel01 = null; //先定义一个空的1.0“画板”
public static void main(String[] args) {
TankGame05 tankGame01 = new TankGame05();
}
/**
* 构造器
*/
public TankGame05(){
System.out.println("1: 开始新游戏\r\n2: 继续上局游戏");
Scanner scanner = new Scanner(System.in);
String next = scanner.next();
tankPanel01 = new TankPanel(next); //初始化1.0“画板”
this.add(tankPanel01); //添加1.0“画板”
this.setSize(1300,850); //设置“画板”大小
this.setVisible(true); //设置“画板”可见
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //点×关闭
this.addKeyListener(tankPanel01);
new Thread(tankPanel01).start();
//Windows窗口关闭监听事件
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("游戏关闭,数据正在存档中......");
Recorder.storekillEneTankNum();
Recorder.storeAliveEneTank();
System.exit(0);
}
});
}
}