package mzxmzx; |
import java.awt.*; |
import java.awt.event.*; |
import java.util.Random; |
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 ; //返回布尔类型,判断坦克的生死 |
private int life = 100 ; |
private BloodBar bb = new BloodBar(); //BloodBar一个bb出来 |
public int getLife() { |
return life; |
} |
public void setLife( int life) { |
this .life = life; |
} |
TankClient tc; |
|
private boolean good; //定义一个布尔变量,判断敌我坦克 |
|
public boolean isGood() { |
return good; |
} |
private int x, y; |
private int oldX,oldY; |
private void stay(){ //坦克撞到墙之后定义为stay |
x = oldX; |
y = oldY; |
} |
|
private static Random r = new Random(); |
|
private boolean bL= false , bU= false , bR= false , bD = false ; //用4个布尔类型的值代表是不是按下了4个键,当按下某个键时由FALSE变成true |
enum Direction {L, LU, U, RU, R, RD, D, LD, STOP}; //枚举 |
|
private int step = r.nextInt( 12 ) + 3 ; //最小值至少移动3步,最大值移动到14步 |
private Direction dir = Direction.STOP; //给默认值为STOP |
private Direction ptDir = Direction.D; //炮筒的方向(向下的方向) |
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); //画一个实心圆(50,50为坐标,30,,30是圆的高度和宽度) |
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; //move之前记录上一步坦克x,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等于0时,才转方向 |
step = r.nextInt( 12 ) + 3 ; |
int rn = r.nextInt(dirs.length); //move完成后,如果是敌军坦克的,随机产生一个数,来设定坦克下一个方向 |
dir = dirs[rn]; |
} |
step --; |
if (r.nextInt( 50 )> 48 ) this .fire(); //防止敌军炮火太猛烈,生成大于48的随机数时才开火 |
} |
|
} |
|
public void keyPressed(KeyEvent e) { |
int key = e.getKeyCode(); //定义一个key,(获得按键的虚拟码) |
switch (key) { |
/* case KeyEvent.VK_CONTROL: |
// tc.missiles.add(fire());//一种调用方法:调用fire方法,返回值是一发炮弹 |
fire(); |
break;*/ // 在KeyPressed中子弹太密集,将其设置为抬起发炮弹(released) |
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_F2: |
if (! this .live){ |
this .live = true ; //复活 |
this .life = 100 ; //100血 |
} 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(); //定义一个key,(获得按键的虚拟码) |
switch (key) { |
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(); |
} |
|
public Missile fire() { //fire方法返回值Missile |
if (!live) return null ; //解决自己坦克被击杀后,仍然可以操作的问题 |
int x = this .x + Tank.WIDTH/ 2 - Missile.WIDTH/ 2 ; //计算x,y的位置 |
int y = this .y + Tank.HEIGHT/ 2 - Missile.HEIGHT/ 2 ; |
Missile m = new Missile(x, y,good, ptDir, this .tc); //坦克的x,y |
tc.missiles.add(m); |
return m; |
} |
public Missile fire(Direction dir){ //超级炮弹的fire方法 |
if (!live) return null ; //解决自己坦克被击杀后,仍然可以操作的问题 |
int x = this .x + Tank.WIDTH/ 2 - Missile.WIDTH/ 2 ; //计算x,y的位置 |
int y = this .y + Tank.HEIGHT/ 2 - Missile.HEIGHT/ 2 ; |
Missile m = new Missile(x, y,good, dir, this .tc); //坦克的x,y |
tc.missiles.add(m); |
return m; |
|
} |
private void superFire() { //超级炮弹!! |
Direction[] dirs = Direction.values(); |
for ( int i= 0 ; i< 8 ; i++) { |
fire(dirs[i]); |
} |
} |
|
public Rectangle getRect() { //矩形,子弹左上角位置,宽度高度 |
return new Rectangle(x, y, WIDTH, HEIGHT); |
} |
public boolean isLive() { |
return live; |
} |
public void setLive( boolean live) { |
this .live = live; |
} |
/** |
* 为了解决坦克穿过墙这一问题 |
* @param w 坦克撞击的墙 |
* @return 坦克一旦撞上了枪,返回true,否则返回false |
*/ |
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<Tank> tanks) { |
for ( int i= 0 ; i<tanks.size(); i++) { |
Tank t = tanks.get(i); //两辆坦克不是一辆坦克才相撞 |
if ( this != t) { |
if ( this .live && t.isLive() && this .getRect().intersects(t.getRect())) { |
this .stay(); //两辆坦克都停止 |
t.stay(); |
return true ; |
} |
} |
} |
return false ; |
} |
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 ; //吃掉血块血量恢复至100 |
b.setLive( false ); // |
return true ; |
} |
return false ; |
} |
} |
初级程序员
by: 切纸 发表于:2017-12-02 17:44:36 顶(0) | 踩(0) 回复
。。
回复评论