1 importjava.awt.Color;2 importjava.awt.Graphics;3 importjava.awt.Image;4 importjava.awt.Rectangle;5 importjava.awt.event.KeyEvent;6 importjava.util.List;7 importjava.util.Random;8
9 importjavax.swing.ImageIcon;10
11
12 public classTank {13 /*坦克本身数据*/
14 int x, y;//坦克坐标
15 private int oldX, oldY; //坦克上一步坐标
16 public static final int Whith = 30; //坦克宽
17 public static final int Higth = 30; //坦克高
18 public static final int XSPEED = 5; //横向移动速度
19 public static final int YSPEED = 5; //纵向移动速度
20 private Color color; //坦克颜色
21 private boolean bL=false, bU=false, bR=false, bD=false; //四个方向控制值
22 enum Direction {L, LU, U, RU, R, RD, D, LD, STOP}; //由四个方向值合成八个方向的移动
23 private Direction dir = Direction.STOP; //出场方向
24 private Direction ptDir = Direction.D; //炮筒初始方向
25 private boolean good; //判断坦克的阵营
26 private boolean live = true; //判断坦克是否存活
27 private static Random r = new Random();//设置一个随机值变量
28 private static int step = r.nextInt(12)+3; //敌方坦克随机移动步骤3-14步
29 private int Life = 100; //血量
30 private BloodBar bb = new BloodBar(); //血块类31
32 //ImageIcon icon = new ImageIcon("res\\myTank.jpg");33 //ImageIcon icon2 = new ImageIcon("res\\enemyTank.jpg");34 //Image image = icon.getImage();35 //Image image2 = icon2.getImage();
36
37
38 private TankClient tc; //主类权限
39
40 public Tank(int x, int y, booleangood, Color color) {41 super();42 this.x =x;43 this.y =y;44 this.color =color;45 this.good =good;46 }47 public Tank(int x, int y, booleangood,Color color,Direction dir,TankClient tc){48 this(x,y,good,color);49 this.dir =dir;50 this.tc =tc;51 }52 /*获取坦克生命值*/
53 public intgetLife() {54 returnLife;55 }56 /*设置坦克生命值*/
57 public void setLife(intLife) {58 this.Life =Life;59 }60
61 /*获取坦克阵营*/
62 public booleanisGood() {63 returngood;64 }65 /*设置坦克阵营*/
66 public void setGood(booleangood) {67 this.good =good;68 }69 /*获取坦克存活状态*/
70 public booleanisLive() {71 returnlive;72 }73 /*设置坦克存活状态*/
74 public void setLive(booleanlive) {75 this.live =live;76 }77 /*画坦克*/
78 public voiddraw(Graphics g){79 if(!live){80 if(!good){81 tc.tanks.remove(this); //敌方坦克死亡时在集合中删除82 //tc.tanks.add(new Tank(r.nextInt(700),r.nextInt(500),false,Color.blue,Direction.D,this.tc));
83 }84 return;85 }86 /*先保存之前的画笔颜色,画完之后再还原画笔颜色*/
87 Color c = g.getColor(); //获取当前画笔颜色
88 g.setColor(color); //设置画笔颜色为红色
89 /*画坦克*/
90 g.fillOval(x, y, Whith, Higth);91 /*两种方法绘制敌我坦克,运用之前加入的图片或者颜色区分*/
92 //if(good)93 //g.drawImage(image, x, y,Whith,Higth,null);94 //else95 //g.drawImage(image2, x, y, Whith, Higth, null);
96 if(good)97 bb.draw(g); //我方坦克画血条
98 g.setColor(Color.black);99 /*通过炮筒方向画出炮筒*/
100 switch(ptDir){101 caseL:102 g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x, y+Tank.Higth/2);103 break;104 caseLU:105 g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x, y);106 break;107 caseU:108 g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith/2, y);109 break;110 caseRU:111 g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith, y);112 break;113 caseR:114 g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith, y+Tank.Higth/2);115 break;116 caseRD:117 g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith, y+Tank.Higth);118 break;119 caseD:120 g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x+Tank.Whith/2, y+Tank.Higth);121 break;122 caseLD:123 g.drawLine(x+Tank.Whith/2, y+Tank.Higth/2, x, y+Tank.Higth);124 break;125 }126 g.setColor(c); //还原画笔颜色
127 move();//移动
128 }129
130 /*键盘监听;摁键*/
131 public voidKeyPressed(KeyEvent e){132 int key = e.getKeyCode(); //将键盘监听到的摁键以整数保存
133 /*键盘移动坦克*/
134 switch(key){135 /*移动摁键*/
136 caseKeyEvent.VK_UP:137 bU=true;138 break;139 caseKeyEvent.VK_DOWN:140 bD=true;141 break;142 caseKeyEvent.VK_RIGHT:143 bR=true;144 break;145 caseKeyEvent.VK_LEFT:146 bL=true;147 break;148 }149 locateDirection();150 }151
152 /*键盘监听;抬起键*/
153 public voidkeyReleased(KeyEvent e){154 int key = e.getKeyCode(); //将键盘监听到的摁键以整数保存
155 /*键盘移动坦克*/
156 switch(key){157 caseKeyEvent.VK_UP:158 bU=false;159 break;160 caseKeyEvent.VK_DOWN:161 bD=false;162 break;163 caseKeyEvent.VK_RIGHT:164 bR=false;165 break;166 caseKeyEvent.VK_LEFT:167 bL=false;168 break;169 case KeyEvent.VK_Z: //单发子弹
170 if(live)171 fire();172 break;173 case KeyEvent.VK_F2: //我方复活
174 if(!this.live){175 this.live=true;176 this.setLife(100);177 }178 break;179 case KeyEvent.VK_F3: //敌方复活
180 fuhuo();181 break;182 case KeyEvent.VK_A: //无敌导弹
183 superFire();184 break;185 case KeyEvent.VK_Q: //回血
186 if(this.live)187 this.Life = 100;188 break;189 case KeyEvent.VK_E: //释放血块
190 tc.b.fh();191 break;192 /*还原位置键*/
193 caseKeyEvent.VK_R:194 x = 50;195 y = 50;196 break;197 }198 locateDirection(); //合成方向
199 }200 /*合成移动方向*/
201 voidlocateDirection(){202 if(bL&&!bU&&!bR&&!bD) dir=Direction.L;203 else if(bL&&bU&&!bR&&!bD) dir=Direction.LU;204 else if(!bL&&bU&&!bR&&!bD) dir=Direction.U;205 else if(!bL&&bU&&bR&&!bD) dir=Direction.RU;206 else if(!bL&&!bU&&bR&&!bD) dir=Direction.R;207 else if(!bL&&!bU&&bR&&bD) dir=Direction.RD;208 else if(!bL&&!bU&&!bR&&bD) dir=Direction.D;209 else if(bL&&!bU&&!bR&&bD) dir=Direction.LD;210 else if(!bL&&!bU&&!bR&&!bD) dir=Direction.STOP;211 }212
213 void move(){ //移动
214 /*记录上一步的位置*/
215 oldX =x;216 oldY =y;217 switch(dir){218 caseL:219 x-=XSPEED;220 break;221 caseLU:222 x-=XSPEED;223 y-=YSPEED;224 break;225 caseU:226 y-=YSPEED;227 break;228 caseRU:229 x+=XSPEED;230 y-=YSPEED;231 break;232 caseR:233 x+=XSPEED;234 break;235 caseRD:236 x+=XSPEED;237 y+=YSPEED;238 break;239 caseD:240 y+=YSPEED;241 break;242 caseLD:243 x-=XSPEED;244 y+=YSPEED;245 break;246 caseSTOP:247 break;248 }249 /*判断坦克移动越界情况(游戏边界)*/
250 if(x < 5) x = 5;251 if(y < 25) y = 25;252 if(x+Whith > tc.GAME_WIDTH-5) x = tc.GAME_WIDTH-Whith-5;253 if(y+Higth > tc.GAME_HEIGTH-5) y = tc.GAME_HEIGTH-Higth-5;254
255 if(dir != Direction.STOP) //如果坦克不静止就改变炮筒方向
256 ptDir =dir;257
258 /*敌方坦克自动移动*/
259 if(!good){260 Direction[] dirs = Direction.values(); //将方向变量设为数组
261 if(step == 0){262 step = r.nextInt(12)+3; //随机移动步骤
263 int randomNumber = r.nextInt(dirs.length); //随机移动方向
264 dir =dirs[randomNumber];265 }266 step--;267 if(r.nextInt(40)>30) this.fire(); //随机是否发射炮弹
268 }269 }270 /*敌方坦克复活*/
271 public voidfuhuo(){272 if(tc.tanks.size() < 20)273 while(true){274 int x = r.nextInt(700);275 int y = r.nextInt(500);276 Tank t = new Tank(x,y,false,Color.blue,Direction.D,tc);277 /*如果坦克与墙重合则重新随机位置直到不重合为止才将新坦克加入集合*/
278 if(t.getRect().intersects(tc.wall1.getRect())||t.getRect().intersects(tc.wall2.getRect())279 ||t.getRect().intersects(tc.wall3.getRect())280 ||t.getRect().intersects(tc.wall4.getRect())){281 continue;282 }283 else{284 tc.tanks.add(t);285 break;286 }287 }288 }289 /*子弹发射*/
290 public voidfire(){291 int x = this.x + Whith/2 - Missile.Whith/2; //控制子弹方向为坦克中间
292 int y = this.y + Higth/2 - Missile.Higth/2;293 tc.missiles.add(new Missile(ptDir,color,x,y,good,tc)); //创建新的子弹类加入到子弹集合中
294 }295 /*碰撞;获取坦克的范围*/
296 publicRectangle getRect(){297 return newRectangle(x,y,Whith,Higth);298 }299 /*回执上一步位置*/
300 private voidstay(){301 x =oldX;302 y =oldY;303 }304 /*如果撞墙,调用stay方法,返回上一步位置*/
305 public booleanhitWall(Wall w){306 if(this.live&&this.getRect().intersects(w.getRect())){307 this.stay();308 return true;309 }310 return false;311 }312 /*坦克互相撞击事件*/
313 public boolean hitTanks(Listtanks){314 for(int i=0;i
317 /*如果相撞返回上一步位置*/
318 if(this.live&&t.isLive()&&this.getRect().intersects(t.getRect())){319 this.stay();320 t.stay();321 return true;322 }323 }324 }325 return false;326 }327 /*带开火方向的发射函数*/
328 publicMissile fire(Direction dir){329 if(!live) return null;330 int x=this.x+Whith/2-Missile.Whith/2;331 int y=this.y+Higth/2-Missile.Higth/2;332 Missile m=new Missile(dir,color,x, y,good, this.tc);333 tc.missiles.add(m);334 returnm;335 }336 /*超级射击导弹*/
337 private voidsuperFire(){338 Direction[] dirs=Direction.values();339 for(int i=0;i<8;i++){340 fire(dirs[i]);//循环调用八个方向
341 }342 }343 /*新增血块类*/
344 private classBloodBar{345 /*画血条*/
346 public voiddraw(Graphics g){347 Color c=g.getColor();348 g.setColor(Color.red);349 g.drawRect(x, y-10, Whith, 10);350 int w=Whith*Life/100;351 g.fillRect(x, y-10, w, 10);352 g.setColor(c);353 }354 }355 /*吃血方法*/
356 public booleaneatBlood(Blood b){357 if(this.live&&b.isLive()&&this.isGood()&&this.getRect().intersects(b.getRect())){358 this.setLife(100);359 b.setLive(false);360 return true;361 }362 if(this.getRect().intersects(tc.wb.getRect()))363 this.Life = 100;364 return false;365 }366 }