今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过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://敌人的tank102 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 Vectorets=new Vector (); 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 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 Vectorets=new Vector (); 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 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 ss=new Vector ();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 Runnable419 {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 Vectorets=new Vector (); 42 int enSize=5; 43 44 //定义炸弹集合 45 Vector bombs=new Vector (); 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 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 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 else168 {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 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 //创建一个炸弹,放入Vector227 Bomb b=new Bomb(et.x,et.y);228 //放入Vector229 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 //创建一个炸弹,放入Vector241 Bomb b=new Bomb(et.x,et.y);242 //放入Vector243 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 ss=new Vector ();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 try484 {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 try501 {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 try518 {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 try535 {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 Tank571 {572 //子弹573 //Shot s=null;574 Vector ss=new Vector ();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 Runnable632 {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 Bomb684 {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 Vectorets=new Vector (); 211 // 全局变量,声明,敌人坦克数量 212 static int enSize=5; 213 public static int getEnSize() { 214 return enSize; 215 } 216 //定义炸弹集合 217 Vector bombs=new Vector (); 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 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 =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 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 nodes1=new Vector (); 596 nodes1=Recorder.getNodes(); 597 598 //初始化敌人的坦克 599 for(int i=0;i 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 nodes=new Vector (); 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 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 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 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 Runnable1040 {1041 //定义一个向量,可以访问到MyPanel上所有敌人的坦克1042 Vector ets=new Vector ();1043 1044 //定义一个向量,可以存放敌人的子弹1045 1046 Vector ss=new Vector ();1047 //敌人添加子弹应该在刚刚创建坦克和坦克子弹死亡之后1048 public EnemyTank(int x,int y)1049 {1050 super(x,y); 1051 }1052 1053 //得到MyPanel的敌人坦克向量1054 public void setEts(Vector 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 =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 =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 =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 =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 try1240 {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 try1257 {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 try1274 {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 try1291 {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 Tank1326 {1327 //子弹1328 //Shot s=null;1329 Vector ss=new Vector ();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 Runnable1387 {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学习视频,跟着教程做程序,效果很明显!(●ˇ∀ˇ●)