Java__线程---基础知识全面实战---坦克大战系列为例
今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过java但对java运用并不是很熟悉的同学,该编程代码基本上涉及了java基础知识的各个方面,大家可以通过练习该程序对自己的java进行一下实战。
每个程序版本代码中,都附有相关注释,看完注释大家就可以对本程序设计有个很明显的思路。真的很有趣,想对java重新温习的同学完全不必再对厚厚的java基础书籍进行阅读了,在跟着本次代码练习并分析后,大家一定会对java各方面基础知识 尤其是线程的知识有更深一步的了解!!!
本次坦克大战系列的各个版本都是在一步步的升级改进,难度逐渐加大,功能愈加完善;话不多说,先给大家分享一下代码(●ˇ∀ˇ●)
Tank大战 version1.0
实现功能:
1.绘制出我方Tank;
2.可以通过键盘上下左右键 控制移动;
1 package com.test; 2 3 import java.awt.Color; 4 import java.awt.Graphics; 5 import java.awt.event.*; 6 7 import javax.swing.*; 8 9 10 public class MyTankGame extends JFrame { 11 Mypanel mp=null; 12 public static void main(String[] args) { 13 // TODO 自动生成的方法存根 14 MyTankGame mtg=new MyTankGame(); 15 } 16 //构造函数 17 public MyTankGame() 18 { 19 mp=new Mypanel(); 20 this.add(mp); 21 this.setSize(800,600); 22 this.setVisible(true); 23 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 24 25 } 26 27 } 28 29 //坦克类 30 class Tank 31 { 32 //表示坦克横坐标 33 int x=0; 34 public int getX() { 35 return x; 36 } 37 38 public void setX(int x) { 39 this.x = x; 40 } 41 42 public int getY() { 43 return y; 44 } 45 46 public void setY(int y) { 47 this.y = y; 48 } 49 50 //表示坦克纵坐标 51 int y=0; 52 53 public Tank(int x,int y) 54 { 55 this.x=x; 56 this.y=y; 57 } 58 } 59 60 //我的Tank 61 class Hero extends Tank 62 { 63 64 public Hero(int x, int y) { 65 super(x, y); 66 // TODO 自动生成的构造函数存根 67 } 68 69 } 70 71 72 //我的面板 73 class Mypanel extends JPanel 74 { 75 //定义一个我的坦克 76 Hero hero=null; 77 78 //构造函数 79 public Mypanel() 80 { 81 hero=new Hero(100,100); 82 } 83 public void paint(Graphics g) 84 { 85 super.paint(g); 86 //设置面板背景色,全部填充即可,默认为黑色 87 g.fillRect(0, 0, 800, 600); 88 //画出我的tank,放到paint函数中 89 this.DrawTank(hero.getX(), hero.getY(), g,0,0);//hero.getX(), hero.getY()就将x,y传过去了 90 } 91 92 //画出tank 93 public void DrawTank(int x,int y,Graphics g,int direct,int type) 94 { 95 //判断是什么类型坦克 96 switch(type) 97 { 98 case 0://我的tank 99 g.setColor(Color.cyan); 100 break; 101 case 1://敌人的tank 102 g.setColor(Color.orange); 103 break; 104 } 105 //判断坦克的方向 106 switch(direct) 107 { 108 //向上 109 case 0: 110 //画出左边矩形 111 g.fill3DRect(x, y, 5, 30, false); 112 //画出右边矩形 113 g.fill3DRect(x+15, y, 5, 30, false); 114 //画出中间矩形 115 g.fill3DRect(x+5, y+5, 10, 20, false); 116 //画出中间圆形 117 g.fillOval(x+5, y+10, 10, 10); 118 //画出中间直线 119 g.fillRect(x+9, y, 2, 10); 120 break; 121 } 122 } 123 } 124 125 /* 126 画出左边矩形 127 g.fill3DRect(hero.getX(), hero.getY(), 5, 30, false); 128 //画出右边矩形 129 g.fill3DRect(hero.getX()+15, hero.getY(), 5, 30, false); 130 //画出中间矩形 131 g.fill3DRect(hero.getX()+5, hero.getY()+5, 10, 20, false); 132 //画出中间圆形 133 g.fillOval(hero.getX()+5, hero.getY()+10, 10, 10); 134 //画出中间直线 135 g.drawLine(hero.getX()+10, hero.getY()+15, 10, 20); 136 break; 137 138 */ 139
Tank大战 version2.0
java练习---->坦克大战2.0------>引入多线程
实现功能:
1.有敌方tank与我方tank;
2.我方tank可以控制移动;
3.我方tank可以发射炮弹;
4.敌方tank未作处理;
1 package TankGame2; 2 3 import java.awt.*; 4 import java.awt.event.KeyEvent; 5 import java.awt.event.KeyListener; 6 import java.util.*; 7 import javax.swing.*; 8 public class MyTankGame2 extends JFrame 9 { 10 MyPanel mp=null; 11 public static void main(String[] args) 12 { 13 MyTankGame2 mytankgame1=new MyTankGame2(); 14 } 15 16 public MyTankGame2() 17 { 18 mp=new MyPanel(); 19 //启动mp线程 20 21 Thread t=new Thread(mp); 22 t.start(); 23 24 this.add(mp); 25 this.addKeyListener(mp); 26 27 this.setSize(400,300); 28 this.setVisible(true); 29 this.setDefaultCloseOperation(EXIT_ON_CLOSE); 30 } 31 } 32 33 34 class MyPanel extends JPanel implements KeyListener,Runnable 35 { 36 //定义我的坦克,成员变量 37 Hero hero=null; 38 39 //定义敌人的坦克组 40 41 Vector<EnemyTank> ets=new Vector<EnemyTank>(); 42 int enSize=3; 43 44 public void paint (Graphics g) 45 { 46 super.paint(g); 47 g.fillRect(0,0,400,300); 48 49 //画出自己的坦克 50 this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1); 51 52 //画出子弹 53 if (hero.s!=null&&hero.s.isLive==true) 54 { 55 g.draw3DRect(hero.s.x, hero.s.y, 1, 1, false); 56 57 } 58 59 60 //画出敌人的坦克 61 for(int i=0;i<ets.size();i++) 62 { 63 64 this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0); 65 66 } 67 68 } 69 70 //画出坦克函数(扩展) 71 public void drawTank(int x,int y,Graphics g,int direct,int type) 72 { 73 //判断类型 74 switch (type) 75 { 76 case 0: 77 g.setColor(Color.cyan);break; 78 case 1: 79 g.setColor(Color.yellow);break; 80 } 81 //判断方向 82 83 switch(direct) 84 { 85 //向上 86 case 0: 87 //画出我的坦克(到时候再封装成一个函数) 88 //1.画出左面的矩形 89 //g.drawRect(hero.getX(), hero.getY(), 5, 30); 90 g.fill3DRect(x,y,5,30,false); 91 92 //2.画出右边的矩形 93 g.fill3DRect(x+15,y,5,30,false); 94 95 //3.画出坦克的中间矩形 96 g.fill3DRect(x+5, y+5, 10, 20,false); 97 //画出中间的圆 98 g.fillOval(x+4, y+10,10,10); 99 //画出线 100 g.drawLine(x+9, y+15, x+9, y); 101 break; 102 case 1: 103 //炮筒向右 104 //画出上面的矩形 105 g.fill3DRect(x,y,30, 5, false); 106 g.fill3DRect(x, y+15, 30, 5, false); 107 g.fill3DRect(x+5, y+5, 20, 10, false); 108 g.fillOval(x+10, y+5, 10, 10); 109 g.drawLine(x+15, y+10, x+30, y+10); 110 111 break; 112 case 2: 113 //向下 114 g.fill3DRect(x,y,5,30,false); 115 g.fill3DRect(x+15,y,5,30,false); 116 g.fill3DRect(x+5, y+5, 10, 20,false); 117 g.fillOval(x+4, y+10,10,10); 118 g.drawLine(x+10, y+15, x+10, y+30); 119 break; 120 121 case 3: 122 //向左 123 g.fill3DRect(x,y,30, 5, false); 124 g.fill3DRect(x, y+15, 30, 5, false); 125 g.fill3DRect(x+5, y+5, 20, 10, false); 126 g.fillOval(x+10, y+5, 10, 10); 127 g.drawLine(x+15, y+10, x, y+10); 128 break; 129 } 130 131 } 132 133 134 public MyPanel() 135 { 136 hero=new Hero(100,100); 137 138 //初始化敌人的坦克 139 for(int i=0;i<enSize;i++) 140 { 141 //创建敌人的坦克对象 142 EnemyTank et=new EnemyTank((i+1)*50,0); 143 et.setColor(0); 144 et.setDirect(2); 145 ets.add(et); 146 } 147 148 } 149 150 //键按下处理a表示左,s表示向下,w表示向上,d表示向右 151 public void keyPressed(KeyEvent e) 152 { 153 if(e.getKeyCode()==KeyEvent.VK_UP) 154 { 155 // 设置我的坦克的方向 156 this.hero.setDirect(0); 157 this.hero.moveUp(); 158 } 159 160 else if (e.getKeyCode()==KeyEvent.VK_DOWN) 161 { 162 this.hero.setDirect(2); 163 this.hero.moveDown(); 164 } 165 166 else if (e.getKeyCode()==KeyEvent.VK_RIGHT) 167 { 168 this.hero.setDirect(1); 169 this.hero.moveRight(); 170 171 } 172 else if (e.getKeyCode()==KeyEvent.VK_LEFT) 173 { 174 this.hero.setDirect(3); 175 this.hero.moveLeft(); 176 } 177 178 if (e.getKeyCode()==KeyEvent.VK_SPACE) 179 { 180 this.hero.shotEnemy(); 181 182 } 183 184 185 //必须重新绘制Panel 186 this.repaint(); 187 } 188 189 public void keyReleased(KeyEvent e) //有什么用?!!!!!!!!!!! 190 { 191 192 } 193 public void keyTyped(KeyEvent e) 194 { 195 196 } 197 public void run() 198 { 199 //每个一百毫秒去重画子弹 200 while(true) 201 { 202 try { 203 Thread.sleep(100); 204 } catch (InterruptedException e) { 205 // TODO Auto-generated catch block 206 e.printStackTrace(); 207 } 208 this.repaint(); 209 210 } 211 } 212 213 } 214 215 216 class Tank 217 { 218 219 //设置坦克的速度 220 int speed=1; 221 public int getSpeed() 222 { 223 return speed; 224 } 225 public void setSpeed(int speed) 226 { 227 this.speed = speed; 228 } 229 //表示坦克的横坐标 230 int x=0; 231 //坦克的纵坐标 232 int y=0; 233 int direct=0; 234 int color; 235 236 //坦克方向,0表示上,1表示右,2表示下,3表示左 237 public int getColor() { 238 return color; 239 } 240 public void setColor(int color) { 241 this.color = color; 242 } 243 public int getDirect() 244 { 245 return direct; 246 } 247 248 public void setDirect(int direct) 249 { 250 this.direct = direct; 251 } 252 public Tank(int x,int y) 253 { 254 this.x=x; 255 this.y=y; 256 } 257 258 public int getX() 259 { 260 return x; 261 } 262 public void setX(int x) 263 { 264 this.x = x; 265 } 266 public int getY() 267 { 268 return y; 269 } 270 public void setY(int y) 271 { 272 this.y = y; 273 } 274 275 } 276 277 class EnemyTank extends Tank 278 { 279 public EnemyTank(int x,int y) 280 { 281 super(x,y); //super的用法??? 282 283 } 284 } 285 286 287 //我的坦克 288 class Hero extends Tank 289 { 290 //子弹 291 Shot s=null; 292 public Hero(int x, int y) 293 { 294 super(x,y); 295 } 296 //坦克向上移动 297 298 //坦克的开火的能力和动作 299 public void shotEnemy() 300 { 301 switch(this.direct) 302 { 303 case 0: 304 s=new Shot(x+9,y-1,0); 305 break; 306 case 1: 307 s=new Shot(x+30,y+10,1); 308 break; 309 case 2: 310 s=new Shot(x+9,y+30,2); 311 break; 312 case 3: 313 s=new Shot(x-1,y+9,3); 314 break; 315 } 316 317 Thread t=new Thread(s); 318 t.start(); 319 320 } 321 322 323 public void moveUp() 324 { 325 this.y-=speed; 326 } 327 public void moveRight() 328 { 329 this.x+=speed; 330 } 331 332 public void moveDown() 333 { 334 this.y+=speed; 335 } 336 public void moveLeft() 337 { 338 this.x-=speed; 339 } 340 } 341 342 343 class Shot implements Runnable //runnable的用法???? 344 { 345 int x; 346 int y; 347 int direct; 348 int speed=1; 349 //是否活着 350 351 boolean isLive=true; 352 public Shot(int x,int y,int direct) 353 { 354 this.x=x; 355 this.y=y; 356 this.direct=direct; 357 } 358 public void run() 359 { 360 while(true) 361 { 362 try { 363 Thread.sleep(50); 364 } catch (InterruptedException e) { 365 e.printStackTrace(); 366 } 367 368 switch(direct) 369 { 370 case 0: 371 //向上 372 y-=speed;break; 373 case 1: 374 x+=speed;break; 375 case 2: 376 y+=speed;break; 377 case 3: 378 x-=speed;break; 379 380 } 381 382 383 //判断该子弹是否碰到边缘 384 if(x<0||x>400||y<0||y>300) 385 { 386 this.isLive=false; 387 break; 388 389 } 390 391 } 392 393 } 394 }
Tank大战 version3.0
java练习---->坦克大战3.0
实现功能:
1.有敌方tank与我方tank;
2.我方tank可以控制移动,可以发射炮弹;
3.写一个函数专门判断子弹是否击中敌人坦克;
4.判断tank是否活着;
(注:本版本中,Tank是不可以发射炮弹的······)
1 package TankGame3; 2 3 import java.awt.*; 4 import java.awt.event.KeyEvent; 5 import java.awt.event.KeyListener; 6 import java.util.*; 7 import javax.swing.*; 8 import java.util.Vector; 9 public class MyTankGame4 extends JFrame 10 { 11 MyPanel mp=null; 12 public static void main(String[] args) 13 { 14 MyTankGame4 mytankgame1=new MyTankGame4(); 15 } 16 17 public MyTankGame4() 18 { 19 mp=new MyPanel(); 20 //启动mp线程 21 22 Thread t=new Thread(mp); 23 t.start(); 24 25 this.add(mp); 26 this.addKeyListener(mp); 27 28 this.setSize(400,300); 29 this.setVisible(true); 30 this.setDefaultCloseOperation(EXIT_ON_CLOSE); 31 } 32 } 33 class MyPanel extends JPanel implements KeyListener,Runnable 34 { 35 //定义我的坦克,成员变量 36 Hero hero=null; 37 38 //定义敌人的坦克组 39 40 Vector<EnemyTank> ets=new Vector<EnemyTank>(); 41 int enSize=3; 42 43 public void paint (Graphics g) 44 { 45 super.paint(g); 46 g.fillRect(0,0,400,300); 47 48 //画出自己的坦克 49 this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1); 50 51 //从Vector ss中取出每一颗子弹,并画出 52 for(int i=0;i<this.hero.ss.size();i++) 53 { 54 Shot myShot=hero.ss.get(i); 55 56 57 //画出子弹,只画一颗子弹 58 if (myShot!=null&&myShot.isLive==true) 59 { 60 g.draw3DRect(myShot.x, myShot.y, 1, 1, false); 61 62 } 63 if (myShot.isLive==false) 64 { 65 //从ss中删除该子弹 66 hero.ss.remove(myShot); 67 68 } 69 } 70 71 //画出敌人的坦克 72 for(int i=0;i<ets.size();i++) 73 { 74 EnemyTank et=ets.get(i); 75 if(et.isLive) 76 { 77 this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0); 78 } 79 } 80 81 } 82 83 //写一个函数专门判断子弹是否击中敌人坦克 84 public void hitTank(Shot s,EnemyTank et) 85 { 86 //判断该坦克的方向 87 switch(et.direct) 88 { 89 //如果敌人的方向是上或者是下 90 case 0: 91 case 2: 92 if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30)) 93 { 94 //击中了 95 //子弹死亡 96 s.isLive=false; 97 //敌人坦克也要死亡 98 et.isLive=false; 99 } 100 case 1: 101 case 3: 102 if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20)) 103 { 104 //击中了 105 //子弹死亡 106 s.isLive=false; 107 //敌人坦克也要死亡 108 et.isLive=false; 109 110 } 111 112 } 113 114 } 115 116 //画出坦克函数(扩展) 117 public void drawTank(int x,int y,Graphics g,int direct,int type) 118 { 119 //判断类型 120 switch (type) 121 { 122 case 0: 123 g.setColor(Color.cyan);break; 124 case 1: 125 g.setColor(Color.yellow);break; 126 } 127 //判断方向 128 129 switch(direct) 130 { 131 //向上 132 case 0: 133 //画出我的坦克(到时候再封装成一个函数) 134 //1.画出左面的矩形 135 //g.drawRect(hero.getX(), hero.getY(), 5, 30); 136 g.fill3DRect(x,y,5,30,false); 137 138 //2.画出右边的矩形 139 g.fill3DRect(x+15,y,5,30,false); 140 141 //3.画出坦克的中间矩形 142 g.fill3DRect(x+5, y+5, 10, 20,false); 143 //画出中间的圆 144 g.fillOval(x+4, y+10,10,10); 145 //画出线 146 g.drawLine(x+9, y+15, x+9, y); 147 break; 148 case 1: 149 //炮筒向右 150 //画出上面的矩形 151 g.fill3DRect(x,y,30, 5, false); 152 g.fill3DRect(x, y+15, 30, 5, false); 153 g.fill3DRect(x+5, y+5, 20, 10, false); 154 g.fillOval(x+10, y+5, 10, 10); 155 g.drawLine(x+15, y+10, x+30, y+10); 156 157 break; 158 case 2: 159 //向下 160 g.fill3DRect(x,y,5,30,false); 161 g.fill3DRect(x+15,y,5,30,false); 162 g.fill3DRect(x+5, y+5, 10, 20,false); 163 g.fillOval(x+4, y+10,10,10); 164 g.drawLine(x+10, y+15, x+10, y+30); 165 break; 166 167 case 3: 168 //向左 169 g.fill3DRect(x,y,30, 5, false); 170 g.fill3DRect(x, y+15, 30, 5, false); 171 g.fill3DRect(x+5, y+5, 20, 10, false); 172 g.fillOval(x+10, y+5, 10, 10); 173 g.drawLine(x+15, y+10, x, y+10); 174 break; 175 } 176 177 } 178 179 180 public MyPanel() 181 { 182 hero=new Hero(100,100); 183 184 //初始化敌人的坦克 185 for(int i=0;i<enSize;i++) 186 { 187 //创建敌人的坦克对象 188 EnemyTank et=new EnemyTank((i+1)*50,0); 189 et.setColor(0); 190 et.setDirect(2); 191 ets.add(et); 192 } 193 194 } 195 196 //键按下处理a表示左,s表示向下,w表示向上,d表示向右 197 public void keyPressed(KeyEvent e) 198 { 199 if(e.getKeyCode()==KeyEvent.VK_W) 200 { 201 // 设置我的坦克的方向 202 this.hero.setDirect(0); 203 this.hero.moveUp(); 204 } 205 206 else if (e.getKeyCode()==KeyEvent.VK_S) 207 { 208 this.hero.setDirect(2); 209 this.hero.moveDown(); 210 } 211 212 else if (e.getKeyCode()==KeyEvent.VK_D) 213 { 214 this.hero.setDirect(1); 215 this.hero.moveRight(); 216 217 } 218 else if (e.getKeyCode()==KeyEvent.VK_A) 219 { 220 this.hero.setDirect(3); 221 this.hero.moveLeft(); 222 } 223 224 if (e.getKeyCode()==KeyEvent.VK_J) 225 { 226 this.hero.shotEnemy(); 227 } 228 229 //必须重新绘制Panel 230 this.repaint(); 231 } 232 public void keyReleased(KeyEvent e) 233 { 234 235 } 236 public void keyTyped(KeyEvent e) 237 { 238 239 } 240 public void run() 241 { 242 //每个一百毫秒去重画子弹 243 while(true) 244 { 245 try { 246 Thread.sleep(100); 247 } catch (InterruptedException e) { 248 // TODO Auto-generated catch block 249 e.printStackTrace(); 250 } 251 252 for(int i=0;i<hero.ss.size();i++) 253 { 254 Shot myShot=hero.ss.get(i); 255 //判断子弹是否有效 256 if(myShot.isLive) 257 { 258 //取出每个坦克,与它判断 259 for(int j=0;j<ets.size();j++) 260 { 261 //取出坦克 262 EnemyTank et=ets.get(j); 263 if(et.isLive) 264 { 265 this.hitTank(myShot,et); 266 267 } 268 269 } 270 271 } 272 } 273 274 this.repaint(); 275 276 } 277 } 278 279 } 280 281 //package MyTankGame4; 282 //import java.util.Vector; 283 //import MyTankGame4.Shot; 284 //import MyTankGame4.Tank; 285 class Tank 286 { 287 288 //设置坦克的速度 289 int speed=1; 290 public int getSpeed() 291 { 292 return speed; 293 } 294 public void setSpeed(int speed) 295 { 296 this.speed = speed; 297 } 298 //表示坦克的横坐标 299 int x=0; 300 //坦克的纵坐标 301 int y=0; 302 int direct=0; 303 int color; 304 305 //坦克方向,0表示上,1表示右,2表示下,3表示左 306 public int getColor() { 307 return color; 308 } 309 public void setColor(int color) { 310 this.color = color; 311 } 312 public int getDirect() 313 { 314 return direct; 315 } 316 317 public void setDirect(int direct) 318 { 319 this.direct = direct; 320 } 321 public Tank(int x,int y) 322 { 323 this.x=x; 324 this.y=y; 325 } 326 327 public int getX() 328 { 329 return x; 330 } 331 public void setX(int x) 332 { 333 this.x = x; 334 } 335 public int getY() 336 { 337 return y; 338 } 339 public void setY(int y) 340 { 341 this.y = y; 342 } 343 344 } 345 346 class EnemyTank extends Tank 347 { 348 boolean isLive=true; 349 public EnemyTank(int x,int y) 350 { 351 super(x,y); 352 353 } 354 } 355 356 357 //我的坦克 358 class Hero extends Tank 359 { 360 //子弹 361 //Shot s=null; 362 Vector<Shot> ss=new Vector<Shot>(); 363 Shot s=null; 364 365 public Hero(int x, int y) 366 { 367 super(x,y); 368 } 369 //坦克向上移动 370 371 //坦克的开火的能力和动作 372 public void shotEnemy() 373 { 374 switch(this.direct) 375 { 376 case 0: 377 s=new Shot(x+9,y-1,0); 378 ss.add(s); 379 break; 380 case 1: 381 s=new Shot(x+30,y+10,1); 382 ss.add(s); 383 break; 384 case 2: 385 s=new Shot(x+9,y+30,2); 386 ss.add(s); 387 break; 388 case 3: 389 s=new Shot(x-1,y+9,3); ss.add(s); 390 ss.add(s); 391 break; 392 } 393 394 Thread t=new Thread(s); 395 t.start(); 396 397 } 398 399 400 public void moveUp() 401 { 402 this.y-=speed; 403 } 404 public void moveRight() 405 { 406 this.x+=speed; 407 } 408 409 public void moveDown() 410 { 411 this.y+=speed; 412 } 413 public void moveLeft() 414 { 415 this.x-=speed; 416 } 417 } 418 class Shot implements Runnable 419 { 420 int x; 421 int y; 422 int direct; 423 int speed=1; 424 //是否活着 425 426 boolean isLive=true; 427 public Shot(int x,int y,int direct) 428 { 429 this.x=x; 430 this.y=y; 431 this.direct=direct; 432 } 433 public void run() 434 { 435 while(true) 436 { 437 try { 438 Thread.sleep(50); 439 } catch (InterruptedException e) { 440 e.printStackTrace(); 441 } 442 443 switch(direct) 444 { 445 case 0: 446 //向上 447 y-=speed;break; 448 case 1: 449 x+=speed;break; 450 case 2: 451 y+=speed;break; 452 case 3: 453 x-=speed;break; 454 455 } 456 457 //判断该子弹是否碰到边缘 458 if(x<0||x>400||y<0||y>300) 459 { 460 this.isLive=false; 461 break; 462 463 } 464 465 } 466 467 } 468 }
Tank大战 version4.0
java练习---->坦克大战4.0
实现功能:
1.有敌方tank与我方tank;
2.双方都可以控制移动,可以发射炮弹;
3.敌方坦克可以被击中消失
4.有爆炸效果;
5.可以计算生命值和炸弹生命;
1 package TankGame4; 2 //package MyTankGame4; 3 import java.util.Vector; 4 import java.awt.*; 5 import java.awt.event.KeyEvent; 6 import java.awt.event.KeyListener; 7 import java.util.*; 8 import javax.swing.*; 9 public class MyTankGame4 extends JFrame 10 { 11 MyPanel mp=null; 12 public static void main(String[] args) 13 { 14 MyTankGame4 mytankgame1=new MyTankGame4(); 15 } 16 17 public MyTankGame4() 18 { 19 mp=new MyPanel(); 20 //启动mp线程 21 22 Thread t=new Thread(mp); 23 24 t.start(); 25 26 this.add(mp); 27 this.addKeyListener(mp); 28 29 this.setSize(400,300); 30 this.setVisible(true); 31 this.setDefaultCloseOperation(EXIT_ON_CLOSE); 32 } 33 } 34 class MyPanel extends JPanel implements KeyListener,Runnable 35 { 36 //定义我的坦克,成员变量 37 Hero hero=null; 38 39 //定义敌人的坦克组 40 41 Vector<EnemyTank> ets=new Vector<EnemyTank>(); 42 int enSize=5; 43 44 //定义炸弹集合 45 Vector<Bomb> bombs=new Vector<Bomb>(); 46 47 public void run() 48 { 49 //每个一百毫秒去重画子弹 50 while(true) 51 { 52 try { 53 Thread.sleep(100); 54 } catch (InterruptedException e) { 55 // TODO Auto-generated catch block 56 e.printStackTrace(); 57 } 58 59 for(int i=0;i<hero.ss.size();i++) 60 { 61 Shot myShot=hero.ss.get(i); 62 //判断子弹是否有效 63 if(myShot.isLive) 64 { 65 //取出每个坦克,与它判断 66 for(int j=0;j<ets.size();j++) 67 { 68 //取出坦克 69 EnemyTank et=ets.get(j); 70 if(et.isLive) 71 { 72 this.hitTank(myShot,et); 73 74 } 75 } 76 77 } 78 } 79 80 this.repaint(); 81 //判断是否需要给坦克加入新的子弹 82 for(int i=0;i<ets.size();i++) 83 { 84 EnemyTank et=ets.get(i); 85 if(et.isLive) 86 { 87 if (et.ss.size()<5&&(int)(100*Math.random())>75) 88 { 89 //每辆坦克的子弹少于5发的话 90 //添加 91 Shot s=null; 92 switch(et.direct) 93 { 94 case 0: 95 s=new Shot(et.x+9,et.y-1,0); 96 et.ss.add(s); 97 break; 98 case 1: 99 s=new Shot(et.x+30,et.y+10,1); 100 et.ss.add(s); 101 break; 102 case 2: 103 s=new Shot(et.x+9,et.y+30,2); 104 et.ss.add(s); 105 break; 106 case 3: 107 s=new Shot(et.x-1,et.y+9,3); 108 et.ss.add(s); 109 break; 110 } 111 112 //启动子弹线程 113 Thread t=new Thread(s); 114 t.start(); 115 116 } 117 118 } 119 } 120 121 } 122 123 } 124 125 public void paint (Graphics g) 126 { 127 super.paint(g); 128 g.fillRect(0,0,400,300); 129 130 //画出自己的坦克 131 this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1); 132 133 //从Vector ss中取出每一颗子弹,并画出 134 for(int i=0;i<this.hero.ss.size();i++) 135 { 136 Shot myShot=hero.ss.get(i); 137 138 139 //画出子弹,只画一颗子弹 140 if (myShot!=null&&myShot.isLive==true) 141 { 142 g.draw3DRect(myShot.x, myShot.y, 1, 1, false); 143 144 } 145 if (myShot.isLive==false) 146 { 147 //从ss中删除该子弹 148 hero.ss.remove(myShot); 149 150 } 151 } 152 153 //画出炸弹 154 for(int i=0;i<bombs.size();i++) 155 { 156 // 取出炸弹 157 Bomb b=bombs.get(i); 158 159 if(b.life>6) 160 { 161 g.drawImage(image1, b.x, b.y, 30,30,this); 162 } 163 else if(b.life>3) 164 { 165 g.drawImage(image2, b.x, b.y, 30,30,this); 166 } 167 else 168 { 169 g.drawImage(image3, b.x, b.y, 30,30,this); 170 } 171 //让b的生命值减小 172 b.lifeDown(); 173 //如果炸弹的生命值为0,我们就剔除 174 if(b.life==0) bombs.remove(b); 175 176 177 } 178 179 180 //画出敌人的坦克 181 for(int i=0;i<ets.size();i++) 182 { 183 EnemyTank et=ets.get(i); 184 if(et.isLive) 185 { 186 this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0); 187 //画出敌人的子弹 188 189 for(int j=0;j<et.ss.size();j++) 190 { 191 //取出子弹 192 Shot enemyShot=et.ss.get(j); 193 if(enemyShot.isLive) 194 { 195 g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false); 196 } 197 else 198 { 199 //如果敌人的坦克死亡就从Vector去掉 200 et.ss.remove(enemyShot); 201 202 } 203 204 } 205 } 206 } 207 208 } 209 210 //写一个函数专门判断子弹是否击中敌人坦克 211 public void hitTank(Shot s,EnemyTank et) 212 { 213 //判断该坦克的方向 214 switch(et.direct) 215 { 216 //如果敌人的方向是上或者是下 217 case 0: 218 case 2: 219 if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30)) 220 { 221 //击中了 222 //子弹死亡 223 s.isLive=false; 224 //敌人坦克也要死亡 225 et.isLive=false; 226 //创建一个炸弹,放入Vector 227 Bomb b=new Bomb(et.x,et.y); 228 //放入Vector 229 bombs.add(b); 230 } 231 case 1: 232 case 3: 233 if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20)) 234 { 235 //击中了 236 //子弹死亡 237 s.isLive=false; 238 //敌人坦克也要死亡 239 et.isLive=false; 240 //创建一个炸弹,放入Vector 241 Bomb b=new Bomb(et.x,et.y); 242 //放入Vector 243 bombs.add(b); 244 } 245 246 } 247 248 } 249 250 //画出坦克函数(扩展) 251 public void drawTank(int x,int y,Graphics g,int direct,int type) 252 { 253 //判断类型 254 switch (type) 255 { 256 case 0: 257 g.setColor(Color.cyan);break; 258 case 1: 259 g.setColor(Color.yellow);break; 260 } 261 //判断方向 262 263 switch(direct) 264 { 265 //向上 266 case 0: 267 //画出我的坦克(到时候再封装成一个函数) 268 //1.画出左面的矩形 269 //g.drawRect(hero.getX(), hero.getY(), 5, 30); 270 g.fill3DRect(x,y,5,30,false); 271 272 //2.画出右边的矩形 273 g.fill3DRect(x+15,y,5,30,false); 274 275 //3.画出坦克的中间矩形 276 g.fill3DRect(x+5, y+5, 10, 20,false); 277 //画出中间的圆 278 g.fillOval(x+4, y+10,10,10); 279 //画出线 280 g.drawLine(x+9, y+15, x+9, y); 281 break; 282 case 1: 283 //炮筒向右 284 //画出上面的矩形 285 g.fill3DRect(x,y,30, 5, false); 286 g.fill3DRect(x, y+15, 30, 5, false); 287 g.fill3DRect(x+5, y+5, 20, 10, false); 288 g.fillOval(x+10, y+5, 10, 10); 289 g.drawLine(x+15, y+10, x+30, y+10); 290 291 break; 292 case 2: 293 //向下 294 g.fill3DRect(x,y,5,30,false); 295 g.fill3DRect(x+15,y,5,30,false); 296 g.fill3DRect(x+5, y+5, 10, 20,false); 297 g.fillOval(x+4, y+10,10,10); 298 g.drawLine(x+10, y+15, x+10, y+30); 299 break; 300 301 case 3: 302 //向左 303 g.fill3DRect(x,y,30, 5, false); 304 g.fill3DRect(x, y+15, 30, 5, false); 305 g.fill3DRect(x+5, y+5, 20, 10, false); 306 g.fillOval(x+10, y+5, 10, 10); 307 g.drawLine(x+15, y+10, x, y+10); 308 break; 309 } 310 311 } 312 313 //定义三张图片,三张图片切换组成一颗炸弹 314 Image image1=null; 315 Image image2=null; 316 Image image3=null; 317 318 //构造函数 319 public MyPanel() 320 { 321 hero=new Hero(100,100); 322 323 //初始化敌人的坦克 324 for(int i=0;i<enSize;i++) 325 { 326 //创建敌人的坦克对象 327 EnemyTank et=new EnemyTank((i+1)*50,0); 328 et.setColor(0); 329 et.setDirect(2); 330 //启动敌人的坦克 331 332 Thread t=new Thread(et); 333 t.start(); 334 //给敌人坦克添加一颗子弹 335 Shot s=new Shot(et.x+10,et.y+30,2); 336 et.ss.add(s); 337 Thread t2=new Thread(s); 338 t2.start(); 339 //加入 340 341 ets.add(et); 342 } 343 344 image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/33.jpg")); 345 image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/22.jpg")); 346 image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/11.jpg")); 347 348 } 349 350 //键按下处理向左,向下,向上,向右 351 public void keyPressed(KeyEvent e) 352 { 353 if(e.getKeyCode()==KeyEvent.VK_UP) 354 { 355 // 设置我的坦克的方向 356 this.hero.setDirect(0); 357 this.hero.moveUp(); 358 } 359 360 else if (e.getKeyCode()==KeyEvent.VK_DOWN) 361 { 362 this.hero.setDirect(2); 363 this.hero.moveDown(); 364 } 365 366 else if (e.getKeyCode()==KeyEvent.VK_RIGHT) 367 { 368 this.hero.setDirect(1); 369 this.hero.moveRight(); 370 371 } 372 else if (e.getKeyCode()==KeyEvent.VK_LEFT) 373 { 374 this.hero.setDirect(3); 375 this.hero.moveLeft(); 376 } 377 378 if (e.getKeyCode()==KeyEvent.VK_J) 379 { 380 this.hero.shotEnemy(); 381 382 } 383 //必须重新绘制Panel 384 this.repaint(); 385 } 386 public void keyReleased(KeyEvent e) 387 { 388 389 } 390 public void keyTyped(KeyEvent e) 391 { 392 393 } 394 395 } 396 397 398 class Tank 399 { 400 401 //设置坦克的速度 402 int speed=3; 403 public int getSpeed() 404 { 405 return speed; 406 } 407 public void setSpeed(int speed) 408 { 409 this.speed = speed; 410 } 411 //表示坦克的横坐标 412 int x=0; 413 //坦克的纵坐标 414 int y=0; 415 int direct=0; 416 int color; 417 418 //坦克方向,0表示上,1表示右,2表示下,3表示左 419 public int getColor() { 420 return color; 421 } 422 public void setColor(int color) { 423 this.color = color; 424 } 425 public int getDirect() 426 { 427 return direct; 428 } 429 430 public void setDirect(int direct) 431 { 432 this.direct = direct; 433 } 434 public Tank(int x,int y) 435 { 436 this.x=x; 437 this.y=y; 438 } 439 440 public int getX() 441 { 442 return x; 443 } 444 public void setX(int x) 445 { 446 this.x = x; 447 } 448 public int getY() 449 { 450 return y; 451 } 452 public void setY(int y) 453 { 454 this.y = y; 455 } 456 457 } 458 459 class EnemyTank extends Tank implements Runnable 460 { 461 boolean isLive=true; 462 463 //定义一个向量,可以存放敌人的子弹 464 465 Vector<Shot> ss=new Vector<Shot>(); 466 //敌人添加子弹应该在刚刚创建坦克和坦克子弹死亡之后 467 468 469 470 public EnemyTank(int x,int y) 471 { 472 super(x,y); 473 474 } 475 public void run() { 476 while(true) 477 { //移动前进 478 switch(this.direct) 479 { 480 case 0: 481 for(int i=0;i<(int)(100*Math.random());i++) 482 { 483 try 484 { 485 Thread.sleep(50); 486 } 487 catch (Exception e) 488 { 489 e.printStackTrace(); 490 } 491 if(y>=speed) 492 { 493 y-=speed; 494 } 495 } 496 break; 497 case 1: 498 for(int i=0;i<(int)(100*Math.random());i++) 499 { 500 try 501 { 502 Thread.sleep(50); 503 } 504 catch (Exception e) 505 { 506 e.printStackTrace(); 507 } 508 if(x<=400-(speed+30)) 509 { 510 x+=speed; 511 } 512 } 513 break; 514 case 2: 515 for(int i=0;i<(int)(100*Math.random());i++) 516 { 517 try 518 { 519 Thread.sleep(50); 520 } 521 catch (Exception e) 522 { 523 e.printStackTrace(); 524 } 525 if(y<=300-(speed+30)) 526 { 527 y+=speed; 528 } 529 } 530 break; 531 case 3: 532 for(int i=0;i<(int)(100*Math.random());i++) 533 { 534 try 535 { 536 Thread.sleep(50); 537 } 538 catch (Exception e) 539 { 540 e.printStackTrace(); 541 } 542 if(x>=speed) 543 { 544 x-=speed; 545 } 546 547 } 548 break; 549 550 } 551 552 //让坦克随机产生一个新的方向 553 if(Math.random()>0.50) 554 this.direct=(int)(Math.random()*4); 555 556 //判断敌人坦克是否死亡 557 if(this.isLive==false) 558 { 559 //让坦克死亡后,退出线程 560 break; 561 } 562 563 } 564 565 } 566 } 567 568 569 //我的坦克 570 class Hero extends Tank 571 { 572 //子弹 573 //Shot s=null; 574 Vector<Shot> ss=new Vector<Shot>(); 575 Shot s=null; 576 577 public Hero(int x, int y) 578 { 579 super(x,y); 580 } 581 //坦克向上移动 582 583 //坦克的开火的能力和动作 584 public void shotEnemy() 585 { 586 switch(this.direct) 587 { 588 case 0: 589 s=new Shot(x+9,y-1,0); 590 ss.add(s); 591 break; 592 case 1: 593 s=new Shot(x+30,y+10,1); 594 ss.add(s); 595 break; 596 case 2: 597 s=new Shot(x+9,y+30,2); 598 ss.add(s); 599 break; 600 case 3: 601 s=new Shot(x-1,y+9,3); ss.add(s); 602 ss.add(s); 603 break; 604 } 605 606 Thread t=new Thread(s); 607 t.start(); 608 609 } 610 611 612 public void moveUp() 613 { 614 this.y-=speed; 615 } 616 public void moveRight() 617 { 618 this.x+=speed; 619 } 620 621 public void moveDown() 622 { 623 this.y+=speed; 624 } 625 public void moveLeft() 626 { 627 this.x-=speed; 628 } 629 } 630 631 class Shot implements Runnable 632 { 633 int x; 634 int y; 635 int direct; 636 int speed=1; 637 //是否活着 638 639 boolean isLive=true; 640 public Shot(int x,int y,int direct) 641 { 642 this.x=x; 643 this.y=y; 644 this.direct=direct; 645 } 646 public void run() 647 { 648 while(true) 649 { 650 try { 651 Thread.sleep(50); 652 } catch (InterruptedException e) { 653 e.printStackTrace(); 654 } 655 656 switch(direct) 657 { 658 case 0: 659 //向上 660 y-=speed;break; 661 case 1: 662 x+=speed;break; 663 case 2: 664 y+=speed;break; 665 case 3: 666 x-=speed;break; 667 668 } 669 670 //子弹何时死亡? 671 //判断该子弹是否碰到边缘 672 if(x<0||x>400||y<0||y>300) 673 { 674 this.isLive=false; 675 break; 676 677 } 678 679 } 680 681 } 682 } 683 class Bomb 684 { 685 //定义炸弹的坐标 686 int x,y; 687 //炸弹的生命 688 int life=9; 689 boolean isLive=true; 690 public Bomb(int x,int y) 691 { 692 this.x=x; 693 this.y=y; 694 } 695 //减少生命值 696 public void lifeDown() 697 { 698 if(life >0) {life--;} 699 else {this.isLive=false;} 700 701 } 702 703 }
Tank大战 version5.0
java练习---->坦克大战5.0
实现功能:
1.在原有基础啊上进行优化和功能完善;
2.增加闯关功能等;
3.完结版!!!!!
1 package TankGame5; 2 3 import java.awt.*; 4 import java.awt.event.ActionEvent; 5 import java.awt.event.ActionListener; 6 import java.awt.event.KeyEvent; 7 import java.awt.event.KeyListener; 8 import java.io.BufferedReader; 9 import java.io.BufferedWriter; 10 import java.io.File; 11 import java.io.FileReader; 12 import java.io.FileWriter; 13 import java.io.IOException; 14 import java.util.*; 15 import java.io.*; 16 import java.util.Vector; 17 import javax.imageio.ImageIO; 18 import javax.swing.*; 19 20 21 public class MyTankGame5 extends JFrame implements ActionListener 22 { 23 //声明一个标志 24 int flag=0; 25 // 声明一个运行面板 26 MyPanel mp=null; 27 //定义一个开始的面板 28 MyStartPanel msp=null; 29 30 //做出我需要的菜单 31 JMenuBar jmb=null; 32 //开始游戏 33 JMenu jm1=null; 34 JMenuItem jmi1=null; 35 //退出系统 36 JMenuItem jmi2=null; 37 JMenuItem jmi3=null; 38 JMenuItem jmi4=null; 39 40 public static void main(String[] args) 41 { 42 MyTankGame5 mytankgame1=new MyTankGame5(); 43 mytankgame1.setLocationRelativeTo(null);//将JFrame设置在中间 44 // mytankgame1.setLocation(210,140);//设置JFrame的位置 45 } 46 47 public MyTankGame5() //构造 48 {//初始化菜单栏 49 jmb=new JMenuBar(); 50 jm1=new JMenu("游戏(G)"); 51 52 //设置快捷方式 53 jm1.setMnemonic('G'); 54 jmi1=new JMenuItem("开始新游戏(N)"); 55 jmi2=new JMenuItem("退出游戏(E)"); 56 jmi3=new JMenuItem("存盘退出(C)"); 57 jmi4=new JMenuItem("继续上次游戏(L)"); 58 59 jmi1.setMnemonic('N'); 60 jmi2.setMnemonic('E'); 61 jmi3.setMnemonic('C'); 62 jmi4.setMnemonic('L'); 63 64 //对jmi1响应,注册监听,标记消息源 65 jmi1.addActionListener(this); 66 jmi1.setActionCommand("new game"); 67 68 jmi2.addActionListener(this); 69 jmi2.setActionCommand("exit"); 70 71 jmi3.addActionListener(this); 72 jmi3.setActionCommand("save and exit"); 73 74 jmi4.addActionListener(this); 75 jmi4.setActionCommand("continue game"); 76 77 jm1.add(jmi1); 78 jm1.add(jmi2); 79 jm1.add(jmi3); 80 jm1.add(jmi4); 81 jmb.add(jm1); 82 83 // 声明初始化面板 84 85 msp=new MyStartPanel(); 86 87 Thread t=new Thread(msp); 88 t.start(); 89 // 初始化窗口,构造函数的重点 90 this.setJMenuBar(jmb);//千万注意啊!!!! 91 92 this.add(msp); 93 this.setSize(400,300); 94 this.setVisible(true); 95 this.setDefaultCloseOperation(EXIT_ON_CLOSE); 96 } 97 public void actionPerformed(ActionEvent e) 98 { 99 //对用户不同的点击做出不同的处理 100 // 首先得到command字符串,判断消息源 101 if(e.getActionCommand().equals("new game")) 102 { 103 this.setSize(600,500); 104 mp=new MyPanel(flag); 105 //启动mp线程 106 107 Thread t1=new Thread(mp); 108 109 t1.start(); 110 //先删除旧的面板 111 this.remove(msp); 112 113 this.add(mp); 114 //注册监听 115 this.addKeyListener(mp); 116 //显示 117 this.setVisible(true); 118 } 119 else if(e.getActionCommand().equals("exit")) 120 { 121 //用户退出 122 //保存击毁敌人数量 123 Recorder.keepRecording(); 124 System.exit(0); 125 } 126 127 else if(e.getActionCommand().equals("save and exit")) 128 { 129 Recorder.keepRecAndEnemyTank(mp.ets); 130 if(this.mp.hero.isLive==true) 131 { 132 Recorder.keepRecAndMyTank(this.mp.hero); 133 134 } 135 System.exit(0); 136 } 137 else if(e.getActionCommand().equals("continue game")) 138 { 139 this.setSize(600,500); 140 flag=1; 141 mp=new MyPanel(flag); 142 //启动mp线程 143 144 Thread t1=new Thread(mp); 145 146 t1.start(); 147 //先删除旧的面板 148 this.remove(msp); 149 150 this.add(mp); 151 //注册监听 152 this.addKeyListener(mp); 153 //显示 154 this.setVisible(true); 155 } 156 } 157 } 158 159 160 //开始面板起一个提示的作用 161 class MyStartPanel extends JPanel implements Runnable 162 { 163 int times=0; 164 public void paint(Graphics g) 165 { 166 super.paint(g); 167 g.fillRect(0, 0, 400, 300); 168 //提示信息 169 if(times%2==0) 170 { 171 g.setColor(Color.yellow); 172 //开关信息的字体 173 try{ 174 Font myFont=new Font("华文新魏",Font.BOLD,30); 175 g.setFont(myFont); 176 } catch(Exception e){e.printStackTrace();} 177 178 g.drawString("stage:1", 150, 150); 179 } 180 } 181 public void run() 182 { 183 while(true) 184 { 185 try { 186 Thread.sleep(500); 187 } catch (Exception e) { 188 // TODO Auto-generated catch block 189 e.printStackTrace(); 190 } 191 this.repaint(); 192 times++; 193 if(times==1000) times=0; 194 } 195 } 196 197 } 198 199 200 class MyPanel extends JPanel implements KeyListener,Runnable 201 { 202 //定义我的坦克,成员变量 203 Hero hero=null; 204 205 //判断是续上局还是新的游戏 206 String flag="newGame"; 207 208 //定义敌人的坦克组 209 210 Vector<EnemyTank> ets=new Vector<EnemyTank>(); 211 // 全局变量,声明,敌人坦克数量 212 static int enSize=5; 213 public static int getEnSize() { 214 return enSize; 215 } 216 //定义炸弹集合 217 Vector<Bomb> bombs=new Vector<Bomb>(); 218 // paint 方法被面板适时自动调用 219 public void paint (Graphics g) 220 { 221 super.paint(g); 222 g.fillRect(0,0,400,300); 223 224 //画出提示信息 225 this.showInfo(g); 226 227 //画出自己的坦克 228 if(hero.isLive==true) 229 { 230 this.drawTank(hero.getX(), hero.getY(), g, this.hero.direct, 1); 231 } 232 //从Vector ss中取出每一颗子弹,并画出,如果有子弹 233 for(int i=0;i<this.hero.ss.size();i++) 234 { 235 Shot myShot=hero.ss.get(i); 236 237 //画出子弹,只画一颗子弹 238 if (myShot!=null&&myShot.isLive==true) 239 { 240 g.draw3DRect(myShot.x, myShot.y, 1, 1, false); 241 242 } 243 if (myShot.isLive==false) 244 { 245 //从ss中删除该子弹 246 hero.ss.remove(myShot); 247 248 } 249 } 250 251 //画出炸弹 252 for(int i=0;i<bombs.size();i++) 253 { 254 // 取出炸弹 255 Bomb b=bombs.get(i); 256 257 if(b.life>6) 258 { 259 g.drawOval(b.x, b.y, 30, 30); 260 // g.drawImage(image1, b.x, b.y, 30,30,this); 261 } 262 else if(b.life>3) 263 { 264 g.drawOval(b.x, b.y, 20, 20); 265 // g.drawImage(image2, b.x, b.y, 30,30,this); 266 267 } 268 else 269 { 270 g.drawOval(b.x, b.y, 10, 10); 271 // g.drawImage(image3, b.x, b.y, 30,30,this); 272 } 273 //让b的生命值减小 274 b.lifeDown(); 275 //如果炸弹的生命值为0,我们就剔除 276 if(b.life==0) bombs.remove(b); 277 278 } 279 280 281 //画出敌人的坦克 282 for(int i=0;i<ets.size();i++) 283 { 284 EnemyTank et=ets.get(i); 285 if(et.isLive) 286 { 287 this.drawTank(ets.get(i).getX(),ets.get(i).getY(), g,ets.get(i).getDirect(), 0); 288 //画出敌人的子弹 289 290 for(int j=0;j<et.ss.size();j++) 291 { 292 //取出子弹 293 Shot enemyShot=et.ss.get(j); 294 if(enemyShot.isLive) 295 { 296 g.draw3DRect(enemyShot.x, enemyShot.y, 1, 1, false); 297 } 298 else 299 { 300 //如果敌人的坦克死亡就从Vector去掉 301 et.ss.remove(enemyShot); 302 303 } 304 305 } 306 } 307 } 308 309 } 310 //判断我是否被击中了 311 public void hitMe() 312 { 313 //取出敌人的每一颗子弹 314 315 for(int i=0;i<this.ets.size();i++) 316 { 317 //取出坦克 318 EnemyTank et=ets.get(i); 319 320 //取出每一颗子弹 321 for (int j=0;j<et.ss.size();j++) 322 { 323 //取出子弹 324 Shot enemyShot=et.ss.get(j); 325 if(hero.isLive)//&&Recorder.getMyLife()>=1 326 { 327 this.hitTank(enemyShot, hero); 328 //Recorder.setMyLife(Recorder.getMyLife()-1); 329 } 330 331 } 332 333 } 334 335 } 336 337 338 //判断我的子弹是否击中敌人的坦克 339 public void hitEnemyTank() 340 { 341 for(int i=0;i<hero.ss.size();i++) 342 { 343 Shot myShot=hero.ss.get(i); 344 //判断子弹是否有效 345 if(myShot.isLive) 346 { 347 //取出每个坦克,与它判断 348 for(int j=0;j<ets.size();j++) 349 { 350 //取出坦克 351 EnemyTank et=ets.get(j); 352 if(et.isLive) 353 { 354 this.hitTank(myShot,et); 355 356 } 357 } 358 359 } 360 } 361 362 } 363 364 //写一个函数专门判断子弹是否击中敌人坦克 365 public void hitTank(Shot s,Tank et) 366 { 367 //判断该坦克的方向 368 switch(et.direct) 369 { 370 //如果敌人的方向是上或者是下 371 case 0: 372 case 2: 373 if (s.x>et.x&&s.x<(et.x+20)&&s.y>et.y&&s.y<(et.y+30)) 374 { 375 //击中了 376 //子弹死亡 377 s.isLive=false; 378 //敌人坦克也要死亡 379 et.isLive=false; 380 //减少敌人数量 381 if (et.getClass()==EnemyTank.class)//反射机制 382 { 383 Recorder.reduceEnNum(); 384 //增加我的记录 385 Recorder.addEnNumRec(); 386 } 387 388 if (et.getClass()==Hero.class)//反射机制 389 { 390 391 } 392 //创建一个炸弹,放入Vector 393 Bomb b=new Bomb(et.x,et.y); 394 //放入Vector 395 bombs.add(b); 396 } 397 case 1: 398 case 3: 399 if (s.x>et.x&&s.x<(et.x+30)&&s.y>et.y&&s.y<(et.y+20)) 400 { 401 //击中了 402 //子弹死亡 403 s.isLive=false; 404 //敌人坦克也要死亡 405 et.isLive=false; 406 //减少敌人数量 407 if (et.getClass()==EnemyTank.class)//反射机制 408 { 409 Recorder.reduceEnNum(); 410 //增加我的记录 411 Recorder.addEnNumRec(); 412 } 413 414 if (et.getClass()==Hero.class)//反射机制 415 { 416 Recorder.setMyLife(Recorder.getMyLife() - 1); 417 } 418 //创建一个炸弹,放入Vector 419 Bomb b=new Bomb(et.x,et.y); 420 //放入Vector 421 bombs.add(b); 422 } 423 424 } 425 426 } 427 428 //画出坦克函数(扩展) 429 public void drawTank(int x,int y,Graphics g,int direct,int type) 430 { 431 //判断类型 432 switch (type) 433 { 434 case 0: 435 g.setColor(Color.cyan);break; 436 case 1: 437 g.setColor(Color.yellow);break; 438 } 439 //判断方向 440 441 switch(direct) 442 { 443 //向上 444 case 0: 445 //画出我的坦克(到时候再封装成一个函数) 446 //1.画出左面的矩形 447 //g.drawRect(hero.getX(), hero.getY(), 5, 30); 448 g.fill3DRect(x,y,5,30,false); 449 450 //2.画出右边的矩形 451 g.fill3DRect(x+15,y,5,30,false); 452 453 //3.画出坦克的中间矩形 454 g.fill3DRect(x+5, y+5, 10, 20,false); 455 //画出中间的圆 456 g.fillOval(x+4, y+10,10,10); 457 //画出线 458 g.drawLine(x+9, y+15, x+9, y); 459 break; 460 case 1: 461 //炮筒向右 462 //画出上面的矩形 463 g.fill3DRect(x,y,30, 5, false); 464 g.fill3DRect(x, y+15, 30, 5, false); 465 g.fill3DRect(x+5, y+5, 20, 10, false); 466 g.fillOval(x+10, y+5, 10, 10); 467 g.drawLine(x+15, y+10, x+30, y+10); 468 469 break; 470 case 2: 471 //向下 472 g.fill3DRect(x,y,5,30,false); 473 g.fill3DRect(x+15,y,5,30,false); 474 g.fill3DRect(x+5, y+5, 10, 20,false); 475 g.fillOval(x+4, y+10,10,10); 476 g.drawLine(x+10, y+15, x+10, y+30); 477 break; 478 479 case 3: 480 //向左 481 g.fill3DRect(x,y,30, 5, false); 482 g.fill3DRect(x, y+15, 30, 5, false); 483 g.fill3DRect(x+5, y+5, 20, 10, false); 484 g.fillOval(x+10, y+5, 10, 10); 485 g.drawLine(x+15, y+10, x, y+10); 486 break; 487 } 488 489 } 490 491 492 public void run() 493 { 494 //每个一百毫秒去重画子弹 495 while(true) 496 { 497 try { 498 Thread.sleep(100); 499 } catch (InterruptedException e) { 500 e.printStackTrace(); 501 } 502 503 504 this.hitEnemyTank(); 505 506 //函数,判断敌人的子弹是否击中我了 507 this.hitMe(); 508 509 this.repaint(); 510 //判断是否需要给坦克加入新的子弹 511 for(int i=0;i<ets.size();i++) 512 { 513 EnemyTank et=ets.get(i); 514 if(et.isLive) 515 { 516 if (et.ss.size()<3) 517 { 518 //没有子弹了 519 //添加 520 Shot s=null; 521 switch(et.direct) 522 { 523 case 0: 524 s=new Shot(et.x+9,et.y-1,0); 525 et.ss.add(s); 526 break; 527 case 1: 528 s=new Shot(et.x+30,et.y+10,1); 529 et.ss.add(s); 530 break; 531 case 2: 532 s=new Shot(et.x+9,et.y+30,2); 533 et.ss.add(s); 534 break; 535 case 3: 536 s=new Shot(et.x-1,et.y+9,3); 537 et.ss.add(s); 538 break; 539 } 540 541 //启动子弹线程 542 Thread t=new Thread(s); 543 t.start(); 544 } 545 } 546 } 547 } 548 } 549 //定义三张图片,三张图片切换组成一颗炸弹 550 Image image1=null; 551 Image image2=null; 552 Image image3=null; 553 int flagOfContinue; 554 //构造函数 555 public MyPanel(int flag) 556 { 557 558 this.flagOfContinue=flag; 559 //恢复记录 560 Recorder.getRecording(); 561 562 563 if(this.flagOfContinue==0) 564 { 565 //如果不是继续上次就直接建一个 566 hero=new Hero(100,100); 567 //初始化敌人的坦克 568 for(int i=0;i<enSize;i++) 569 { 570 //创建敌人的坦克对象 571 EnemyTank et=new EnemyTank((i+1)*60,0); 572 et.setColor(0); 573 et.setDirect(2); 574 //将MyPanel的敌人坦克向量交给该敌人坦克 575 et.setEts(ets); 576 577 578 //启动敌人的坦克 579 580 Thread t=new Thread(et); 581 t.start(); 582 //给敌人坦克添加一颗子弹 583 Shot s=new Shot(et.x+10,et.y+30,2); 584 et.ss.add(s); 585 Thread t2=new Thread(s); 586 t2.start(); 587 //加入 588 589 ets.add(et); 590 } 591 } 592 else if(this.flagOfContinue==1) 593 { 594 //如果是继续上次的就读取坐标 595 Vector<Node> nodes1=new Vector<Node>(); 596 nodes1=Recorder.getNodes(); 597 598 //初始化敌人的坦克 599 for(int i=0;i<nodes1.size();i++) 600 { 601 if(nodes1.get(i).type==0) 602 { 603 //创建敌人的坦克对象 604 EnemyTank et=new EnemyTank(nodes1.get(i).x,nodes1.get(i).y); 605 et.setColor(0); 606 et.setDirect(nodes1.get(i).direct); 607 //将MyPanel的敌人坦克向量交给该敌人坦克 608 et.setEts(ets); 609 610 611 //启动敌人的坦克 612 613 Thread t=new Thread(et); 614 t.start(); 615 //给敌人坦克添加一颗子弹 616 Shot s=new Shot(et.x+10,et.y+30,2); 617 et.ss.add(s); 618 Thread t2=new Thread(s); 619 t2.start(); 620 //加入 621 622 ets.add(et); 623 } 624 else if(nodes1.get(i).type==1) 625 { 626 //如果保存有我上次的坦克的信息,就按照信息保存 627 hero=new Hero(nodes1.get(i).x,nodes1.get(i).y); 628 hero.setDirect(nodes1.get(i).direct); 629 } 630 } 631 632 } 633 634 // image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/33.jpg"));//文件应该放在src文件夹里面 635 // image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/22.jpg")); 636 // image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/11.jpg")); 637 //关于图像我们使用好一点的方法,引入java.io.File;和java.io.IOException; 638 try 639 { 640 image1=ImageIO.read(new File("33.jpg"));//此时文件应该放在工程的根目录里面 641 image2=ImageIO.read(new File("22.jpg")); 642 image3=ImageIO.read(new File("11.jpg")); 643 } 644 catch (IOException e) 645 { 646 e.printStackTrace(); 647 } 648 649 } 650 //画出提示信息 651 public void showInfo(Graphics g) 652 { 653 //画出提示信息的坦克 ,该坦克不参加战斗 654 this.drawTank(80,330,g,0,0); 655 g.setColor(Color.black); 656 g.drawString(Recorder.getEnNum()+"",110,350); 657 658 this.drawTank(150,330,g,0,1); 659 g.setColor(Color.black); 660 g.drawString(Recorder.getMyLife()+"",180,350); 661 //画出玩家的总成绩 662 663 g.setColor(Color.black); 664 try{ 665 Font f=new Font("宋体",Font.BOLD,20); 666 g.setFont(f); 667 }catch(Exception e){ e.printStackTrace();} 668 g.drawString("您的总成绩:",420,40); 669 670 this.drawTank(420, 60, g, 0, 0); 671 672 g.setColor(Color.BLACK); 673 g.drawString(Recorder.getAllEnemy()+"",460,80); 674 675 } 676 677 //键按下处理a表示左,s表示向下,w表示向上,d表示向右 678 public void keyPressed(KeyEvent e) 679 { 680 if(hero.isLive) 681 { 682 if(e.getKeyCode()==KeyEvent.VK_UP&&hero.getY()>0) 683 { 684 // 设置我的坦克的方向 685 this.hero.setDirect(0); 686 this.hero.moveUp(); 687 } 688 689 else if (e.getKeyCode()==KeyEvent.VK_DOWN&&hero.getY()<270) 690 { 691 this.hero.setDirect(2); 692 this.hero.moveDown(); 693 } 694 695 else if (e.getKeyCode()==KeyEvent.VK_RIGHT&&hero.getX()<370) 696 { 697 this.hero.setDirect(1); 698 this.hero.moveRight(); 699 700 } 701 else if (e.getKeyCode()==KeyEvent.VK_LEFT&&hero.getX()>0) 702 { 703 this.hero.setDirect(3); 704 this.hero.moveLeft(); 705 } 706 707 if (e.getKeyCode()==KeyEvent.VK_SPACE) 708 { 709 this.hero.shotEnemy(); 710 } 711 712 //必须重新绘制Panel 713 this.repaint(); 714 } 715 } 716 public void keyReleased(KeyEvent e) 717 { 718 719 } 720 public void keyTyped(KeyEvent e) 721 { 722 723 } 724 725 } 726 727 728 //---------------------------------------------------- 729 730 class Node 731 { 732 int x; 733 int y; 734 int direct; 735 int type; 736 public Node(int x,int y,int direct,int type) 737 { 738 this.x=x; 739 this.y=y; 740 this.direct=direct; 741 this.type=type; 742 } 743 744 } 745 746 747 748 //记录类 749 class Recorder 750 { 751 public static int getEnNum() { 752 return enNum; 753 } 754 public static void setEnNum(int enNum) { 755 Recorder.enNum = enNum; 756 } 757 public static int getMyLife() { 758 return myLife; 759 } 760 public static void setMyLife(int myLife) { 761 Recorder.myLife = myLife; 762 } 763 //记录每关多少敌人 764 private static int enNum=MyPanel.getEnSize(); 765 //设置我有多少可以用的人 766 public static int myLife=3; 767 //记录总共消灭了多少敌人 768 private static int allEnNum=0; 769 //从文件中恢复记录点 770 static Vector<Node> nodes=new Vector<Node>(); 771 private static FileWriter fw=null; 772 private static BufferedWriter bw=null; 773 private static FileReader fr=null; 774 private static BufferedReader br=null; 775 776 public static Vector<Node> getNodes() 777 { 778 try { 779 fr=new FileReader("d:\\myRecording.txt"); 780 br=new BufferedReader(fr); 781 String n=""; 782 783 n=br.readLine();//读第一行 784 allEnNum=Integer.parseInt(n); 785 while((n=br.readLine())!=null) 786 { 787 String []xyz=n.split(" ");//按照空格返回数组,新技能 788 Node node=new Node(Integer.parseInt(xyz[0]),Integer.parseInt(xyz[1]),Integer.parseInt(xyz[2]),Integer.parseInt(xyz[3])); 789 nodes.add(node); 790 } 791 } 792 793 catch (Exception e) 794 { 795 e.printStackTrace(); 796 } 797 finally 798 { 799 try { 800 br.close(); 801 fr.close(); 802 } catch (Exception e) { 803 e.printStackTrace(); 804 } 805 } 806 return nodes; 807 } 808 public static void keepRecAndEnemyTank(Vector<EnemyTank> ets) 809 { 810 try 811 { 812 //创建 813 fw=new FileWriter("d:\\myRecording.txt"); 814 bw=new BufferedWriter(fw); 815 816 bw.write(allEnNum+"\r\n"); 817 818 //保存当前还活着的敌人坐标和方向 819 for(int i=0;i<ets.size();i++) 820 { 821 //取出第一个坦克 822 EnemyTank et=ets.get(i); 823 if(et.isLive) 824 { 825 //活着的保存 826 String record=et.x+" "+et.y+" "+et.direct+" "+0; 827 //写入 828 bw.write(record+"\r\n"); 829 } 830 } 831 832 } 833 catch (Exception e) 834 { 835 e.printStackTrace(); 836 } 837 finally 838 { 839 //关闭流 840 try { 841 //谁先开谁后关 842 bw.close(); 843 fw.close(); 844 } catch (Exception e2) { 845 } 846 } 847 848 } 849 850 public static void keepRecAndMyTank(Hero hero) 851 { 852 try 853 { 854 //创建 855 fw=new FileWriter("d:\\myRecording.txt",true);//追加 856 bw=new BufferedWriter(fw); 857 858 //保存当前我的坐标和方向 859 String record=hero.x+" "+hero.y+" "+hero.direct+" "+1; 860 //写入 861 bw.write(record+"\r\n"); 862 863 } 864 865 catch (Exception e) 866 { 867 e.printStackTrace(); 868 } 869 finally 870 { 871 //关闭流 872 try 873 { 874 //谁先开谁后关 875 bw.close(); 876 fw.close(); 877 } 878 catch (Exception e2) 879 { 880 e2.printStackTrace(); 881 } 882 } 883 884 } 885 886 //从文件中读取记录 887 public static void getRecording() 888 { 889 try { 890 fr=new FileReader("d:\\myRecording.txt"); 891 br=new BufferedReader(fr); 892 String n=br.readLine(); 893 allEnNum=Integer.parseInt(n); 894 } 895 catch (Exception e) 896 { 897 e.printStackTrace(); 898 } 899 finally 900 { 901 try { 902 br.close(); 903 fr.close(); 904 } catch (Exception e) { 905 e.printStackTrace(); 906 } 907 } 908 909 } 910 //把玩家击毁敌人的坦克数量保存到文件中 911 public static void keepRecording() 912 { 913 try 914 { 915 //创建 916 fw=new FileWriter("d:\\myRecording.txt"); 917 bw=new BufferedWriter(fw); 918 919 bw.write(allEnNum+"\r\n"); 920 } 921 catch (Exception e) 922 { 923 e.printStackTrace(); 924 } 925 finally 926 { 927 //关闭流 928 try { 929 //谁先开谁后关 930 bw.close(); 931 fw.close(); 932 } catch (Exception e2) { 933 } 934 } 935 } 936 937 public static int getAllEnemy() { 938 return allEnNum; 939 } 940 public static void reduceEnNum() 941 { 942 enNum--; 943 } 944 945 //消灭敌人 946 public static void addEnNumRec() 947 { 948 allEnNum++; 949 } 950 951 } 952 953 954 class Bomb 955 { 956 //定义炸弹的坐标 957 int x,y; 958 //炸弹的生命 959 int life=9; 960 boolean isLive=true; 961 public Bomb(int x,int y) 962 { 963 this.x=x; 964 this.y=y; 965 } 966 //减少生命值 967 public void lifeDown() 968 { 969 if(life >0) {life--;} 970 else {this.isLive=false;} 971 972 } 973 } 974 975 976 class Tank 977 { 978 979 //设置坦克的速度 980 int speed=3; 981 public int getSpeed() 982 { 983 return speed; 984 } 985 public void setSpeed(int speed) 986 { 987 this.speed = speed; 988 } 989 //表示坦克的横坐标 990 int x=0; 991 //坦克的纵坐标 992 int y=0; 993 int direct=0; 994 int color; 995 boolean isLive=true; 996 997 //坦克方向,0表示上,1表示右,2表示下,3表示左 998 public int getColor() { 999 return color; 1000 } 1001 public void setColor(int color) { 1002 this.color = color; 1003 } 1004 public int getDirect() 1005 { 1006 return direct; 1007 } 1008 1009 public void setDirect(int direct) 1010 { 1011 this.direct = direct; 1012 } 1013 public Tank(int x,int y) 1014 { 1015 this.x=x; 1016 this.y=y; 1017 } 1018 1019 public int getX() 1020 { 1021 return x; 1022 } 1023 public void setX(int x) 1024 { 1025 this.x = x; 1026 } 1027 public int getY() 1028 { 1029 return y; 1030 } 1031 public void setY(int y) 1032 { 1033 this.y = y; 1034 } 1035 1036 } 1037 1038 1039 class EnemyTank extends Tank implements Runnable 1040 { 1041 //定义一个向量,可以访问到MyPanel上所有敌人的坦克 1042 Vector<EnemyTank> ets=new Vector<EnemyTank>(); 1043 1044 //定义一个向量,可以存放敌人的子弹 1045 1046 Vector<Shot> ss=new Vector<Shot>(); 1047 //敌人添加子弹应该在刚刚创建坦克和坦克子弹死亡之后 1048 public EnemyTank(int x,int y) 1049 { 1050 super(x,y); 1051 } 1052 1053 //得到MyPanel的敌人坦克向量 1054 public void setEts(Vector<EnemyTank> vv) 1055 { 1056 this.ets=vv; 1057 1058 } 1059 1060 1061 //判断是否碰到了别人的坦克 1062 public boolean isTouchOtherEnemy() 1063 { 1064 boolean b=false; 1065 1066 switch(this.direct) 1067 { 1068 case 0: 1069 1070 //我的坦克向上 1071 //取出所有的敌人坦克 1072 for(int i=0;i<ets.size();i++) 1073 { 1074 //取出第一个坦克 1075 EnemyTank et=ets.get(i); 1076 //如果不是自己 1077 if(et!=this) 1078 { 1079 //如果敌人的方向向上或者是向下 1080 if(et.direct==0||et.direct==2) 1081 { 1082 if(this.x>=et.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30) 1083 { 1084 return true; 1085 } 1086 if(this.x+20>=et.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30) 1087 { 1088 return true; 1089 } 1090 1091 } 1092 1093 if(et.direct==1||et.direct==3) 1094 { 1095 if(this.x>=et.x&&this.x<=et.x+30&&this.y>=et.y&&this.y<=et.y+20) 1096 { 1097 return true; 1098 } 1099 if(this.x+20>=et.x && this.x+20<=et.x+30&&this.y>=et.y&&this.y<=et.y+30) 1100 { 1101 return true; 1102 } 1103 } 1104 } 1105 1106 } 1107 1108 break; 1109 case 1: 1110 //坦克向右 1111 //取出所有的敌人坦克 1112 for(int i=0;i<ets.size();i++) 1113 { 1114 //取出第一个坦克 1115 EnemyTank et=ets.get(i); 1116 //如果不是自己 1117 if(et!=this) 1118 { 1119 //如果敌人的方向向上或者是向下 1120 if(et.direct==0||et.direct==2) 1121 { 1122 if(this.x+30>=et.x&&this.x+30<=et.x+20&&this.y>=et.y&&this.y<=et.y+30) 1123 { 1124 return true; 1125 } 1126 if(this.x+30>=et.x&&this.x+30<=et.x+20&&this.y+20>=et.y&&this.y+20<=et.y+30) 1127 { 1128 return true; 1129 } 1130 1131 } 1132 1133 if(et.direct==1||et.direct==3) 1134 { 1135 if(this.x+30>=et.x&&this.x+30<=et.x+30&&this.y>=et.y&&this.y<=et.y+20) 1136 { 1137 return true; 1138 } 1139 if(this.x+30>=et.x && this.x+30<=et.x+30&&this.y+20>=et.y&&this.y+20<=et.y+20) 1140 { 1141 return true; 1142 } 1143 } 1144 } 1145 1146 } 1147 1148 1149 case 2: 1150 //坦克向下 1151 //取出所有的敌人坦克 1152 for(int i=0;i<ets.size();i++) 1153 { 1154 //取出第一个坦克 1155 EnemyTank et=ets.get(i); 1156 //如果不是自己 1157 if(et!=this) 1158 { 1159 //如果敌人的方向向上或者是向下 1160 if(et.direct==0||et.direct==2) 1161 { 1162 if(this.x>=et.x&&this.x<=et.x+20&&this.y+30>=et.y&&this.y+30<=et.y+30) 1163 { 1164 return true; 1165 } 1166 if(this.x+20>=et.x&&this.x<=et.x+20&&this.y+30>=et.y&&this.y+30<=et.y+30) 1167 { 1168 return true; 1169 } 1170 1171 } 1172 1173 if(et.direct==1||et.direct==3) 1174 { 1175 if(this.x+20>=et.x&&this.x+20<=et.x+30&&this.y+30>=et.y&&this.y+30<=et.y+20) 1176 { 1177 return true; 1178 } 1179 if(this.x+20>=et.x && this.x+20<=et.x+30&&this.y+30>=et.y&&this.y+30<=et.y+30) 1180 { 1181 return true; 1182 } 1183 } 1184 } 1185 1186 } 1187 break; 1188 case 3 : 1189 //坦克向左 1190 //取出所有的敌人坦克 1191 for(int i=0;i<ets.size();i++) 1192 { 1193 //取出第一个坦克 1194 EnemyTank et=ets.get(i); 1195 //如果不是自己 1196 if(et!=this) 1197 { 1198 //如果敌人的方向向上或者是向下 1199 if(et.direct==0||et.direct==2) 1200 { 1201 if(this.x>=et.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30) 1202 { 1203 return true; 1204 } 1205 if(this.x>=et.x&&this.x<=et.x+20&&this.y>=et.y&&this.y<=et.y+30) 1206 { 1207 return true; 1208 } 1209 1210 } 1211 1212 if(et.direct==1||et.direct==3) 1213 { 1214 if(this.x>=et.x&&this.x<=et.x+30&&this.y+20>=et.y&&this.y+20<=et.y+20) 1215 { 1216 return true; 1217 } 1218 if(this.x>=et.x && this.x<=et.x+30&&this.y+20>=et.y&&this.y+20<=et.y+20) 1219 { 1220 return true; 1221 } 1222 } 1223 } 1224 1225 } 1226 } 1227 1228 return b; 1229 } 1230 1231 public void run() { 1232 while(true) 1233 { 1234 switch(this.direct) 1235 { 1236 case 0: 1237 for(int i=0;i<(int)(100*Math.random());i++) 1238 { 1239 try 1240 { 1241 Thread.sleep(50); 1242 } 1243 catch (Exception e) 1244 { 1245 e.printStackTrace(); 1246 } 1247 if(y>=speed && !this.isTouchOtherEnemy()) 1248 { 1249 y-=speed; 1250 } 1251 } 1252 break; 1253 case 1: 1254 for(int i=0;i<(int)(100*Math.random());i++) 1255 { 1256 try 1257 { 1258 Thread.sleep(50); 1259 } 1260 catch (Exception e) 1261 { 1262 e.printStackTrace(); 1263 } 1264 if(x<=(400-(speed+30))&& !this.isTouchOtherEnemy()) 1265 { 1266 x+=speed; 1267 } 1268 } 1269 break; 1270 case 2: 1271 for(int i=0;i<(int)(100*Math.random());i++) 1272 { 1273 try 1274 { 1275 Thread.sleep(50); 1276 } 1277 catch (Exception e) 1278 { 1279 e.printStackTrace(); 1280 } 1281 if(y<=(300-(speed+30))&& !this.isTouchOtherEnemy()) 1282 { 1283 y+=speed; 1284 } 1285 } 1286 break; 1287 case 3: 1288 for(int i=0;i<(int)(100*Math.random());i++) 1289 { 1290 try 1291 { 1292 Thread.sleep(50); 1293 } 1294 catch (Exception e) 1295 { 1296 e.printStackTrace(); 1297 } 1298 if(x>=speed && !this.isTouchOtherEnemy()) 1299 { 1300 x-=speed; 1301 } 1302 1303 } 1304 break; 1305 1306 } 1307 1308 //让坦克随机产生一个新的方向 1309 this.direct=(int)(Math.random()*4); 1310 1311 //判断敌人坦克是否死亡 1312 if(this.isLive==false) 1313 { 1314 //让坦克死亡后,退出线程 1315 break; 1316 } 1317 1318 } 1319 1320 } 1321 } 1322 1323 1324 //我的坦克 1325 class Hero extends Tank 1326 { 1327 //子弹 1328 //Shot s=null; 1329 Vector<Shot> ss=new Vector<Shot>(); 1330 Shot s=null; 1331 1332 public Hero(int x, int y) 1333 { 1334 super(x,y); 1335 } 1336 //坦克向上移动 1337 1338 //坦克的开火的能力和动作 1339 public void shotEnemy() 1340 { 1341 switch(this.direct) 1342 { 1343 case 0: 1344 s=new Shot(x+9,y-1,0); 1345 ss.add(s); 1346 break; 1347 case 1: 1348 s=new Shot(x+30,y+10,1); 1349 ss.add(s); 1350 break; 1351 case 2: 1352 s=new Shot(x+9,y+30,2); 1353 ss.add(s); 1354 break; 1355 case 3: 1356 s=new Shot(x-1,y+9,3); ss.add(s); 1357 ss.add(s); 1358 break; 1359 } 1360 1361 Thread t=new Thread(s); 1362 t.start(); 1363 1364 } 1365 1366 1367 public void moveUp() 1368 { 1369 this.y-=speed; 1370 } 1371 public void moveRight() 1372 { 1373 this.x+=speed; 1374 } 1375 1376 public void moveDown() 1377 { 1378 this.y+=speed; 1379 } 1380 public void moveLeft() 1381 { 1382 this.x-=speed; 1383 } 1384 } 1385 1386 class Shot implements Runnable 1387 { 1388 int x; 1389 int y; 1390 int direct; 1391 int speed=2; 1392 //是否活着 1393 1394 boolean isLive=true; 1395 public Shot(int x,int y,int direct) 1396 { 1397 this.x=x; 1398 this.y=y; 1399 this.direct=direct; 1400 } 1401 public void run() 1402 { 1403 while(true) 1404 { 1405 try { 1406 Thread.sleep(50); 1407 } catch (InterruptedException e) { 1408 e.printStackTrace(); 1409 } 1410 1411 switch(direct) 1412 { 1413 case 0: 1414 //向上 1415 y-=speed;break; 1416 case 1: 1417 x+=speed;break; 1418 case 2: 1419 y+=speed;break; 1420 case 3: 1421 x-=speed;break; 1422 1423 } 1424 1425 //子弹何时死亡? 1426 //判断该子弹是否碰到边缘 1427 if(x<0||x>400||y<0||y>300) 1428 { 1429 this.isLive=false; 1430 break; 1431 1432 } 1433 1434 } 1435 1436 } 1437 }
注:如果大家很多java基础内容不是很清楚,可以观看韩顺平的java学习视频,跟着教程做程序,效果很明显!(●ˇ∀ˇ●)