TankClient.java
Tank.java
Missile.java
Explode.java
Wall.java
package tungkee.javase.project.tankwar;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
/**
* 这个类是坦克游戏的主窗口,2011-07-10
* @author tungkee
*
*/
public class TankClient extends Frame {
/**
* 定义我方坦克的变量
*/
private Tank myTank = null;
/**
* 定义虚拟的屏幕图片,用双缓冲解决屏幕闪烁问题
*/
private Image offScreenImage = null;
/**
* 定义三个集合List,装敌方坦克,子弹,爆炸等
*/
private List<Tank> tanks = new ArrayList<Tank>();
private List<Missile> missiles = new ArrayList<Missile>();
private List<Explode> explodes = new ArrayList<Explode>();
/**
* 定义四堵墙,分别置于游戏主窗口的左、右、上、下四个位置
*/
private Wall leftWall = new Wall(200, 200, 50, 400, this);
private Wall rightWall = new Wall(800, 200, 50, 400, this);
private Wall upWall = new Wall(300, 200, 400, 50, this);
private Wall downWall = new Wall(300, 600, 400, 50, this);
/**
* 定义血块,血块按照自身的不规则轨迹进行运动
*/
private Blood b = new Blood(this);
/**
* 定义控制游戏主窗口刷新的线程停止或运行的变量
*/
private boolean threadFlag = true;
/**
* 定义主窗口刷新的线程变量
*/
private Thread thread = null;
/**
* 整个游戏的高度的静态常量
*/
public static final int GAME_WIDTH = 1024;
/**
* 整个游戏的宽度的静态常量
*/
public static final int GAME_HEIGHT = 768;
/**
* 游戏的背景颜色和游戏的标题栏的文字
*/
public static final Color GAME_BACKGROUND = new Color(0, 100, 0);
public static final String GAME_TITLE = "TankWar坦克大战单机版";
/**
* 定义坦克在游戏界面中的最大x 和最大y 值
*/
public static final int Tank_MaxX = GAME_WIDTH - Tank.WIDTH;
public static final int Tank_MaxY = GAME_HEIGHT - Tank.HEIGHT;
/**
* 添加子弹对象到List中的方法,没有返回值。
* @param missile 需要添加的子弹对象引用
*/
public void addMissile(Missile missile) {
missiles.add(missile);
}
/**
* 从List中移除子弹对象的方法,没有返回值
* @param missile 需要移除的子弹对象引用
*/
public void removeMissile(Missile missile) {
missiles.remove(missile);
}
/**
* 添加爆炸对象到List中的方法,没有返回值
* @param explode 需要添加爆炸的对象引用
*/
public void addExplode(Explode explode) {
explodes.add(explode);
}
/**
* 从List中移除爆炸对象的方法,没有返回值
* @param explode 需要移除爆炸的对象引用
*/
public void removeExplode(Explode explode) {
explodes.remove(explode);
}
/**
* main方法,创建一个TankClient对象,调用其launchFrame方法
* @param args 命令行参数
*/
public static void main(String[] args) {
TankClient tc = new TankClient();
tc.launchFrame();
}
/**
* 从List中移除一个坦克的方法,没有返回值
* @param tank 需要移除的坦克的对象的引用
*/
public void removeTank(Tank tank) {
tanks.remove(tank);
}
/**
* 创建敌方坦克的方法,没有返回值
* @param tankCount 创建敌方坦克的数量
*/
private void createTanks(int tankCount) {
Tank tank = null;
for(int i=0; i<tankCount; i++) {
do {
tank = createTank(false, Tank.Direction.D);
} while(tank == null);
tanks.add(tank);
}
}
/**
* 创建一辆坦克的方法
* @param good 设置为我方坦克还是敌方坦克,true为我方,false为敌方
* @param dir 设置坦克初始的方向
* @return 返回一辆坦克对象的引用
*/
public Tank createTank(boolean good, Tank.Direction dir) {
int x = 0;
int y = 0;
Tank tank = null;
x = (int)(Math.random() * Tank_MaxX);
y = (int)(Math.random() * Tank_MaxY);
tank = new Tank(x, y, good, dir, this);
//当前创建的坦克与四堵墙进行碰撞检测,并且与坦克集合中的每一辆坦克进行
//碰撞检测,没有重叠则返回坦克的对象的引用,否则返回null。
if(!tank.collidesWithWall(leftWall)
&& !tank.collidesWithWall(rightWall)
&& !tank.collidesWithWall(upWall)
&& !tank.collidesWithWall(downWall)
&& !tank.collidesWithTanks(tanks)) {
return tank;
}
return null;
}
/**
* TankClient的launchFrame方法,用于启动游戏主窗体
*/
public void launchFrame() {
this.setTitle(GAME_TITLE);
this.setBackground(GAME_BACKGROUND);
this.setSize(GAME_WIDTH, GAME_HEIGHT);
this.setLocation(50, 50);
this.setResizable(false);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
if(myTank != null) {
myTank = null;
}
tanks = null;
missiles = null;
explodes = null;
threadFlag = false;
try {
thread.join();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.exit(0);
}
});
this.addKeyListener(new KeyMonitor());
this.setVisible(true);
//创建出我方坦克以后添加到List中,这样方便增加敌方坦克时
//可以和我方坦克进行碰撞检测,以免坦克叠加在一起
myTank = createTank(true, Tank.Direction.STOP);
tanks.add(myTank);
//创建敌方坦克
createTanks(10);
//碰撞检测完成以后从List中移除我方坦克
tanks.remove(myTank);
//设置主线程睡眠1秒以后再启动刷新游戏界面的线程
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//创建并启动刷新游戏界面的线程
thread = new Thread(new PaintThread());
thread.start();
}
/**
* 复写了父类的paint方法,以便画出游戏元素
*/
@Override
public void paint(Graphics g) {
/*
* 指明子弹的数量、爆炸的数量、敌方坦克的数量、我方坦克的生命值
*/
Color c = g.getColor();
g.setColor(Color.BLACK);
g.drawString("ArrayList<Tank>:" + tanks.size(), 10, 40);
g.drawString("ArrayList<Missile>:" + missiles.size(), 10, 60);
g.drawString("ArrayList<Explode>:" + explodes.size(), 10, 80);
g.drawString("myTank.getLife():" + myTank.getLife(), 10, 100);
g.setColor(c);
if(leftWall != null) leftWall.draw(g);
if(rightWall != null) rightWall.draw(g);
if(upWall != null) upWall.draw(g);
if(downWall != null) downWall.draw(g);
if(myTank != null) {
if(myTank.isLive()) {
myTank.draw(g);
//我方坦克与四堵墙进行碰撞检测,以避免坦克穿越墙
myTank.collidesWithWall(leftWall);
myTank.collidesWithWall(rightWall);
myTank.collidesWithWall(upWall);
myTank.collidesWithWall(downWall);
//我方坦克与坦克集合中的每辆坦克进行碰撞检测,以避免穿越其他坦克
myTank.collidesWithTanks(tanks);
//我方坦克吃血块
if(b != null) {
if(myTank.eat(b)) {
b = null;
}
}
} else {
myTank = null;
}
}
Tank tank = null;
for(int i=0; i<tanks.size(); i++) {
tank = tanks.get(i);
tank.draw(g);
tank.collidesWithWall(leftWall);
tank.collidesWithWall(rightWall);
tank.collidesWithWall(upWall);
tank.collidesWithWall(downWall);
tank.collidesWithTanks(tanks);
tank.collidesWithTank(myTank);
}
Missile missile = null;
for(int i=0; i<missiles.size(); i++) {
missile = missiles.get(i);
missile.draw(g);
missile.hitTanks(tanks);
missile.hitTank(myTank);
missile.hitWall(leftWall);
missile.hitWall(rightWall);
missile.hitWall(upWall);
missile.hitWall(downWall);
}
for(int i=0; i<explodes.size(); i++) {
explodes.get(i).draw(g);
}
if(b != null) b.draw(g);
}
/**
* 复写了父类的update方法,以便解决游戏闪烁问题
*/
@Override
public void update(Graphics g) {
//使用双缓冲解决游戏界面闪烁的问题
//解决方式是先将所有的元素画在虚拟的屏幕图片上,然后再一次性的贴在屏幕上
if(offScreenImage == null) {
offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT);
}
Graphics gOffScreen = offScreenImage.getGraphics();
Color c = gOffScreen.getColor();
gOffScreen.setColor(GAME_BACKGROUND);
gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
gOffScreen.setColor(c);
paint(gOffScreen);
g.drawImage(offScreenImage, 0, 0, null);
}
/**
* 定义了内部类PaintThread,用于每隔50毫秒对游戏画面进行刷新重画
* @author tungkee
*
*/
private class PaintThread implements Runnable {
@Override
public void run() {
try {
while(threadFlag) {
repaint();
Thread.sleep(50);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 定义键盘响应的监听器类
* @author tungkee
*
*/
private class KeyMonitor extends KeyAdapter {
@Override
public void keyReleased(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_F2:
if(tanks.size() == 0) createTanks(10);
break;
case KeyEvent.VK_F3:
if(myTank == null) {
myTank = createTank(true, Tank.Direction.STOP);
}
break;
default:
myTank.keyReleased(e);
break;
}
}
@Override
public void keyPressed(KeyEvent e) {
myTank.keyPressed(e);
}
}
}
Tank.java
package tungkee.javase.project.tankwar;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.List;
public class Tank {
/**
* 定义坦克的x方向移动速度、y方向移动速度、坦克的宽度以及坦克的高度
*/
public static final int XSPEED = 5;
public static final int YSPEED = 5;
public static final int WIDTH = 30;
public static final int HEIGHT = 30;
//定义坦克主窗体的对象的引用以及x、y的坐标
private TankClient tc = null;
private int x = 0;
private int y = 0;
//记录坦克上一个位置的x、y坐标
private int oldX = 0, oldY = 0;
//定义枪口的点以及发子弹的点
private Point barrel = null;
private Point gun = null;
//记录用户按键,用来确定用户需要坦克改变为哪个方向
private boolean bL = false, bU = false, bR = false, bD = false;
//定义坦克是否处于活着的状态
private boolean live = true;
//定义坦克的方向的枚举类型
enum Direction {L, LU, U, RU, R, RD, D, LD, STOP};
//定义坦克的方向
private Direction dir = Direction.STOP;
//定义炮筒的方向
private Direction barrelDir = Direction.D;
//定义坦克是我方坦克还是敌方坦克
private boolean good = false;
//定义随机数,引用了随机数的类
private static Random r = new Random();
//定义坦克随机行走的步数,在10-20之间产生
private int step = r.nextInt(20) + 10;
//定义坦克的生命值
private int life = 100;
//定义坦克的血条
private BloodBar bb = null;
public boolean isGood() {
return good;
}
public Tank(int x, int y, boolean good) {
this.x = x;
this.y = y;
this.oldX = x;
this.oldY = y;
this.good = good;
}
public Tank(int x, int y, boolean good, Direction dir, TankClient tc) {
this(x, y, good);
this.dir = dir;
this.tc = tc;
}
public void draw(Graphics g) {
//如果坦克已经处于未活着的状态,则不对该坦克进行重画
if(live == false) {
if(! good) {
//如果该坦克对象good为false,则从List中移除它
tc.removeTank(this);
}
return;
}
Color color = g.getColor();
if(good) {
//画血条
bb = new BloodBar();
bb.draw(g);
//设置我方坦克颜色为白色
g.setColor(Color.WHITE);
} else {
//设置敌方坦克颜色为红色
g.setColor(Color.RED);
}
//画坦克的机身,用一个圆来模拟
g.fillOval(x, y, WIDTH, HEIGHT);
g.setColor(Color.BLACK);
g.setColor(color);
//计算确定坦克的枪口的点的位置以及发子弹的点的位置
sureBarrelGun();
//从坦克的机身的圆的中心点到枪口点的位置,画一条直线模拟坦克的枪管
g.drawLine(x + WIDTH / 2, y + HEIGHT / 2, barrel.x, barrel.y);
//坦克的移动方法
move();
}
/**
* 确定枪口的点以及发子弹的点的位置
* 因为需要让子弹从枪口的正中发出
*/
private void sureBarrelGun() {
if(dir != Direction.STOP) {
barrelDir = dir;
}
switch(barrelDir) {
case L:
barrel = new Point(x, y + HEIGHT / 2);
gun = new Point(barrel.x - Missile.WIDTH, barrel.y - Missile.HEIGHT / 2);
break;
case LU:
barrel = new Point(x, y);
gun = new Point(barrel.x - Missile.WIDTH, barrel.y - Missile.HEIGHT);
break;
case U:
barrel = new Point(x + WIDTH / 2, y);
gun = new Point(barrel.x - Missile.WIDTH / 2, barrel.y);
break;
case RU:
barrel = new Point(x + WIDTH, y);
gun = new Point(barrel.x, barrel.y - Missile.HEIGHT);
break;
case R:
barrel = new Point(x + WIDTH, y + HEIGHT / 2);
gun = new Point(barrel.x, barrel.y - Missile.HEIGHT / 2);
break;
case RD:
barrel = new Point(x + WIDTH, y + HEIGHT);
gun = new Point(barrel.x, barrel.y);
break;
case D:
barrel = new Point(x + WIDTH / 2, y + HEIGHT);
gun = new Point(barrel.x - Missile.WIDTH / 2, barrel.y);
break;
case LD:
barrel = new Point(x, y + HEIGHT);
gun = new Point(barrel.x - Missile.WIDTH, barrel.y);
break;
}
}
/**
* 坦克移动的方法
*/
private void move() {
//记录移动之前坦克的点的x、y的值
//以便坦克移动到墙边以后能够回到上一次的位置
//因为坦克与墙的碰撞检测中设定,当坦克与墙碰撞、
//成功以后,坦克就停止移动,如果不记录坦克的上一次位置
//坦克就无法回到上一次位置,就一直处于与墙碰撞成功
//的死循环中
//同时也用与坦克与坦克之间的碰撞后停止并返回到上一次移动的位置
this.oldX = x;
this.oldY = y;
switch(dir) {
case L:
x -= XSPEED;
break;
case LU:
x -= XSPEED;
y -= YSPEED;
break;
case U:
y -= YSPEED;
break;
case RU:
x += XSPEED;
y -= YSPEED;
break;
case R:
x += XSPEED;
break;
case RD:
x += XSPEED;
y += YSPEED;
break;
case D:
y += YSPEED;
break;
case LD:
x -= XSPEED;
y += YSPEED;
break;
case STOP:
break;
}
/*
* 判断坦克当前的x值是否大于游戏主窗体中设定的坦克的最大x值
* 大于则将坦克的x值设置为最大的x值
*/
if(x > TankClient.Tank_MaxX) {
x = TankClient.Tank_MaxX;
}
/*
* 判断坦克的x值是否小于0,如果小于0则将其值设置为0
*/
if(x < 0) {
x = 0;
}
/*
* 判断坦克当前的y值是否大于游戏主窗体中设定的坦克的最大y值
* 如果大于则将坦克的y值设置为最大的y值
*/
if(y > TankClient.Tank_MaxY) {
y = TankClient.Tank_MaxY;
}
/*
* 判断坦克的y值是否小于0,如果小于0则将其值设置为0
*/
if(y < 20) {
y = 20;
}
/*
* 如果当前坦克的good为false
* 判断当前的移动步数是否等于0,如果等于0重新获得随机获得坦克移动的方向
* 同时随机获得坦克移动的步数
* 最后坦克移动的步数自减1
* 然后随机产生一个0-50之间的数,如果这个数大于47则坦克开火
*/
if(!good) {
Direction[] dirs = Direction.values();
if(step == 0) {
step = r.nextInt(20) + 10;
int rn = r.nextInt(dirs.length);
dir = dirs[rn];
}
step --;
if(r.nextInt(50) > 47) this.fire();
}
}
/**
* 让坦克移动到上一次的位置的方法
*/
public void stay() {
this.x = oldX;
this.y = oldY;
}
/**
* 处理按键事件以便确定坦克当前应该改变的方向,keyPressed
* @param e
*/
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_LEFT:
bL = true;
break;
case KeyEvent.VK_UP:
bU = true;
break;
case KeyEvent.VK_RIGHT:
bR = true;
break;
case KeyEvent.VK_DOWN:
bD = true;
break;
}
locateDirection();
}
/**
* 坦克开火的方法
*/
public void fire() {
Missile m = new Missile(gun.x, gun.y, barrelDir, good, tc);
tc.addMissile(m);
}
/**
* 指定一个方向,让坦克朝指定的方向开火的方法
* @param dir 指定坦克开火的方向
*/
public void fire(Direction dir) {
Missile m = new Missile(gun.x, gun.y, dir, good, tc);
tc.addMissile(m);
}
/**
* 坦克朝八个方向开火的方法
*/
public void superFire(){
Direction[] dirs = Direction.values();
for(int i=0; i<dirs.length; i++) {
if(dirs[i] != Direction.STOP) fire(dirs[i]);
}
}
/**
* 定位坦克的方法的方法
*/
private void locateDirection() {
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.RU;
else if(!bL && !bU && bR && !bD) dir = Direction.R;
else if(!bL && !bU && bR && bD) dir = Direction.RD;
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;
}
/**
* 处理keyReleased事件
* @param e
*/
public void keyReleased(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_CONTROL:
fire();
break;
case KeyEvent.VK_LEFT:
bL = false;
break;
case KeyEvent.VK_UP:
bU = false;
break;
case KeyEvent.VK_RIGHT:
bR = false;
break;
case KeyEvent.VK_DOWN:
bD = false;
break;
case KeyEvent.VK_A:
superFire();
break;
}
locateDirection();
}
/**
* 获得坦克自身的矩形的方法,以便进行碰撞检测
* @return
*/
public Rectangle getRect() {
return new Rectangle(x, y, WIDTH, HEIGHT);
}
public void setLive(boolean live) {
this.live = live;
}
public boolean isLive() {
return live;
}
/**
*
* @param wall 被撞的墙
* @return 被撞后返回true,未被撞返回false
*/
public boolean collidesWithWall(Wall wall) {
if(this.live && this.getRect().intersects(wall.getRect())) {
this.stay();
return true;
}
return false;
}
/**
* 与其他一辆坦克进行碰撞检测
* @param tank 需要进行碰撞检测的坦克对象引用
* @return 碰撞成功返回true,否则返回false
*/
public boolean collidesWithTank(Tank tank) {
if(this != tank) {
if(this.live && tank.isLive() && this.getRect().intersects(tank.getRect())) {
this.stay();
tank.stay();
return true;
}
}
return false;
}
/**
* 与一个List集合中的坦克进行碰撞检测
* @param tanks 需要进行碰撞检测的坦克集合
* @return 碰撞成功返回true,否则返回false
*/
public boolean collidesWithTanks(List<Tank> tanks) {
for(int i =0; i<tanks.size(); i++) {
if(this.collidesWithTank(tanks.get(i))) {
return true;
}
}
return false;
}
public void setLife(int life) {
this.life = life;
}
public int getLife() {
return life;
}
/**
* 定义血条的内部类
* @author tungkee
*
*/
private class BloodBar {
private int width = Tank.WIDTH;
private int height = 10;
public void draw(Graphics g) {
Color c = g.getColor();
g.setColor(Color.RED);
g.drawRect(x, y - height, width, height);
g.fillRect(x, y - height, width * life / 100, height);
g.setColor(c);
}
}
/**
* 定义坦克吃血条的方法,同样采用矩形碰撞检测的技术
* @param b 被吃的血条
* @return 被吃后返回true,否则返回false
*/
public boolean eat(Blood b) {
if(this.live && b.isLive() && this.getRect().intersects(b.getRect())) {
this.life = 100;
b.setLive(false);
return true;
}
return false;
}
}
Missile.java
package tungkee.javase.project.tankwar;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.List;
import tungkee.javase.project.tankwar.Tank.Direction;
public class Missile {
public static final int XSPEED = 10;
public static final int YSPEED = 10;
public static final int WIDTH = 10;
public static final int HEIGHT = 10;
private Direction dir = Direction.STOP;
private TankClient tc = null;
private int x = 0;
private int y = 0;
private boolean live = true;
private boolean good = true;
public Missile(int x, int y, Direction dir) {
this.x = x;
this.y = y;
this.dir = dir;
}
public Missile(int x, int y, Direction dir, boolean good, TankClient tc) {
this(x, y, dir);
this.good = good;
this.tc = tc;
}
public void draw(Graphics g) {
if(live == false) {
tc.removeMissile(this);
return;
}
Color color = g.getColor();
if(!good) {
g.setColor(Color.RED);
} else {
g.setColor(Color.WHITE);
}
g.fillOval(x, y, WIDTH, HEIGHT);
g.setColor(color);
move();
}
private void move() {
switch(dir) {
case L:
x -= XSPEED;
break;
case LU:
x -= XSPEED;
y -= YSPEED;
break;
case U:
y -= YSPEED;
break;
case RU:
x += XSPEED;
y -= YSPEED;
break;
case R:
x += XSPEED;
break;
case RD:
x += XSPEED;
y += YSPEED;
break;
case D:
y += YSPEED;
break;
case LD:
x -= XSPEED;
y += YSPEED;
break;
}
if(x < 0 || x > TankClient.GAME_WIDTH || y < 0 || y > TankClient.GAME_HEIGHT) {
this.live = false;
}
}
public boolean isLive() {
return live;
}
public Rectangle getRect() {
return new Rectangle(x, y, WIDTH, HEIGHT);
}
public boolean hitTank(Tank tank) {
if(this.live && tank.isLive() && this.good != tank.isGood() && this.getRect().intersects(tank.getRect())) {
if(tank.isGood()) {
tank.setLife(tank.getLife() - 20);
if(tank.getLife() == 0) tank.setLive(false);
} else {
tank.setLive(false);
}
tc.addExplode(new Explode(x, y, tc));
this.live = false;
return true;
}
return false;
}
public boolean hitTanks(List<Tank> tanks) {
for(int i=0; i<tanks.size(); i++) {
if(this.hitTank(tanks.get(i))) {
return true;
}
}
return false;
}
public boolean hitWall(Wall wall) {
if(this.live && this.getRect().intersects(wall.getRect())) {
this.live = false;
return true;
}
return false;
}
}
Blood.java
package tungkee.javase.project.tankwar;
import java.awt.*;
public class Blood {
private int x, y, w, h;
private boolean live = true;
private TankClient tc = null;
//指明血块运动的轨迹,由pos中各个点构成
private int[][] pos = {
{200,100},{210,200},{220,230},{300,400},{100,300},{50,250},{100,200},{150,150}
};
private int step = 0;
public Blood(TankClient tc) {
x = pos[0][0];
y = pos[0][1];
w = h = 15;
this.tc = tc;
}
public void draw(Graphics g) {
Color c = g.getColor();
g.setColor(Color.MAGENTA);
g.fillRect(x, y, w, h);
g.setColor(c);
move();
}
private void move() {
step ++;
if(step == pos.length) {
step = 0;
}
x = pos[step][0];
y = pos[step][1];
}
public boolean isLive() {
return live;
}
public void setLive(boolean live) {
this.live = live;
}
public Rectangle getRect() {
return new Rectangle(x, y, w, h);
}
}
Explode.java
package tungkee.javase.project.tankwar;
import java.awt.*;
public class Explode {
private int x = 0, y = 0;
private TankClient tc = null;
private int[] diameter = {4, 7, 12, 16, 32, 40, 49, 30, 16, 10, 6};
private int step = 0;
private boolean live = true;
public Explode(int x, int y, TankClient tc) {
this.x = x;
this.y = y;
this.tc = tc;
}
public void draw(Graphics g) {
if(! live) {
tc.removeExplode(this);
return;
}
if(step == diameter.length) {
live = false;
step = 0;
}
Color color = g.getColor();
g.setColor(Color.ORANGE);
g.fillOval(x - diameter[step] / 2, y - diameter[step] / 2, diameter[step], diameter[step]);
g.setColor(color);
step ++;
}
}
Wall.java
package tungkee.javase.project.tankwar;
import java.awt.*;
public class Wall {
private int x, y;
private int width, height;
private TankClient tc;
public Wall(int x, int y, int width, int height, TankClient tc) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.tc = tc;
}
public void draw(Graphics g) {
Color c = g.getColor();
g.setColor(Color.BLACK);
g.fillRect(x, y, width, height);
g.setColor(c);
}
public Rectangle getRect() {
return new Rectangle(x, y, width, height);
}
}