坦克大战游戏
- 主函数
- 战场面板
- 开始界面
- 坦克父类
- 敌方坦克
- 我方坦克
- 子弹
- 爆炸效果
- 数据存盘及恢复
- 图片
主函数
package cn.wenxiao.release9;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
public class GameMain extends JFrame implements ActionListener {
// 战场面板
WorldPanel mp = null;
// 开始面板
StartPanel sPanel = null;
// 定义菜单栏
JMenuBar jBar = null;
// 定义菜单
JMenu menu1 = null;
// 定义菜单选项
JMenuItem startMenuItem = null;
// 保存退出游戏
JMenuItem exitGaMenuItem = null;
// 继续上局游戏
JMenuItem continueGaMenuItem = null;
// 退出而不保存
JMenuItem exitWithoutSaveItem = null;
public static void main(String[] args) {
// TODO 主函数
GameMain gameMain = new GameMain();
}
public GameMain() {
// 创建开始页面的面板
sPanel = new StartPanel();
// 创建菜单栏
jBar = new JMenuBar();
// 创建菜单
menu1 = new JMenu("游戏(G)");
// 设置快捷方式
menu1.setMnemonic('G');
// 创建菜单项-开始新游戏
startMenuItem = new JMenuItem("开始新游戏(N)");
// 设置菜单项快捷方式
startMenuItem.setMnemonic('N');
// 创建菜单项继续上一局游戏
continueGaMenuItem = new JMenuItem("继续上一局游戏(C)");
continueGaMenuItem.setMnemonic('C');
// 创建保存退出游戏菜单项
exitGaMenuItem = new JMenuItem("保存并退出游戏(E)");
// 设置保存退出项快捷方式
exitGaMenuItem.setMnemonic('E');
// 退出不保存
exitWithoutSaveItem = new JMenuItem("退出不保存游戏(Q)");
exitWithoutSaveItem.setActionCommand("quit");
exitWithoutSaveItem.addActionListener(this);
// 设置菜单项的监听
startMenuItem.addActionListener(this);
continueGaMenuItem.addActionListener(this);
exitGaMenuItem.addActionListener(this);
// 设置菜单项目的命令识别符
startMenuItem.setActionCommand("new_game");
continueGaMenuItem.setActionCommand("continue");
exitGaMenuItem.setActionCommand("exit");
// 将菜单项目添加至菜单中
menu1.add(startMenuItem);
menu1.add(continueGaMenuItem);
menu1.add(exitGaMenuItem);
menu1.add(exitWithoutSaveItem);
// 将菜单添加至菜单栏中
jBar.add(menu1);
// 将面板添加至当前窗口
this.add(sPanel);
// 将开始页面的面板添加至新的线程中,并开启线程
Thread starThread = new Thread(sPanel);
starThread.start();
// 将菜单栏添加至当前窗口上
this.setJMenuBar(jBar);
// 设置窗口大小
this.setSize(800, 600);
// 设置窗口可见
this.setVisible(true);
// 设置窗口关闭程序关闭
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO 重写菜单项目监听事件处理方式
if (e.getActionCommand().equalsIgnoreCase("new_game")) {
// 删除当前窗口显示的开始面板
this.remove(sPanel);
// 如果在战场运行过程中,玩家点击了开始新游戏,那么删除旧的游戏面板,开启新的面板
if (mp != null) {
this.remove(mp);
}
// 如果点击了“开始新游戏”的按钮,则创建战场面板
mp = new WorldPanel();
Recorder.setEnemyTankTotal(20);
Recorder.setKilledNum(0);
Recorder.setMyLife(3);
// 开启战场面板的线程
Thread mpThread = new Thread(mp);
mpThread.start();
// 将战场面板添加至当前窗口
this.add(mp);
// 注册战场面板的监听
this.addKeyListener(mp);
// 当前窗口刷新显示
this.setVisible(true);
} else if (e.getActionCommand().equals("exit")) {
Recorder.saveData();
System.exit(0);
} else if (e.getActionCommand().equals("continue")) {
Recorder.readData();
// 删除当前窗口显示的开始面板
this.remove(sPanel);
// 如果在战场运行过程中,玩家点击了开始新游戏,那么删除旧的游戏面板,开启新的面板
if (mp != null) {
this.remove(mp);
}
// 如果点击了“开始新游戏”的按钮,则创建战场面板
mp = new WorldPanel();
// 开启战场面板的线程
Thread mpThread = new Thread(mp);
mpThread.start();
// 将战场面板添加至当前窗口
this.add(mp);
// 注册战场面板的监听
this.addKeyListener(mp);
// 当前窗口刷新显示
this.setVisible(true);
}else if(e.getActionCommand().equals("quit")) {
System.exit(0);
}
}
}
战场面板
package cn.wenxiao.release9;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;
import javax.swing.JPanel;
public class WorldPanel extends JPanel implements KeyListener, Runnable {
// 定义一个我的坦克
MyTank myTank = null;
int enemyTankbirth = 0;
// 定义敌人的坦克集合
Vector<EnemyTank> enemyTanks = new Vector<EnemyTank>();
// 定义一个爆炸效果的集合
Vector<Bomb> bombs = new Vector<Bomb>();
Image image1 = null;
Image image2 = null;
Image image3 = null;
int enemyCounts = 3;
// 构造函数
public WorldPanel() {
myTank = new MyTank(260, 380, 0);
// 初始化爆炸效果图片
image1 = Toolkit.getDefaultToolkit().getImage(WorldPanel.class.getResource("/3.png"));
image2 = Toolkit.getDefaultToolkit().getImage(WorldPanel.class.getResource("/2.png"));
image3 = Toolkit.getDefaultToolkit().getImage(WorldPanel.class.getResource("/1.png"));
}
// 重画
public void paint(Graphics graphics) {
super.paint(graphics);
graphics.fillRect(0, 0, 600, 400);
// 绘制爆炸效果
for (int i = 0; i < bombs.size(); i++) {
Bomb curentBomb = bombs.get(i);
if (curentBomb.life > 5) {
graphics.drawImage(image1, curentBomb.x, curentBomb.y, 30, 30, this);
} else if (bombs.get(i).life > 3) {
graphics.drawImage(image2, curentBomb.x, curentBomb.y, 30, 30, this);
} else {
graphics.drawImage(image3, curentBomb.x, curentBomb.y, 30, 30, this);
}
curentBomb.lifeDown();
if (curentBomb.life < 0) {
bombs.remove(curentBomb);
}
}
// 画出我方坦克
if (myTank.isAlive) {
this.drawTank(myTank.getX(), myTank.getY(), graphics, this.myTank.getDirect(), 0);
}
// 画出敌方坦克及敌人的子弹
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank currentTank = enemyTanks.get(i);
if (currentTank.isAlive) {
this.drawTank(currentTank.getX(), currentTank.getY(), graphics, currentTank.direct, 1);
}
if (currentTank.isAlive == false) {
enemyTanks.remove(i);
}
if (currentTank.bullets.size() > 0) {
for (int j = 0; j < currentTank.bullets.size(); j++) {
Bullet curBullet = currentTank.bullets.get(j);
if (curBullet != null && curBullet.isAlive == true) {
graphics.draw3DRect(curBullet.x, curBullet.y, 1, 1, false);
}
if (curBullet.isAlive == false) {
currentTank.bullets.remove(curBullet);
}
}
}
}
// 绘制子弹
for (int i = 0; i < myTank.bullets.size(); i++) {
Bullet currBullet = myTank.bullets.get(i);
if (currBullet != null && currBullet.isAlive == true) {
graphics.draw3DRect(currBullet.x, currBullet.y, 1, 1, false);
}
if (currBullet.isAlive == false) {
myTank.bullets.remove(currBullet);
}
}
this.paintInfo(graphics);
}
// 显示游戏信息的方法
public void paintInfo(Graphics graphics) {
this.drawTank(20, 430, graphics, 0, 1);
this.drawTank(20, 480, graphics, 0, 0);
graphics.setColor(Color.BLACK);
Font font = new Font("微软雅黑", Font.BOLD, 20);
graphics.setFont(font);
graphics.drawString("剩余:" + Recorder.getEnemyTankTotal(), 40, 440);
graphics.drawString("剩余:" + Recorder.getMyLife(), 40, 480);
graphics.drawString("已击杀: " + Recorder.getKilledNum(), 610, 30);
}
// 判断是否被击中
public void beHited(MyTank myTank, Vector<EnemyTank> enemyTanks) {
// 判断我方坦克的方向
// 取出敌方坦克
for (int i = 0; i < this.enemyTanks.size(); i++) {
EnemyTank enemyTank = enemyTanks.get(i);
// 取出敌方坦克的每一颗子弹
for (int j = 0; j < enemyTank.bullets.size(); j++) {
Bullet currentBullet = enemyTank.bullets.get(j);
switch (myTank.direct) {
case 0:
case 2:
if (currentBullet.x > myTank.getX() - 10 && currentBullet.x < myTank.getX() + 10
&& currentBullet.y > myTank.getY() - 15 && currentBullet.y < myTank.getY() + 15) {
// 爆炸效果
Bomb bomb = new Bomb(myTank.getX() - 15, myTank.getY() - 15);
bombs.add(bomb);
// 击中
currentBullet.isAlive = false;
myTank.isAlive = false;
Recorder.myLifeDown();
}
break;
case 1:
case 3:
if (currentBullet.x > myTank.getX() - 15 && currentBullet.x < myTank.getX() + 15
&& currentBullet.y > myTank.getY() - 10 && currentBullet.y < myTank.getY() + 10) {
// 爆炸效果
Bomb bomb = new Bomb(myTank.getX() - 5, myTank.getY() - 5);
bombs.add(bomb);
// 击中
currentBullet.isAlive = false;
myTank.isAlive = false;
Recorder.myLifeDown();
}
break;
}
}
}
}
// 判断击中与否的方法
public void hited(Bullet bullet, EnemyTank enemyTank) {
// 判断敌机的方向
switch (enemyTank.direct) {
case 0:
case 2:
if (bullet.x > enemyTank.getX() - 10 && bullet.x < enemyTank.getX() + 10 && bullet.y > enemyTank.getY() - 15
&& bullet.y < enemyTank.getY() + 15) {
// 爆炸效果
Bomb bomb = new Bomb(enemyTank.getX() - 15, enemyTank.getY() - 15);
bombs.add(bomb);
// 击中
bullet.isAlive = false;
enemyTank.isAlive = false;
Recorder.enemyTankTotalDown();
Recorder.killedNumUp();
}
break;
case 1:
case 3:
if (bullet.x > enemyTank.getX() - 15 && bullet.x < enemyTank.getX() + 15 && bullet.y > enemyTank.getY() - 10
&& bullet.y < enemyTank.getY() + 10) {
// 爆炸效果
Bomb bomb = new Bomb(enemyTank.getX() - 5, enemyTank.getY() - 5);
bombs.add(bomb);
// 击中
bullet.isAlive = false;
enemyTank.isAlive = false;
Recorder.enemyTankTotalDown();
Recorder.killedNumUp();
}
break;
}
}
// 画出坦克的函数
public void drawTank(int x, int y, Graphics graphics, int direct, int type) {
// 判断需要画的坦克的类型
switch (type) {
case 0:
graphics.setColor(Color.CYAN);
break;
case 1:
graphics.setColor(Color.YELLOW);
break;
}
// 判断方向
switch (direct) {
case 0:
graphics.fill3DRect(x - 10, y - 15, 5, 30, false);
graphics.fill3DRect(x + 5, y - 15, 5, 30, false);
graphics.fill3DRect(x - 5, y - 10, 10, 20, false);
graphics.fillOval(x - 5, y - 5, 10, 10);
graphics.drawLine(x, y - 15, x, y);
break;
case 1:
graphics.fill3DRect(x - 15, y - 10, 30, 5, false);
graphics.fill3DRect(x - 15, y + 5, 30, 5, false);
graphics.fill3DRect(x - 10, y - 5, 20, 10, false);
graphics.fillOval(x - 5, y - 5, 10, 10);
graphics.drawLine(x, y, x + 15, y);
break;
case 2:
graphics.fill3DRect(x - 10, y - 15, 5, 30, false);
graphics.fill3DRect(x + 5, y - 15, 5, 30, false);
graphics.fill3DRect(x - 5, y - 10, 10, 20, false);
graphics.fillOval(x - 5, y - 5, 10, 10);
graphics.drawLine(x, y, x, y + 15);
break;
case 3:
graphics.fill3DRect(x - 15, y - 10, 30, 5, false);
graphics.fill3DRect(x - 15, y + 5, 30, 5, false);
graphics.fill3DRect(x - 10, y - 5, 20, 10, false);
graphics.fillOval(x - 5, y - 5, 10, 10);
graphics.drawLine(x - 15, y, x, y);
break;
}
}
// 重写监听事件
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() == KeyEvent.VK_W) {
// 向上
// 设置我的坦克的方向
this.myTank.setDirect(0);
this.myTank.moveUp();
} else if (e.getKeyCode() == KeyEvent.VK_D) {
// 向右
this.myTank.setDirect(1);
this.myTank.moveRight();
} else if (e.getKeyCode() == KeyEvent.VK_S) {
// 向下
this.myTank.setDirect(2);
this.myTank.moveDown();
} else if (e.getKeyCode() == KeyEvent.VK_A) {
// 向左
this.myTank.setDirect(3);
this.myTank.moveLeft();
}
if (e.getKeyCode() == KeyEvent.VK_J) {
// 判断玩家按下了发射键
if (myTank.bullets.size() < 5) {
this.myTank.Shot();
}
}
// 暂停游戏
// boolean isPaused = false;
// if(e.getKeyCode() == KeyEvent.VK_P) {
// if(isPaused == true) {
// System.out.println("继续");
// myTank.speed=2;
// for(int i=0;i<enemyTanks.size();i++) {
// enemyTanks.get(i).speed=2;
// for(int j=0;j<enemyTanks.get(i).bullets.size();j++) {
// enemyTanks.get(i).bullets.get(j).speed=10;
// }
// }
// isPaused = false;
// }else if(isPaused==false) {
// System.out.println("暂停");
// myTank.speed=0;
// for(int i=0;i<enemyTanks.size();i++) {
// enemyTanks.get(i).speed=0;
// for(int j=0;j<enemyTanks.get(i).bullets.size();j++) {
// enemyTanks.get(i).bullets.get(j).speed=0;
// }
// }
// isPaused=true;
// }
//
// }
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
Thread.sleep(50);
} catch (Exception e) {
// TODO: handle exception
}
// 判断子弹是否击中,击中的时候,敌人的坦克就消失
for (int i = 0; i < myTank.bullets.size(); i++) {
Bullet curentBullet = myTank.bullets.get(i);
if (curentBullet.isAlive) {
for (int j = 0; j < enemyTanks.size(); j++) {
EnemyTank curEnemyTank = enemyTanks.get(j);
if (curEnemyTank.isAlive) {
hited(curentBullet, curEnemyTank);
}
}
}
}
// 判断是否是恢复游戏
if(Recorder.isContinue()) {
// 敌方坦克上场
if (enemyTanks.size() < 3 && (Recorder.getEnemyTankTotal() - 2) > 0) {
for(int i=0;i<Recorder.getEnemyTanks().size();i++) {
EnemyTank addTank = Recorder.getEnemyTanks().get(i);
Thread enemyThread = new Thread(addTank);
enemyThread.start();
enemyTanks.add(addTank);
addTank.setEnemyTanks(enemyTanks);
enemyTankbirth++;
if (enemyTankbirth >= 3) {
enemyTankbirth = 0;
}
}
Recorder.setContinue(false);
Recorder.setEnemyTanks(enemyTanks);
}else if(Recorder.getEnemyTankTotal()==1) {
EnemyTank addTank = Recorder.getEnemyTanks().get(0);
Thread enemyThread = new Thread(addTank);
enemyThread.start();
enemyTanks.add(addTank);
addTank.setEnemyTanks(enemyTanks);
enemyTankbirth++;
if (enemyTankbirth >= 3) {
enemyTankbirth = 0;
}
}
Recorder.setContinue(false);
Recorder.setEnemyTanks(enemyTanks);
}else {
// 敌方坦克上场
if (enemyTanks.size() < 3 && (Recorder.getEnemyTankTotal() - 2) > 0) {
EnemyTank addTank = new EnemyTank(enemyTankbirth * 250 + 50, 20, 2);
Thread enemyThread = new Thread(addTank);
enemyThread.start();
enemyTanks.add(addTank);
addTank.setEnemyTanks(enemyTanks);
enemyTankbirth++;
if (enemyTankbirth >= 3) {
enemyTankbirth = 0;
}
Recorder.setEnemyTanks(enemyTanks);
}
}
// 判断敌人的坦克是否击中我的坦克
if (myTank.isAlive) {
beHited(myTank, enemyTanks);
}
// 复活
if (Recorder.getMyLife() > 0) {
if (myTank.isAlive == false) {
myTank = new MyTank(260, 380, 0);
}
}
this.repaint();
}
}
}
开始界面
package cn.wenxiao.release9;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JPanel;
public class StartPanel extends JPanel implements Runnable{
// 控制字体闪烁
int times=0;
// 在面板上显示关卡信息
public void paint(Graphics graphics) {
super.paint(graphics);
graphics.fillRect(0, 0, 600, 400);
graphics.setColor(Color.YELLOW);
Font myFont = new Font("微软雅黑",Font.BOLD,50);
graphics.setFont(myFont);
if(times%2==0) {
graphics.drawString("第一关", 230, 210);
}
}
@Override
public void run() {
// TODO 线程,用于显示关卡数闪烁
while(true) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.repaint();
times++;
if(times>10000) {
times=0;
}
}
}
}
坦克父类
package cn.wenxiao.release9;
public class Tanks {
// 表示坦克的横坐标
int x = 0;
// 表示坦克的纵坐标
int y = 0;
// 坦克的方向
// 0表示上 1表示右 2表示下 3表示左
int direct = 0;
// 坦克的颜色
int color;
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
// 坦克的速度
int speed = 2;
public Tanks(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 cn.wenxiao.release9;
import java.util.Vector;
/*
* 敌人坦克对象
*/
public class EnemyTank extends Tanks implements Runnable {
// 敌人坦克的生命状态
boolean isAlive = true;
// 敌人坦克的默认方向向下
//int direct = (int) (Math.random() * 4);
int direct = 2;
// 定义敌人坦克的子弹
Bullet bullet = null;
// 定义敌人坦克的弹夹
Vector<Bullet> bullets = new Vector<Bullet>();
// 定义每个敌人坦克可以看到的友军坦克信息的集合
Vector<EnemyTank> enemyTanks = new Vector<EnemyTank>();
// 获取友军坦克信息的方法
public Vector<EnemyTank> getEnemyTanks() {
return enemyTanks;
}
// 从战场获取友军坦克信息的方法
public void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
this.enemyTanks = enemyTanks;
}
// 构造函数
public EnemyTank(int x, int y, int direct) {
super(x, y, direct);
}
@Override
public String toString() {
return "EnemyTank [isAlive=" + isAlive + ", direct=" + direct + "]";
}
// 判断坦克是否重叠的方法
public boolean isOverlapped() {
// 默认不重叠
boolean status = false;
// 根据当前坦克的方向,判断与之相遇的坦克是否重叠
switch(this.direct) {
case 0:
for(int i=0;i<enemyTanks.size();i++) {
// 取出一个坦克做判断
EnemyTank thEnemyTank = enemyTanks.get(i);
if(thEnemyTank!=this) {
if(thEnemyTank.direct==0 || thEnemyTank.direct==2) {
if((this.x-10)>=(thEnemyTank.x-10) && (this.x-10)<=(thEnemyTank.x+10) && (this.y-15) >= (thEnemyTank.y-15) && (this.y-15)<=(thEnemyTank.y+15)) {
return true;
}
if((this.x+10)>=(thEnemyTank.x-10) && (this.x+10)<=(thEnemyTank.x+10) && (this.y-15) >= (thEnemyTank.y-15) && (this.y-15)<=(thEnemyTank.y+15)) {
return true;
}
}
if(thEnemyTank.direct==1 || thEnemyTank.direct==3) {
if((this.x-10)>=(thEnemyTank.x-15) && (this.x-10)<=(thEnemyTank.x+15) && (this.y-15) >= (thEnemyTank.y-15) && (this.y-15)<=(thEnemyTank.y+15)) {
return true;
}
if((this.x+10)>=(thEnemyTank.x-15) && (this.x+10)<=(thEnemyTank.x+15) && (this.y-15) >= (thEnemyTank.y-10) && (this.y-15)<=(thEnemyTank.y+15)) {
return true;
}
}
}
}
break;
case 1:
for(int i=0;i<enemyTanks.size();i++) {
// 取出一个坦克做判断
EnemyTank thEnemyTank = enemyTanks.get(i);
if(thEnemyTank!=this) {
if(thEnemyTank.direct==0 || thEnemyTank.direct==2) {
if((this.x+15)>=(thEnemyTank.x-10) && (this.x+15)<=(thEnemyTank.x-10) && (this.y-10) >= (thEnemyTank.y-15) && (this.y-10)<=(thEnemyTank.y+15)) {
return true;
}
if((this.x+15)>=(thEnemyTank.x-10) && (this.x+15)<=(thEnemyTank.x+10) && (this.y-10) >= (thEnemyTank.y+15) && (this.y+10)<=(thEnemyTank.y+15)) {
return true;
}
}
if(thEnemyTank.direct==1 || thEnemyTank.direct==3) {
if((this.x+15)>=(thEnemyTank.x-15) && (this.x+15)<=(thEnemyTank.x+15) && (this.y-10) >= (thEnemyTank.y-10) && (this.y-10)<=(thEnemyTank.y+10)) {
return true;
}
if((this.x+15)>=(thEnemyTank.x-15) && (this.x+15)<=(thEnemyTank.x+15) && (this.y+10) >= (thEnemyTank.y-10) && (this.y+10)<=(thEnemyTank.y+10)) {
return true;
}
}
}
}
break;
case 2:
for(int i=0;i<enemyTanks.size();i++) {
// 取出一个坦克做判断
EnemyTank thEnemyTank = enemyTanks.get(i);
if(thEnemyTank!=this) {
if(thEnemyTank.direct==0 || thEnemyTank.direct==2) {
if((this.x-10)>=(thEnemyTank.x-10) && (this.x-10)<=(thEnemyTank.x+10) && (this.y+15) >= (thEnemyTank.y-15) && (this.y+15)<=(thEnemyTank.y+15)) {
return true;
}
if((this.x+10)>=(thEnemyTank.x-10) && (this.x+10)<=(thEnemyTank.x+10) && (this.y+15) >= (thEnemyTank.y-15) && (this.y+15)<=(thEnemyTank.y+15)) {
return true;
}
}
if(thEnemyTank.direct==1 || thEnemyTank.direct==3) {
if((this.x-10)>=(thEnemyTank.x-15) && (this.x-10)<=(thEnemyTank.x+15) && (this.y+15) >= (thEnemyTank.y-10) && (this.y+15)<=(thEnemyTank.y+10)) {
return true;
}
if((this.x+10)>=(thEnemyTank.x-10) && (this.x+10)<=(thEnemyTank.x+15) && (this.y+15) >= (thEnemyTank.y-10) && (this.y+15)<=(thEnemyTank.y+10)) {
return true;
}
}
}
}
break;
case 3:
for(int i=0;i<enemyTanks.size();i++) {
// 取出一个坦克做判断
EnemyTank thEnemyTank = enemyTanks.get(i);
if(thEnemyTank!=this) {
if(thEnemyTank.direct==0 || thEnemyTank.direct==2) {
if((this.x-15)>=(thEnemyTank.x-10) && (this.x-15)<=(thEnemyTank.x+10) && (this.y-10) >= (thEnemyTank.y-15) && (this.y-10)<=(thEnemyTank.y+15)) {
return true;
}
if((this.x-15)>=(thEnemyTank.x-10) && (this.x-15)<=(thEnemyTank.x+10) && (this.y+10) >= (thEnemyTank.y-15) && (this.y+10)<=(thEnemyTank.y+15)) {
return true;
}
}
if(thEnemyTank.direct==1 || thEnemyTank.direct==3) {
if((this.x-15)>=(thEnemyTank.x-15) && (this.x-15)<=(thEnemyTank.x+15) && (this.y-10) >= (thEnemyTank.y-10) && (this.y-10)<=(thEnemyTank.y+10)) {
return true;
}
if((this.x-15)>=(thEnemyTank.x-15) && (this.x-15)<=(thEnemyTank.x+15) && (this.y+10) >= (thEnemyTank.y-10) && (this.y+10)<=(thEnemyTank.y+10)) {
return true;
}
}
}
}
break;
}
return status;
}
// 设置一个速度
// 坦克向上移动
public void moveUp() {
y -= speed;
}
// 坦克向右移动
public void moveRight() {
x += speed;
}
// 坦克向下移动
public void moveDown() {
y += speed;
}
// 坦克向左移动
public void moveLeft() {
x -= speed;
}
// 发射子弹的方法
public void Shot() {
switch (direct) {
case 0:
bullet = new Bullet(x - 1, y - 15, 0);
bullets.add(bullet);
break;
case 1:
bullet = new Bullet(x + 15, y, 1);
bullets.add(bullet);
break;
case 2:
bullet = new Bullet(x - 1, y + 15, 2);
bullets.add(bullet);
break;
case 3:
bullet = new Bullet(x - 15, y, 3);
bullets.add(bullet);
break;
}
Thread shoThread = new Thread(bullet);
shoThread.start();
}
@Override
public void run() {
// TODO 每个敌人坦克都是一个独立的线程
while (true) {
// 通过随机数控制敌人坦克发射子弹
if (x > 15 && x < 570 && y > 15 && y < 450 && !this.isOverlapped()) {
// 控制敌人坦克随机发射子弹
int RandomShot = (int) (Math.random() * 100);
if (RandomShot < 50) {
this.Shot();
}
}
// 通过敌人坦克当前的方向控制坦克的运动
switch (this.direct) {
case 0:
for (int i = 0; i < 30; i++) {
if (y > 15 && !this.isOverlapped()) {
y -= speed;
}
try {
Thread.sleep(50);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
break;
case 1:
for (int i = 0; i < 30; i++) {
if (x < 450 && !this.isOverlapped()) {
x += speed;
}
try {
Thread.sleep(50);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
break;
case 2:
for (int i = 0; i < 30; i++) {
if (y < 380 && !this.isOverlapped()) {
y += speed;
}
try {
Thread.sleep(50);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
break;
case 3:
for (int i = 0; i < 30; i++) {
if (x > 15 && !this.isOverlapped()) {
x -= speed;
}
try {
Thread.sleep(50);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
break;
}
// 随机控制方向
this.direct = (int) (Math.random() * 4);
// 判断坦克是否被打死,打死了则停止线程
if (isAlive == false) {
break;
}
}
}
}
我方坦克
package cn.wenxiao.release9;
import java.util.Vector;
public class MyTank extends Tanks {
// 定义子弹
Bullet bullet = null;
// 定义我的弹夹
Vector<Bullet> bullets = new Vector<Bullet>();
// 我方坦克的生命状态
boolean isAlive = true;
// 构造函数
public MyTank(int x, int y, int direct) {
super(x, y, direct);
}
// 发射子弹的方法
public void Shot() {
switch (direct) {
case 0:
bullet = new Bullet(x - 1, y - 15, 0);
bullets.add(bullet);
break;
case 1:
bullet = new Bullet(x + 15, y, 1);
bullets.add(bullet);
break;
case 2:
bullet = new Bullet(x - 1, y + 15, 2);
bullets.add(bullet);
break;
case 3:
bullet = new Bullet(x - 15, y, 3);
bullets.add(bullet);
break;
}
Thread shoThread = new Thread(bullet);
shoThread.start();
}
// 坦克向上移动
public void moveUp() {
if (y > 15) {
y -= speed;
}
}
// 坦克向右移动
public void moveRight() {
if (x < 770) {
x += speed;
}
}
// 坦克向下移动
public void moveDown() {
if (y < 550) {
y += speed;
}
}
// 坦克向左移动
public void moveLeft() {
if (x > 15) {
x -= speed;
}
}
}
子弹
package cn.wenxiao.release9;
/*
* 子弹对象
*/
public class Bullet implements Runnable{
// 坐标
int x;
int y;
// 子弹的方向
int directory;
// 子弹运行的速度
int speed = 10;
// 子弹的生命状态
Boolean isAlive = true;
public Bullet(int x, int y, int directory) {
this.x = x;
this.y = y;
this.directory = directory;
}
@Override
public void run() {
// TODO 每一颗子弹都是一个独立的线程
while(true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 判断子弹的方向,每100毫秒运动一次
switch(directory) {
case 0:
y -= speed;
break;
case 1:
x += speed;
break;
case 2:
y += speed;
break;
case 3:
x -= speed;
break;
}
// 如果子弹触碰到了战场面板的边缘,则生命周期结束
if(x<0 || x >600 || y < 0 || y>400) {
this.isAlive = false;
break;
}
}
}
}
爆炸效果
package cn.wenxiao.release9;
/*
* 爆炸效果对象
*/
public class Bomb {
// 坐标
int x;
int y;
// 生命周期
int life=8;
// 状态
boolean isAlive=true;
public Bomb(int x, int y) {
this.x = x;
this.y = y;
}
// 爆炸显示过程控制
public void lifeDown() {
if(life>=0) {
life--;
}else {
isAlive=false;
}
}
}
数据存盘及恢复
package cn.wenxiao.release9;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Vector;
public class Recorder {
// 敌人坦克总数
private static int enemyTankTotal = 20;
// 我方坦克总数
private static int myLife = 3;
// 歼灭敌方坦克数
private static int killedNum = 0;
// 文件输出流
private static FileWriter fWriter = null;
// Buffered输出流
private static BufferedWriter bWriter = null;
// 文件输入流
private static FileReader fReader = null;
// Buffered输入流
private static BufferedReader bReader = null;
// 得到敌机集合
private static Vector<EnemyTank> enemyTanks = null;
// 是否是恢复游戏
private static boolean isContinue = false;
public static Vector<EnemyTank> getEnemyTanks() {
return enemyTanks;
}
public static void setEnemyTanks(Vector<EnemyTank> enemyTanks) {
Recorder.enemyTanks = enemyTanks;
}
public static int getEnemyTankTotal() {
return enemyTankTotal;
}
public static void setEnemyTankTotal(int enemyTankTotal) {
Recorder.enemyTankTotal = enemyTankTotal;
}
public static int getMyLife() {
return myLife;
}
public static void setMyLife(int myLife) {
Recorder.myLife = myLife;
}
public static int getKilledNum() {
return killedNum;
}
public static void setKilledNum(int killedNum) {
Recorder.killedNum = killedNum;
}
public static boolean isContinue() {
return isContinue;
}
public static void setContinue(boolean isContinue) {
Recorder.isContinue = isContinue;
}
// 保存当前游戏数据
public static void saveData() {
try {
fWriter = new FileWriter(".\\GameData.txt");
bWriter = new BufferedWriter(fWriter);
bWriter.write("当前总击杀:" + killedNum + "\r\n");
bWriter.write("敌机剩余:" + enemyTankTotal + "\r\n");
bWriter.write("我的生命剩余:" + myLife + "\r\n");
// 遍历当前在场上的敌机,并将坐标存入文件
for (int i = 0; i < enemyTanks.size(); i++) {
EnemyTank currEnemyTank = enemyTanks.get(i);
String positionData = "第" + (i + 1) + "辆敌机坐标:" + "X:" + currEnemyTank.x + ":Y:" + currEnemyTank.y
+ ":Directory:" + currEnemyTank.direct + "\r\n";
bWriter.write(positionData);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
bWriter.close();
fWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// 读取数据
public static void readData() {
enemyTanks = new Vector<EnemyTank>();
isContinue = true;
try {
fReader = new FileReader(".\\GameData.txt");
bReader = new BufferedReader(fReader);
int[] data = new int[3];
int index = 0;
String dataString = null;
while ((dataString = bReader.readLine()) != null) {
String[] string = dataString.split(":");
// 前三个是游戏主要数据,通过数组取出
if (index < 3) {
data[index++] = Integer.parseInt(string[1]);
// 后面的数据都是上一局游戏中敌机的坐标信息,单独处理
} else if (index >= 3) {
int x = Integer.parseInt(string[2]);
int y = Integer.parseInt(string[4]);
int direct = Integer.parseInt(string[6]);
EnemyTank enemyTank = new EnemyTank(x, y, direct);
enemyTanks.add(enemyTank);
}
}
killedNum = data[0];
enemyTankTotal = data[1];
myLife = data[2];
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bReader.close();
fReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 敌人坦克减少
public static void enemyTankTotalDown() {
enemyTankTotal--;
}
// 我方坦克被击中,命数减少
public static void myLifeDown() {
myLife--;
}
// 歼灭敌方坦克数
public static void killedNumUp() {
killedNum++;
}
}
图片