java 坦克大战从敌人集合中删除坦克时报错

【Java_项目篇(1)】--JAVA实现坦克大战游戏--赋予敌人行动和攻击(五)
前期相关文章
【_项目篇&1&】&JAVA实现坦克大战游戏&画出坦克(一)
【Java_项目篇&1&】&JAVA实现坦克大战游戏&坦克移动+添加敌方坦克(二)
【Java_项目篇&1&】&JAVA实现坦克大战游戏&坦克发射子弹(三)
【Java_项目篇&1&】&JAVA实现坦克大战游戏&子弹连发+爆炸效果(四)
一、任务需求
赋予敌人行动和攻击。
- 敌人行动
1.需要把EnemyTank做成线程类实现Runnable接口.
run方法中,坦克移动非常快biu biu biu,所以用sleep和for循环进行减速,让他缓慢移动。移动后再让弹可随机选择一个direct,如果坦克islive=false就让该线程结束。另外,增加if语句,当坦克跑出400*300的边界时,坦克不能向外移动。只能向边界内移动。
while (true) {
Thread.sleep(50);
} catch (Exception e) {
e.printStackTrace();
switch (Direct) {
for(int i=0;i&3;i++){
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
//说明坦克正在向上移动
for(int i=0;i&3;i++){
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
for(int i=0;i&3;i++){
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
for(int i=0;i&3;i++){
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
//让坦克随机产生新的方向
(int)(Math.random()*4);
//判断敌人坦克是否死亡
if(isLive==false){
//让坦克死亡,退出线程
2.改进画出敌方坦克代码,并且在MyPanel中定义坦克集合
// 定义敌军
Vector ets = new Vector();
// 画出敌方坦克
for (int i = 0; i & ets.size(); i++) {
EnemyTank et = ets.get(i);
if (et.isLive) {
drawTank(et.getX(), et.getY(), g, et.getDirect(), ets.get(i)
.getColor());
// 画出敌人坦克子弹
for (int j = 0; j & et.ss.size(); j++) {
Shot enemyShot = et.ss.get(j);// j写错成i
if (enemyShot.isLive) {
g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);
// 如果敌人的坦克死亡,就从Vector去掉
et.ss.remove(enemyShot);
-坦克发射子弹
2.将之前的MyPanel类run()方法中判断子弹击中坦克部分提取出来,再改写为hitEnemyTank()方法。
3.同上一步骤,改写hitMe()方法。
4. 而之前的hitTank(Shot s,EnemyTank et)改成hitTank(Shot s,Tank et)用以被hitMe()和hitEnemyTank()调用
三、源代码
MyTankGame.java
* 功能:坦克游戏的2.0
* 1.画出坦克
* 2.坦克的移动
* 3.坦克发射子弹,子弹连发,最多五颗
* 4.爆炸效果
* 5.敌人开始行动啦
* 6.我被打爆
package Tank_05;
import java.awt.C
import java.awt.G
import java.awt.I
import java.awt.P
import java.awt.T
import java.awt.event.KeyE
import java.awt.event.KeyL
import java.util.V
import javax.swing.JF
import javax.swing.JP
@SuppressWarnings(&serial&)
public class MyTankGame4 extends JFrame {
MyPanel p1 =
public MyTankGame4() {
p1 = new MyPanel();
Thread t = new Thread(p1);
t.start();
setSize(400, 300);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(p1);// 注册监听
public static void main(String[] args) {
new MyTankGame4();
@SuppressWarnings(&serial&)
class MyPanel extends JPanel implements KeyListener, Runnable {
int enSize = 3;
Hero hero =
// 定义敌军
Vector ets = new Vector();
// 定义炸弹集合
Vector bombs = new Vector();
// 定义8张图片,8张图片组成一颗炸弹
Image image1 =
Image image2 =
Image image3 =
Image image4 =
Image image5 =
Image image6 =
Image image7 =
Image image8 =
public MyPanel() {
hero = new Hero(100, 100);// 设置坦克出现的位置(10,10)
// 初始化敌人的坦克
for (int i = 0; i & enS i++) {
// 创建对人的坦克对象
EnemyTank et = new EnemyTank((i + 1) * 80, 0);
et.setColor(1);
et.setDirect(1);
// 启动敌人的坦克
Thread t = new Thread(et);
t.start();
// 给敌人添加子弹
Shot s = new Shot(et.x + 9, et.y + 28, 1);
// 加入给敌人坦克
et.ss.add(s);
Thread t2 = new Thread(s);
t2.start();
ets.add(et);
// 初始化图片
image1 = Toolkit.getDefaultToolkit().getImage(
Panel.class.getResource(&/blast1.gif&));
image2 = Toolkit.getDefaultToolkit().getImage(
Panel.class.getResource(&/blast2.gif&));
image3 = Toolkit.getDefaultToolkit().getImage(
Panel.class.getResource(&/blast3.gif&));
image4 = Toolkit.getDefaultToolkit().getImage(
Panel.class.getResource(&/blast4.gif&));
image5 = Toolkit.getDefaultToolkit().getImage(
Panel.class.getResource(&/blast5.gif&));
image6 = Toolkit.getDefaultToolkit().getImage(
Panel.class.getResource(&/blast6.gif&));
image7 = Toolkit.getDefaultToolkit().getImage(
Panel.class.getResource(&/blast7.gif&));
image8 = Toolkit.getDefaultToolkit().getImage(
Panel.class.getResource(&/blast8.gif&));
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillRect(0, 0, 400, 300);// 背景填充
// 画出我方坦克
if(hero.isLive){
drawTank(hero.getX(), hero.getY(), g, hero.Direct, 0);// 一定要传入画笔g
// 从ss中取出每一颗子弹,并画出
for (int i = 0; i & hero.ss.size(); i++) {
Shot myShot = hero.ss.get(i);
// 画出子弹
if (myShot != null && myShot.isLive == true) {
// System.out.format(&%d %d
&, hero.s.x,hero.s.y);
g.setColor(Color.red);
g.draw3DRect(myShot.x, myShot.y, 1, 1, false);
if (myShot.isLive == false) {
hero.ss.remove(myShot);// 记住是myShot 不是i
// 画出炸弹
for (int i = 0; i & bombs.size(); i++) {
// 取出炸弹
Bomb b = bombs.get(i);
// System.out.format(&%d&,++num);
if (b.life & 8) {
g.drawImage(image1, b.x, b.y, 30, 30, this);
} else if (b.life & 7) {
g.drawImage(image2, b.x, b.y, 30, 30, this);
} else if (b.life & 6) {
g.drawImage(image3, b.x, b.y, 30, 30, this);
} else if (b.life & 5) {
g.drawImage(image4, b.x, b.y, 30, 30, this);
} else if (b.life & 4) {
g.drawImage(image5, b.x, b.y, 30, 30, this);
} else if (b.life & 3) {
g.drawImage(image6, b.x, b.y, 30, 30, this);
} else if (b.life & 2) {
g.drawImage(image7, b.x, b.y, 30, 30, this);
} else if (b.life & 1) {
g.drawImage(image8, b.x, b.y, 30, 30, this);
b.lifeDown();
// 如果life为 0 酒吧炸弹从bombs向量去掉
if (b.life == 0) {
bombs.remove(b);
// 画出敌方坦克
for (int i = 0; i & ets.size(); i++) {
EnemyTank et = ets.get(i);
if (et.isLive) {
drawTank(et.getX(), et.getY(), g, et.getDirect(), ets.get(i)
.getColor());
// 画出敌人坦克子弹
for (int j = 0; j & et.ss.size(); j++) {
Shot enemyShot = et.ss.get(j);// j写错成i
if (enemyShot.isLive) {
g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false);
// 如果敌人的坦克死亡,就从Vector去掉
et.ss.remove(enemyShot);
public void hitMe() {
// 取出每个敌人的坦克
for (int i = 0; i & ets.size(); i++) {
// 取出坦克
EnemyTank et = ets.get(i);
// 取出每颗子弹
for (int j = 0; j & et.ss.size(); j++) {
Shot enemyShot = et.ss.get(j);
hitTank(enemyShot, hero);
public void hitEnemyTank() {
// 判断是否击中敌人坦克
for (int i = 0; i & hero.ss.size(); i++) {
Shot myShot = hero.ss.get(i);
// 判断子弹是否有效
if (myShot.isLive) {
// 取出每个坦克,与他判断
for (int j = 0; j & ets.size(); j++) {
EnemyTank et = ets.get(j);
if (et.isLive) {
hitTank(myShot, et);
// 写一个函数专门判断: 子弹是否击中敌人坦克
public void hitTank(Shot s, Tank et) {
// 判断该坦克的方向
switch (et.Direct) {
// 方向上或者下,是相同的
if (s.x & et.x && s.x & et.x + 20 && s.y & et.y && s.y & et.y + 30) {
// 击中,子弹死亡
s.isLive =
// 坦克死亡
et.isLive =
// 触发爆炸,放入vector
Bomb b = new Bomb(et.x, et.y);
bombs.add(b);
// 方向左右,相同
if (s.x & et.x && s.x & et.x + 30 && s.y & et.y && s.y &= et.y + 20) {
s.isLive =
et.isLive =
Bomb b = new Bomb(et.x, et.y);
bombs.add(b);
* drawTank (坦克坐标x,y,画笔g,方向,坦克类型) 方法介绍: 可以设置--&坦克的颜色(类型:敌方坦克,我方坦克),方向,出现的坐标
* 如果type是default 则默认颜色为画出黑色坦克
* 封装性:将坦克封装到方法中。
public void drawTank(int x, int y, Graphics g, int direct, int type) {
switch (type) {
g.setColor(Color.cyan);
g.setColor(Color.yellow);
switch (direct) {
g.fill3DRect(x, y, 5, 30, false);
g.fill3DRect(x + 15, y, 5, 30, false);
g.fill3DRect(x + 5, y + 5, 10, 20, false);
g.fillOval(x + 4, y + 10, 10, 10);
g.drawLine(x + 9, y + 15, x + 9, y);
g.fill3DRect(x, y, 5, 30, false);
g.fill3DRect(x + 15, y, 5, 30, false);
g.fill3DRect(x + 5, y + 5, 10, 20, false);
g.fillOval(x + 4, y + 10, 10, 10);
g.drawLine(x + 9, y + 15, x + 9, y + 30);
g.fill3DRect(x, y, 30, 5, false);
g.fill3DRect(x, y + 15, 30, 5, false);
g.fill3DRect(x + 5, y + 5, 20, 10, false);
g.fillOval(x + 9, y + 4, 10, 10);
g.drawLine(x + 5, y + 9, x - 4, y + 9);
g.fill3DRect(x, y, 30, 5, false);
g.fill3DRect(x, y + 15, 30, 5, false);
g.fill3DRect(x + 5, y + 5, 20, 10, false);
g.fillOval(x + 9, y + 4, 10, 10);
g.drawLine(x + 15, y + 9, x + 30, y + 9);
// repaint(); 因为监听器里面有repaint() 所以不用在加repaint()了
public void keyTyped(KeyEvent e) {
public void keyPressed(KeyEvent e) {// 实现接口 根据按键上下左右移动 可以控制速度和移动
if (e.getKeyCode() == KeyEvent.VK_W) {
hero.setDirect(0);
hero.moveUp();
} else if (e.getKeyCode() == KeyEvent.VK_S) {
hero.setDirect(1);
hero.moveDown();
} else if (e.getKeyCode() == KeyEvent.VK_A) {
hero.setDirect(2);
hero.moveLeft();
} else if (e.getKeyCode() == KeyEvent.VK_D) {
hero.setDirect(3);
hero.moveRight();
if (e.getKeyCode() == KeyEvent.VK_J) {
if (hero.ss.size() &= 4) {
hero.shotEnemy();
// 判断玩家是否按下J攻击键
repaint();
public void keyReleased(KeyEvent e) {
public void run() {
// 每隔100毫秒 重新画图
while (true) {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
hitEnemyTank();
repaint();
members.java
package Tank_05;
import java.util.V
//坦克父类
可以设置坦克出现位置(x,y)
class Tank {
int x = 0;
int y = 0;
int speed = 8;
int Direct = 0;
boolean isLive =
public int getColor() {
public void setColor(int color) {
this.color =
public int getDirect() {
public void setDirect(int direct) {
public int getSpeed() {
public void setSpeed(int speed) {
this.speed =
public Tank(int x, int y) {
public int getX() {
public void setX(int x) {
public int getY() {
public void setY(int y) {
// 视频中是把移动放在hero类中
// 敌方坦克
// 需要做成线程类
class EnemyTank extends Tank implements Runnable {
int time = 0;
//定义一个向量存放敌人的子弹
Vector ss = new Vector();
//敌人添加子弹,在刚刚创建坦克的时候
public EnemyTank(int x, int y) {
super(x, y);
public void run() {
while (true) {
Thread.sleep(50);
} catch (Exception e) {
e.printStackTrace();
switch (Direct) {
for(int i=0;i&3;i++){
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
//说明坦克正在向上移动
for(int i=0;i&3;i++){
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
for(int i=0;i&3;i++){
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
for(int i=0;i&3;i++){
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
if(time%2==0){
if(isLive){
if(ss.size()&8){
//没有子弹了
switch(Direct){
// 创建一颗子弹
s = new Shot(x + 8, y - 4, 0);
// 把子弹加入向量
ss.add(s);
s = new Shot(x + 9, y + 32, 1);
ss.add(s);
s = new Shot(x - 8, y + 8, 2);
ss.add(s);
s = new Shot(x + 32, y + 9, 3);
ss.add(s);
//启动子单线程
Thread t = new Thread(s);
t.start();
//让坦克随机产生新的方向
(int)(Math.random()*4);
//判断敌人坦克是否死亡
if(isLive==false){
//让坦克死亡,退出线程
// 我的英雄坦克
class Hero extends Tank {
Vector ss = new Vector();
public Hero(int x, int y) {
super(x, y);
public void shotEnemy() {
switch (Direct) {
// 创建一颗子弹
s = new Shot(x + 8, y - 4, 0);
// 把子弹加入向量
ss.add(s);
s = new Shot(x + 9, y + 32, 1);
ss.add(s);
s = new Shot(x - 8, y + 8, 2);
ss.add(s);
s = new Shot(x + 32, y + 9, 3);
ss.add(s);
Thread t = new Thread(s);
t.start();
public void moveUp() {
public void moveDown() {
public void moveLeft() {
public void moveRight() {
class Shot implements Runnable {
int speed = 1;
boolean isLive =
public Shot(int x, int y, int Direct) {
this.Direct = D
public void run() {
while (true) {
Thread.sleep(50);
} catch (Exception e) {
switch (Direct) {
// System.out.println(&&+x+& &+y);
// 子弹何时死亡
if (x & 0 || x & 400 || y & 0 || y & 300) {
this.isLive =
class Bomb {
// 炸弹的生命
int life = 9;
boolean isLive =
public Bomb(int x, int y) {
// 减少生命值
public void lifeDown() {
if (life & 0) {
四、效果图package _25增加配置文件;
import java.awt.*;
import java.awt.event.*;
import java.util.L
import java.util.ArrayL
* 这是这款游戏的主窗口,各个类都有他的引用
public class TankClient extends Frame{
private Image offScreamImage = null;
public static int WIDTH,HEIGHT;
public int times = 0;
public List&Bullets& myBullets = new ArrayList&Bullets&();
public List&Explode& explodes = new ArrayList&Explode&();
public List&Tank& enemyTank = new ArrayList&Tank&();
public Tank myTank = new Tank(50,500,true,Direction.STOP,this);
public int width = Toolkit.getDefaultToolkit().getScreenSize().
public int height = Toolkit.getDefaultToolkit().getScreenSize().
public Wall wall1 = new Wall(100,100,20,200,this);
public Wall wall2 = new Wall(300,450,70,70,this);
public Blood b = new Blood(this);
private boolean GAME_OVER = false;
* 这个方法时画出图形的主要方法,其他类实现的图形,最终都要放到这个方法中
public void paint(Graphics g) {
wall1.draw(g);
wall2.draw(g);
b.draw(g);
myTank.drawTank(g);
myTank.eat(b);
* 当敌人没有了,就再生成一些敌人
if(enemyTank.size()==0){
int reinitTank = Integer.parseInt(GetProp.getProp("reTankCount"));
for(int i = 0;i&reinitTi++){
Tank t = new Tank(50+80*i,50,false,Direction.STOP,this);
t.GAME_LEVEL -= 3 ;
enemyTank.add(t);
* 每隔25毫秒就重画地方所有坦克
for(int i=0 ;i&enemyTank.size();i++){
Tank t = enemyTank.get(i);
t.hitWall(wall1);
t.hitWall(wall2);
t.hitTank(enemyTank);
t.drawTank(g);
* 画出爆炸
for(int i = 0;i&explodes.size();i++){
Explode e = explodes.get(i);
e.draw(g);
给用户的提示信息
g.setFont(new Font("", Font.BOLD, 15));
if(times&=30){
g.drawString("还有多少发炮弹:"+0, 10, 50);
g.setColor(Color.red);
g.drawString("没炮弹了(充钱)", 20, 75);
g.drawString("还有多少发炮弹:"+(30-times), 10, 50);
g.drawString("敌方坦克:"+enemyTank.size(), 10, 70);
* 画子弹,当子弹没有了,就不能画子弹了
if(myBullets.size()!=0)
for(int i=0;i&myBullets.size();i++){
Bullets b = myBullets.get(i);
b.hitTanks(enemyTank);
b.hitTank(myTank);
b.hitWall(wall1);
b.hitWall(wall2);
b.draw(g);
* 添加双缓冲消除闪烁现象
public void update(Graphics g) {
if(offScreamImage == null){
offScreamImage = this.createImage(WIDTH,HEIGHT);
Graphics gOffScream = offScreamImage.getGraphics();
Color c = g.getColor();
gOffScream.setColor(Color.gray);
gOffScream.fillRect(0, 0, WIDTH, HEIGHT);
gOffScream.setColor(c);
paint(gOffScream);
g.drawImage(offScreamImage, 0, 0, null);
* 程序开始的主方法
public void lauchFrame(){
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension size = kit.getScreenSize();
WIDTH = size.width/2+size.width/4;
HEIGHT = size.height/2+size.height/4;
this.setBounds(size.width/8,size.height/8,WIDTH,HEIGHT);
Image image = kit.getImage("1.jpg");
setIconImage(image);
this.setBackground(Color.gray);
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e) {
GAME_OVER = true;
System.exit(0);
this.addKeyListener(myTank.new MyKeyEvent());
int initTankCount = Integer.parseInt(GetProp.getProp("initTankCount"));
for(int i = 1;i&initTankCi++){
enemyTank.add(new Tank(50+50*i,50,false,Direction.STOP,this));
setVisible(true);
new Thread(new PaintThread()).start();
public static void main(String[] args) {
new TankClient().lauchFrame();
* 重画的一个线程
private class PaintThread implements Runnable{
public void run() {
while(!GAME_OVER){
repaint();
Thread.sleep(25);
} catch (InterruptedException e) {
e.printStackTrace();
package _25增加配置文件;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
* 画坦克的主要类
public class Tank {
private int x,y;
private int oldX,oldY;
private static final int WIDTH = 50,HEIGHT = 50;
private static final int XSPEED = 5,YSPEED = 5;
public int GAME_LEVEL = 14;
private boolean bL = false ,bU = false ,bR = false ,bD = false;
private Direction dir = Direction.STOP;
private Direction ptDir = Direction.D;
private TankClient tc = null;
private boolean
private boolean live = true;
private static Random rand = new Random();
private int step = rand.nextInt(15)+3;
private int life = 100;
private BloodBar bb
= new BloodBar();
* 增加图片
private static Toolkit tk = Toolkit.getDefaultToolkit();
private static Map&String,Image& imags = new HashMap&String,Image&();
private static Image[] tankImage = null;
tankImage = new Image[]{
tk.getImage(Explode.class.getClassLoader().getResource("images/tankL.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankLU.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankU.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankRD.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankR.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankRU.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankD.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/tankLD.gif"))
imags.put("L", tankImage[0]);
imags.put("LU", tankImage[1]);
imags.put("U", tankImage[2]);
imags.put("RD", tankImage[3]);
imags.put("R", tankImage[4]);
imags.put("RU", tankImage[5]);
imags.put("D", tankImage[6]);
imags.put("LD", tankImage[7]);
public int getLife() {
public void setLife(int life) {
this.life =
public void setGood(boolean good) {
this.good =
public boolean isGood() {
public boolean isLive() {
public void setLive(boolean live) {
this.live =
public Tank(int x,int y,boolean good,Direction dir,TankClient tc){
this.good =
this.dir =
public void drawTank(Graphics g){
if(!live){
tc.enemyTank.remove(this);
bb.draw(g);
ptDraw(g);
* 用于判断
tank 往哪个方向走
用枚举里面的数
来判断是往哪个方向走的
从此 x y 的改变就从move这个方法里面改变(原来是从KeyAdapter 里面改变的)
private void move(){
switch(dir){
x-=XSPEED; break;
x-=XSPEED; y-=YSPEED; break;
y-=XSPEED; break;
x+=XSPEED; y+=YSPEED; break;
x+=XSPEED; break;
x+=XSPEED; y-=YSPEED; break;
y+=YSPEED; break;
x-=XSPEED; y+=YSPEED; break;
case STOP : break;
* 判断是否出界
if(x&=TankClient.WIDTH-Tank.WIDTH-5)
x = TankClient.WIDTH-Tank.WIDTH-5;
if(y&=TankClient.HEIGHT-Tank.HEIGHT-5)
y=TankClient.HEIGHT-Tank.HEIGHT-5;
* 给炮筒一个方向
if(this.dir != Direction.STOP)
* 让炮筒发射子弹
if(!good){
if(step == 0){
Direction[] arr = Direction.values();
int r = rand.nextInt(arr.length);
dir = arr[r];
step = rand.nextInt(15)+3;
if(step&=GAME_LEVEL) fire();
* 画出炮筒
private void ptDraw(Graphics g){
switch(ptDir){
g.drawImage(imags.get("L"),x, y, null); break;
g.drawImage(imags.get("LU"),x, y, null); break;
g.drawImage(imags.get("U"),x, y, null); break;
g.drawImage(imags.get("RD"),x, y, null); break;
g.drawImage(imags.get("R"),x, y, null); break;
g.drawImage(imags.get("RU"),x, y, null); break;
g.drawImage(imags.get("D"),x, y, null); break;
g.drawImage(imags.get("LD"),x, y, null); break;
case STOP :
g.drawImage(imags.get("STOP"),x, y, null); break;
* Tank真正走的方向
L, LU, U, RD, R, RU, D, LD, STOP
取决于dir的值
private void realDirection(){
if(bL && !bU && !bR && !bD)
dir = Direction.L;
else if(bL && bU && !bR && !bD)
dir = Direction.LU;
else if(!bL && bU && !bR && !bD)
dir = Direction.U;
else if(!bL && !bU && bR && bD)
dir = Direction.RD;
else if(!bL && !bU && bR && !bD)
dir = Direction.R;
else if(!bL && bU && bR && !bD)
dir = Direction.RU;
else if(!bL && !bU && !bR && bD)
dir = Direction.D;
else if(bL && !bU && !bR && bD)
dir = Direction.LD;
else if(!bL && !bU && !bR && !bD)
dir = Direction.STOP;
* Tank发射子弹
给子弹一个信号,,让子弹往自己指定的方向发子弹
private void fire(){
tc.times++;
int x = this.x + Tank.WIDTH/2 - Bullets.WIDTH/2;
int y = this.y + Tank.HEIGHT/2 - Bullets.HEIGHT/2;
Bullets b = new Bullets(x,y,ptDir,good,tc);
tc.myBullets.add(b);
else if(tc.times&30 && live){
tc.myBullets.add(b);
* 超级炮筒
private void superFire(){
Direction[] arr = dir.values();
for(int i = 0;i&8;i++){
fire(arr[i]);
tc.times += 4;
* 发射超级炮弹
* dir 不受炮筒方向控制的炮弹
private void fire(Direction dir){
int x = this.x + Tank.WIDTH/2 - Bullets.WIDTH/2;
int y = this.y + Tank.HEIGHT/2 - Bullets.HEIGHT/2;
Bullets b = new Bullets(x,y,dir,good,tc);
if(tc.times&30 && live){
tc.myBullets.add(b);
* 判断两个矩形是否相碰的方法
* 返回值在判断是否相碰会用到
public Rectangle getRect(){
return new Rectangle(x,y,WIDTH,HEIGHT);
* 判断是否撞墙
public void hitWall(Wall w){
if(live && this.getRect().intersects(w.getRect())){
public void hitTank(java.util.List&Tank& tanks){
for(int i = 0;i&tanks.size();i++){
Tank t = tanks.get(i);
if(this != t)
if(live && this.getRect().intersects(tanks.get(i).getRect())){
* 吃血块方法
public void eat(Blood b){
if(this.live && this.getRect().intersects(b.getRect())){
this.life = 100;
b.setLive(false);
private class BloodBar{
public void draw(Graphics g){
Color c = g.getColor();
g.setColor(Color.red);
g.drawRect(x, y-15, WIDTH, HEIGHT/4);
int width = WIDTH * life/100;
g.fillRect(x, y-15, width, HEIGHT/4);
g.setColor(c);
* 添加按键事件
class MyKeyEvent extends KeyAdapter{
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch(key){
case KeyEvent.VK_UP
: bU = true; break;
case KeyEvent.VK_DOWN
: bD = true; break;
case KeyEvent.VK_RIGHT : bR = true; break;
case KeyEvent.VK_LEFT
: bL = true; break;
case KeyEvent.VK_Q
: fire(); break;
case KeyEvent.VK_W
: superFire(); break;
case KeyEvent.VK_SPACE : tc.times = 0; break;
case KeyEvent.VK_F2
: if(!live) { live = true; life = 100;}
realDirection();
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
switch(key){
case KeyEvent.VK_UP
: bU = false; break;
case KeyEvent.VK_DOWN
: bD = false; break;
case KeyEvent.VK_RIGHT : bR = false; break;
case KeyEvent.VK_LEFT
: bL = false; break;
realDirection();
package _25增加配置文件;
import java.awt.C
import java.awt.G
import java.awt.I
import java.awt.T
public class Explode {
private int x ,
private boolean live = true;
private int step = 0;
private TankC
private static boolean
private static Toolkit tk = Toolkit.getDefaultToolkit();
private static Image[] image = {
tk.getImage(Explode.class.getClassLoader().getResource("images/0.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/1.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/2.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/3.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/4.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/5.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/6.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/7.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/8.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/9.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/10.gif"))
Explode(int x,int y,TankClient tc){
public void draw(Graphics g){
if(!init){
for (int i = 0; i& image. i++) {
g.drawImage(image[i], 100, 100, null);
init = true;
if(!live){
tc.explodes.remove(this);
if(step==11){
this.live = false;
this.step = 0;
g.drawImage(image[step++], x, y, null);
package _25增加配置文件;
* 方向的枚举
public enum Direction {
L, LU, U, RD, R, RU, D, LD, STOP
package _25增加配置文件;
import java.awt.*;
import java.util.HashM
import java.util.L
import java.util.M
public class Bullets {
private int x,y;
private boolean live = true;
public static final int WIDTH = 10, HEIGHT = 10;
private static final int XSPEED = 10,YSPEED = 10;
private TankC
private boolean
private static Toolkit tk = Toolkit.getDefaultToolkit();
private static Map&String,Image& imags = new HashMap&String,Image&();
private static Image[] tankImage = null;
tankImage = new Image[]{
tk.getImage(Explode.class.getClassLoader().getResource("images/missileL.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileLU.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileU.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileRD.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileR.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileRU.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileD.gif")),
tk.getImage(Explode.class.getClassLoader().getResource("images/missileLD.gif"))
imags.put("L", tankImage[0]);
imags.put("LU", tankImage[1]);
imags.put("U", tankImage[2]);
imags.put("RD", tankImage[3]);
imags.put("R", tankImage[4]);
imags.put("RU", tankImage[5]);
imags.put("D", tankImage[6]);
imags.put("LD", tankImage[7]);
public Bullets(int x,int y,Direction dir,boolean good,TankClient tc){
this.dir =
this.good =
public void draw(Graphics g){
if(!live){
tc.myBullets.remove(this);
Color c = g.getColor();
g.setColor(Color.black);
g.fillOval( x, y, WIDTH, HEIGHT);
g.setColor(c);
switch(dir){
g.drawImage(imags.get("L"),x, y, null); break;
g.drawImage(imags.get("LU"),x, y, null); break;
g.drawImage(imags.get("U"),x, y, null); break;
g.drawImage(imags.get("RD"),x, y, null); break;
g.drawImage(imags.get("R"),x, y, null); break;
g.drawImage(imags.get("RU"),x, y, null); break;
g.drawImage(imags.get("D"),x, y, null); break;
g.drawImage(imags.get("LD"),x, y, null); break;
case STOP :
g.drawImage(imags.get("STOP"),x, y, null); break;
private void move() {
switch(dir){
x-=XSPEED; break;
x-=XSPEED; y-=YSPEED; break;
y-=XSPEED; break;
x+=XSPEED; y+=YSPEED; break;
x+=XSPEED; break;
x+=XSPEED; y-=YSPEED; break;
y+=YSPEED; break;
x-=XSPEED; y+=YSPEED; break;
if(x&0 || y&0 || x&TankClient.WIDTH || y&TankClient.HEIGHT){
live = false;
public Rectangle getRect(){
return new Rectangle(x,y,WIDTH,HEIGHT);
public void hitTanks(List&Tank& tanks){
for(int i=0;i&tanks.size();i++)
hitTank(tanks.get(i));
public void hitTank(Tank t){
if(this.getRect().intersects(t.getRect()) && t.isLive() && this.good != t.isGood()){
if(t.isGood()){
t.setLife(t.getLife()-20);
if(t.getLife()&=0)
t.setLive(false);
t.setLive(false);
this.live = false;
Explode e = new Explode(x,y,tc);
tc.explodes.add(e);
public void hitWall(Wall w){
if(this.live && this.getRect().intersects(w.getRect())){
this.live = false;
package _25增加配置文件;
import java.awt.C
import java.awt.G
import java.awt.R
import java.util.R
public class Blood {
private int x ,y , w ,h;
private TankC
private boolean live = true;
private Random rand = new Random();
Blood(TankClient tc){
public boolean isLive() {
public void setLive(boolean live) {
this.live =
public void draw(Graphics g){
if(!live) return ;
x = rand.nextInt(tc.WIDTH/50)+600;
y = rand.nextInt(tc.HEIGHT/50)+150;
Color c = g.getColor();
g.setColor(Color.green);
g.fillRect(x, y, 20, 20);
g.setColor(c);
public Rectangle getRect(){
return new Rectangle(x, y, 20, 20);
package _25增加配置文件;
import java.awt.G
import java.awt.R
public class Wall {
private int x,y,w,h;
private TankC
public Wall(int x, int y, int w, int h, TankClient tc) {
public void draw(Graphics g){
g.fillRect(x, y, w, h);
public Rectangle getRect(){
return new Rectangle(x,y,w,h);
package _25增加配置文件;
import java.io.IOE
import java.util.P
* 使用配置文件,,采用了单例设计模式
public class GetProp {
private static Properties prop = new Properties();
prop.load(GetProp.class.getClassLoader().getResourceAsStream("config/tank.properties"));
} catch (IOException e1) {
e1.printStackTrace();
private GetProp(){}
public static String getProp(String key){
return prop.getProperty(key);
reTankCount=10
Java坦克大战 (七) 之图片版
本文来自:小易博客专栏。转载请注明出处:http://blog.csdn.net/oldinaction
在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样...
坦克大战java源码分析(上)
坦克大战java源码分析,源代码在本人的资源列表中,或查看本人的另外的博客,专门存放坦克大战源码
这篇博客适合新手参考,请勿嘲讽,本人也是在不断的学习中;错误请指正,十分感谢!...
java实现的坦克大战
《Java实现的坦克大战》
一.程序基本结构
二.实现的功能
1、单人模式
2、双人模式
3、通过深度优先算法实现的AI坦克寻路功能
4、局域网联机(半成品,以后补坑)
三.运行效果...
基于java的坦克大战实例
原创性声明
此博文的出处 为 http://blog.csdn.net/zhujunxxxxx/article/details/如果进行转载请注明出处。本文作者原创,邮箱zhujun...
《Java小游戏实现》:坦克大战
《Java小游戏实现》:坦克大战前面写了一个简单的聊天小程序,今天开始就写一个坦克大战的游戏,算是对Java相关小知识点的一个应用。这个游戏的完成,我们也是分步完成,逐步累加,一个一个小功能的添加,最...
*版权证明: 只允许上传png/jpeg/jpg/gif格式的图片,且小于3M
*详细原因:
交 &em&java实现坦克大战&/em& demo 3积分 立即下载 ...
学习一门编程语言入门,什么方法比较快,那肯定是跟着老师一起来找一个项目入手了,下面是java
坦克大战制作视频链接地址,该视频报包裹了本地版坦克大战,局域网版坦克大战,网络版坦克大战,有需求的同学可...
&em&坦克大战&/em&博客链接:http://blog.csdn.net/a/article/details/ 这是用eclipse开发,便于深入理解&em&java&/em&面向对象编程、swing界面编程、多线程编程。现在不...
坦克大战图片版
坦克大战图片版本文转自:小易博客专栏。http://blog.csdn.NET/oldinaction坦克大战效果图:
注意事项:
1、ProperMrg类中props.load(ProperMg...
java简单坦克大战制作代码
转载自:http://www.jb51.net/article/88317.htm
利用Java语言中的集合、Swing、线程等知识点编写一个坦克大战游戏。
(1) 画出敌我坦克的原理:
没有更多推荐了,

我要回帖

 

随机推荐