//血块类
public class Blood {
int x, y, w, h;//定义血块坐标变量,宽度、高度变量
TankClient tc; //生命坦克客户端变量
int step = 0;
private boolean live = true;//初始生命为true
//定义5个血块数组
private int[][] pos = {
{350, 300}, {360, 300}, {375, 275}, {400, 200}, {360, 270}, {365, 290}, {340, 280}
};
//血块构造函数
public Blood() {
x = pos[0][0];
y = pos[0][1];
w = h = 15;
}
//画出血块
public void draw(Graphics g) {
if(!live) return;
Color c = g.getColor();//对象c获取当前颜色
g.setColor(Color.MAGENTA);//设定血块颜色为洋红色
g.fillRect(x, y, w, h);//用洋红色填充矩形
g.setColor(c);
move();//调用move方法
}
//血块移动方法
private void move() {
step ++;
if(step == pos.length){
step = 0;
}
x = pos[step][0];
y = pos[step][1];
}
//看是否和子弹相碰撞
public Rectangle getRect() {
return new Rectangle(x, y, w , h);
}
//判断生存状态
public boolean isLive() {
return live;//返回生存状态
}
//设定生死状态
public void setLive(boolean live) {
this.live = live;
}
}
import java.awt.*;
//爆炸类
public class Explode {
int x, y; //定义爆炸坐标变量
private boolean live = true;//初始化生命为true
//引用坦克客户端对象
private TankClient tc ;
//定义并初始化半径数组
int[] diameter = {4, 7, 12, 18, 26, 32, 49, 30, 14, 6};
int step = 0;
//根据碰撞位置创建爆炸
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.explodes.remove(this);
return;
}
if(step == diameter.length) {
live = false;
step = 0;
return;
}
Color c = g.getColor();//对象c用来获取颜色
g.setColor(Color.ORANGE);//设定爆炸颜色为桔黄色
g.fillOval(x, y, diameter[step], diameter[step]);//用桔黄色填充圆
g.setColor(c);
step ++;
}
}
import java.awt.*;
import java.util.List;
//子弹类
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;//子弹高度变量
int x, y;//子弹坐标
Tank.Direction dir;//子弹方向
//子弹生死状态变量
private boolean good;//设定敌我双方判断标志
private boolean live = true;//判断是否存活
//坦克客户对象
private TankClient tc;
//子弹构造函数
public Missile(int x, int y, Tank.Direction dir) {
this.x = x;
this.y = y;
this.dir = dir;
}
//重写构造函数
public Missile(int x, int y, boolean good, Tank.Direction dir, TankClient tc) {
this(x, y, dir);
this.good = good;
this.tc = tc;
}
//在窗体上画出子弹
public void draw(Graphics g) {
if(!live) {
tc.missiles.remove(this);
return;
}//如果子弹死了,则不画出
Color c = g.getColor();//获取颜色
g.setColor(Color.BLACK);//设置子弹颜色为黑色
g.fillOval(x, y, WIDTH, HEIGHT);//用黑色填充圆
g.setColor(c);
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;
case STOP:
break;
}
//判断子弹是否出界,若出则去掉
if(x < 0 || y < 0 || x > TankClient.GAME_WIDTH || y > TankClient.GAME_HEIGHT) {
live = false;
}
}
//判断子弹生存状态
public boolean isLive() {
return live;//返回子弹生存状态
}
//获取子弹外围坐标
public Rectangle getRect() {
return new Rectangle(x, y, WIDTH, HEIGHT);
}
//打坦克函数
public boolean hitTank(Tank t) {
if(this.live && this.getRect().intersects(t.getRect()) && t.isLive() && this.good != t.isGood()) { //每中一次弹生命值减少20
if(t.isGood()) {
t.setLife(t.getLife()-20);
if(t.getLife() <= 0) t.setLive(false);//坦克没血了则没生命
} else {
t.setLive(false);
}
this.live = false;
Explode e = new Explode(x, y, tc);//创建一个爆炸e对象
tc.explodes.add(e);//添加到爆炸容器中
return true;
}
return false;
}
//依次判断所有敌方坦克是否被子弹击中
public boolean hitTanks(List for(int i=0; i return true; } } return false; } //判断子弹是否击中墙 public boolean hitWall(Wall w) { if(this.live && this.getRect().intersects(w.getRect())) { this.live = false; return true; } return false; } } import java.awt.*; import java.awt.event.*; import java.util.*; //定义坦克类 public class Tank { public static final int XSPEED = 5; //坦克水平速度 public static final int YSPEED = 5; //坦克垂直速度 public static final int WIDTH = 30; //坦克宽度 public static final int HEIGHT = 30; //坦克高度 private boolean live = true; //初始化生命为true private BloodBar bb = new BloodBar();//声明血块变量 private int life = 100; //初始化生命值为100 TankClient tc;//生命坦克客户端变量 private boolean good;//设置区分敌我两方标志 private int x, y; //声明两个整型私有变量x,y坐标 private int oldX, oldY;//记录上一步的坐标 private static Random r = new Random(); //创建一个随机数r对象 //声明方向变量 private boolean bL=false, bU=false, bR=false, bD = false; enum Direction {L, LU, U, RU, R, RD, D, LD, STOP};/*坦克的八个方向和一个stop状态*/ private Direction dir = Direction.STOP; private Direction ptDir = Direction.D; private int step = r.nextInt(12) + 3;//整数step在[3,14]间随机取值 //构造方法 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) { if(!good) { tc.tanks.remove(this); } return; } Color c = g.getColor();//获取颜色 if(good) g.setColor(Color.RED);//我方坦克颜色设置为红色 else g.setColor(Color.BLUE); g.fillOval(x, y, WIDTH, HEIGHT); g.setColor(c); //画出子弹 if(good) bb.draw(g); switch(ptDir) { case L: g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y + Tank.HEIGHT/2); break; case LU: g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y); break; case U: g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH/2, y); break; case RU: g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y); break; case R: g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y + Tank.HEIGHT/2); break; case RD: g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y + Tank.HEIGHT); break; case D: g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH/2, y + Tank.HEIGHT); break; case LD: g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y + Tank.HEIGHT); break; } move(); } //移动方法 void move() { //记录上一次坐标 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; } if(this.dir != Direction.STOP) { this.ptDir = this.dir; } //控制坦克不出界 if(x < 0) x = 0; if(y < 30) y = 30; if(x + Tank.WIDTH > TankClient.GAME_WIDTH) x = TankClient.GAME_WIDTH - Tank.WIDTH; if(y + Tank.HEIGHT > TankClient.GAME_HEIGHT) y = TankClient.GAME_HEIGHT - Tank.HEIGHT; if(!good) { Direction[] dirs = Direction.values(); if(step == 0) { step = r.nextInt(12) + 3; int rn = r.nextInt(dirs.length);//改变方向 dir = dirs[rn]; } step --; if(r.nextInt(40) > 38) this.fire(); } } private void stay() { x = oldX; y = oldY; } //键按下的消息处理 public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); switch(key) { case KeyEvent.VK_Q : if(!this.live) { this.live = true; this.life = 100; } break; 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(); } //设定方向 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; } //键抬起的消息处理 public void keyReleased(KeyEvent e) { int key = e.getKeyCode(); switch(key) { case KeyEvent.VK_CONTROL: fire(); break; 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; case KeyEvent.VK_A ://按下A开火 superFire(); break; } locateDirection(); } //开火发射方法 public Missile fire() { if(!live) return null; int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2; int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2; Missile m = new Missile(x, y, good, ptDir, this.tc); tc.missiles.add(m); return m; } public Missile fire(Direction dir) { if(!live) return null; int x = this.x + Tank.WIDTH/2 - Missile.WIDTH/2; int y = this.y + Tank.HEIGHT/2 - Missile.HEIGHT/2; Missile m = new Missile(x, y, good, dir, this.tc); tc.missiles.add(m); return m; } //看坦克是否与子弹碰撞 public Rectangle getRect() { return new Rectangle(x, y, WIDTH, HEIGHT); } //判断坦克是否还活着 public boolean isLive() { return live; } //设定坦克的生死状态 public void setLive(boolean live) { this.live = live; } //判断坦克状态是否良好 public boolean isGood() { return good; } //坦克与墙相撞 public boolean collidesWithWall(Wall w) { if(this.live && this.getRect().intersects(w.getRect())) { this.stay(); return true; } return false; } //坦克与坦克相撞 public boolean collidesWithTanks(java.util.List for(int i=0; i if(this != t) { if(this.live && t.isLive() && this.getRect().intersects(t.getRect())) { this.stay(); t.stay(); return true; } } } return false; } //发射超级子弹 private void superFire() { Direction[] dirs = Direction.values(); for(int i=0; i<8; i++) { fire(dirs[i]); } } //返回坦克的生命值 public int getLife() { return life; } //设置坦克的生命值 public void setLife(int life) { this.life = life; } //创建生命值 private class BloodBar { //在坦克上方画出生命条 public void draw(Graphics g) { Color c = g.getColor(); g.setColor(Color.RED); g.drawRect(x, y-10, WIDTH, 10); int w = WIDTH * life/100 ; g.fillRect(x, y-10, w, 10); g.setColor(c); } } //判断坦克是否吃到东西 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; } } import java.awt.*; import java.awt.event.*; import java.util.List; import java.util.ArrayList; //坦克游戏的窗体类 public class TankClient extends Frame { //定义窗口宽高 public static final int GAME_WIDTH = 800; public static final int GAME_HEIGHT = 600; //声明一个自己坦克的对象 Tank myTank = new Tank(50, 50, true, Tank.Direction.STOP, this); //声明两个墙变量 Wall w1 = new Wall(100, 200, 20, 150, this), w2 = new Wall(300, 100, 300, 20, this); List List List Image offScreenImage = null; Blood b = new Blood();//创建一个血块对象 //画方法 public void paint(Graphics g) { //左上角显示的有关游戏的相关信息 g.drawString("missiles count:" + missiles.size(), 10, 50);//子弹数 g.drawString("explodes count:" + explodes.size(), 10, 70);//爆炸数 g.drawString("tanks count:" + tanks.size(), 10, 90);//坦克数 g.drawString("tanks life:" + myTank.getLife(), 10, 110);//坦克生命 //画出爆炸 if(tanks.size() <= 0) { for(int i=0; i<5; i++) { tanks.add(new Tank(50 + 40*(i+1), 50, false, Tank.Direction.D, this)); } } //画出子弹 for(int i=0; i m.hitTanks(tanks);//打敌人 m.hitTank(myTank);//被敌人打 m.hitWall(w1);//撞墙 m.hitWall(w2); m.draw(g); //if(!m.isLive()) missiles.remove(m); //else m.draw(g); } for(int i=0; i e.draw(g); } for(int i=0; i t.collidesWithWall(w1); t.collidesWithWall(w2);//坦克撞到墙 t.collidesWithTanks(tanks);//坦克相撞 t.draw(g); } myTank.draw(g);//画出坦克 myTank.eat(b); w1.draw(g);//画出墙 w2.draw(g); b.draw(g); } //双缓存消除闪烁 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(Color.GREEN); gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT); gOffScreen.setColor(c); paint(gOffScreen); g.drawImage(offScreenImage, 0, 0, null); } //启动窗口 public void lauchFrame() { //画出坦克 for(int i=0; i<10; i++) { tanks.add(new Tank(50 + 40*(i+1), 50, false, Tank.Direction.D, this)); } //this.setLocation(400, 300); this.setSize(GAME_WIDTH, GAME_HEIGHT); this.setTitle("TankWar"); this.addWindowListener(new WindowAdapter() //处理窗口的关闭 { public void windowClosing(WindowEvent e) { System.exit(0); } }); this.setResizable(false);//设置窗口大小固定 this.setBackground(Color.GREEN);//窗口背景颜色为绿色 this.addKeyListener(new KeyMonitor()); setVisible(true); new Thread(new PaintThread()).start(); } public static void main(String[] args) { TankClient tc = new TankClient();//创建一个窗体 tc.lauchFrame(); } //内部类新起一线程控制坦克移动 private class PaintThread implements Runnable { public void run() { while(true) { repaint(); try { Thread.sleep(50);//每隔50ms,坦克移动一下(重画一下) } catch (InterruptedException e) { e.printStackTrace(); } } } } //增加键盘监听 private class KeyMonitor extends KeyAdapter { //键盘抬起 public void keyReleased(KeyEvent e) { myTank.keyReleased(e); } //键盘按下 public void keyPressed(KeyEvent e) { myTank.keyPressed(e); } } } import java.awt.*; //墙类 public class Wall { int x, y, w, h;//坐标,长,宽 TankClient tc ;//坦克客户对象 //根据墙左上角坐标,宽度,高度创建墙 public Wall(int x, int y, int w, int h, TankClient tc) { this.x = x; this.y = y; this.w = w; this.h = h; this.tc = tc; } //在窗体中画出墙 public void draw(Graphics g) { g.fillRect(x, y, w, h); } //返回墙的矩形碰撞区域 public Rectangle getRect() { return new Rectangle(x, y, w, h); } }下载本文