坦克大战(版本1.0-版本1.6)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了坦克大战(版本1.0-版本1.6)相关的知识,希望对你有一定的参考价值。
版本1.0
功能: 添加子弹类
步骤: 1)添加Missile类;
2)添加x,y,dir等属性以及常量;
3)添加构造方法、draw方法等必要方法;
4)根据不同方向,进行不同的运动;
5)在TankClient中模拟一颗子弹;
6)new一颗子弹出来;
7)画出来
注意: 不一定一次写到位,进行多次试验,将步骤分解开来逐一进行调试;
具体代码实现:
Tank:
1 import java.awt.*; 2 import java.awt.event.*; 3 4 public class Tank { 5 // 方便后期更改 6 public static final int XSPEED = 5; 7 public static final int YSPEED = 5; 8 private int x; 9 private int y; 10 // 添加记录按键状态的布尔量 11 private boolean bL = false; 12 private boolean bR = false; 13 private boolean bU = false; 14 private boolean bD = false; 15 16 // 添加代表方向的量(使用枚举) 17 enum Direction { 18 L, R, U, D, LU, LD, RU, RD, STOP 19 }; 20 21 private Direction dir = Direction.STOP; 22 23 public Tank(int x, int y) { 24 this.x = x; 25 this.y = y; 26 } 27 28 // Tank对象的draw方法 29 public void draw(Graphics g) { 30 Color c = g.getColor(); 31 g.setColor(Color.RED); 32 g.fillOval(x, y, 30, 30); 33 g.setColor(c); 34 move(); 35 } 36 37 public void move() { 38 switch (dir) { 39 case L: 40 x -= XSPEED; 41 break; 42 case R: 43 x += XSPEED; 44 break; 45 case U: 46 y -= YSPEED; 47 break; 48 case D: 49 y += YSPEED; 50 break; 51 case LU: 52 x -= XSPEED; 53 y -= YSPEED; 54 break; 55 case LD: 56 x -= XSPEED; 57 y += YSPEED; 58 break; 59 case RU: 60 x += XSPEED; 61 y -= YSPEED; 62 break; 63 case RD: 64 x += XSPEED; 65 y += YSPEED; 66 break; 67 68 case STOP: 69 break; 70 } 71 } 72 73 public void locateDirection() { 74 if (bL && !bU && !bR && !bD) 75 dir = Direction.L; 76 else if (bL && bU && !bR && !bD) 77 dir = Direction.LU; 78 else if (!bL && bU && !bR && !bD) 79 dir = Direction.U; 80 else if (!bL && bU && bR && !bD) 81 dir = Direction.RU; 82 else if (!bL && !bU && bR && !bD) 83 dir = Direction.R; 84 else if (!bL && !bU && bR && bD) 85 dir = Direction.RD; 86 else if (!bL && !bU && !bR && bD) 87 dir = Direction.D; 88 else if (bL && !bU && !bR && bD) 89 dir = Direction.LD; 90 else if (!bL && !bU && !bR && !bD) 91 dir = Direction.STOP; 92 93 } 94 95 // 坦克自己向哪个方向移动,它自己最清楚; 96 public void KeyPressed(KeyEvent e) { 97 // 获得所按下的键所对应的虚拟码: 98 // Returns the integer keyCode associated with the key in this event 99 int key = e.getKeyCode(); 100 // 判断不同的按键,指挥坦克的运动方向 101 switch (key) { 102 case KeyEvent.VK_LEFT: 103 bL = true; 104 break; 105 case KeyEvent.VK_UP: 106 bU = true; 107 break; 108 case KeyEvent.VK_RIGHT: 109 bR = true; 110 break; 111 case KeyEvent.VK_DOWN: 112 bD = true; 113 break; 114 } 115 locateDirection(); 116 } 117 118 public void keyReleased(KeyEvent e) { 119 int key = e.getKeyCode(); 120 // 判断不同的按键,指挥坦克的运动方向 121 // 哪个键按下了,就把对应方向的布尔类型置为false 122 switch (key) { 123 case KeyEvent.VK_LEFT: 124 bL = false; 125 break; 126 case KeyEvent.VK_UP: 127 bU = false; 128 break; 129 case KeyEvent.VK_RIGHT: 130 bR = false; 131 break; 132 case KeyEvent.VK_DOWN: 133 bD = false; 134 break; 135 } 136 // 重新定位一下 137 locateDirection(); 138 } 139 }
Missile:新添加的子弹类
1 import java.awt.Color; 2 import java.awt.Graphics; 3 4 public class Missile { 5 //炮弹的移动速度,不要比坦克的移动速度慢,不然你看到的是满屏的坦克追着炮弹跑 6 public static final int XSPEED=10; 7 public static final int YSPEED=10; 8 //炮弹自己的三个属性 9 int x; 10 int y; 11 Tank.Direction dir; 12 public Missile(int x, int y, Tank.Direction dir) { 13 this.x = x; 14 this.y = y; 15 this.dir = dir; 16 } 17 //炮弹自己的draw方法 18 public void draw(Graphics g){ 19 Color c=g.getColor(); 20 g.setColor(Color.BLACK); 21 //炮弹形状不要比坦克大,这里设置成10,10; 22 g.fillOval(x, y, 10, 10); 23 g.setColor(c); 24 move(); 25 } 26 public void move() { 27 switch (dir) { 28 case L: 29 x -= XSPEED; 30 break; 31 case R: 32 x += XSPEED; 33 break; 34 case U: 35 y -= YSPEED; 36 break; 37 case D: 38 y += YSPEED; 39 break; 40 case LU: 41 x -= XSPEED; 42 y -= YSPEED; 43 break; 44 case LD: 45 x -= XSPEED; 46 y += YSPEED; 47 break; 48 case RU: 49 x += XSPEED; 50 y -= YSPEED; 51 break; 52 case RD: 53 x += XSPEED; 54 y += YSPEED; 55 break; 56 //炮弹就没有STOP这个枚举类型的值了 57 /* case STOP: 58 break;*/ 59 } 60 } 61 }
TankClient:在TankClient中模拟一颗子弹
1 import java.awt.*; 2 import java.awt.event.*; 3 4 public class TankClient extends Frame { 5 // 设置成常量,方便以后的改动 6 public static final int GAME_WIDTH = 800; 7 public static final int GAME_HEIGHT = 600; 8 Tank myTank = new Tank(50, 50); 9 10 // 在TankClient中定义炮弹 11 Missile m = new Missile(50, 50, Tank.Direction.R); 12 // 定义虚拟图片,方便后期的一次性显示 13 Image offScreenImage = null; 14 15 public void paint(Graphics g) { 16 // 把炮弹画出来 17 m.draw(g); 18 // 不改变前景色 19 myTank.draw(g); 20 } 21 22 // 刷新操作 23 public void update(Graphics g) { 24 if (offScreenImage == null) { 25 offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT); 26 } 27 Graphics gOffScreen = offScreenImage.getGraphics(); 28 Color c = gOffScreen.getColor(); 29 gOffScreen.setColor(Color.GREEN); 30 gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT); 31 gOffScreen.setColor(c); 32 paint(gOffScreen); 33 g.drawImage(offScreenImage, 0, 0, null); 34 } 35 36 public void lauchFrame() { 37 this.setLocation(400, 300); 38 this.setSize(GAME_WIDTH, GAME_HEIGHT); 39 this.setTitle("TankWar"); 40 this.addWindowListener(new WindowAdapter() { 41 public void windowClosing(WindowEvent e) { 42 System.exit(0); 43 } 44 }); 45 this.setResizable(false); 46 this.setBackground(Color.GREEN); 47 48 this.addKeyListener(new KeyMonitor()); 49 50 setVisible(true); 51 52 new Thread(new PaintThread()).start(); 53 } 54 55 public static void main(String[] args) { 56 TankClient tc = new TankClient(); 57 tc.lauchFrame(); 58 } 59 60 private class PaintThread implements Runnable { 61 62 public void run() { 63 while (true) { 64 repaint(); 65 try { 66 Thread.sleep(50); 67 } catch (InterruptedException e) { 68 e.printStackTrace(); 69 } 70 } 71 } 72 } 73 74 // 创建键盘时间监听 75 private class KeyMonitor extends KeyAdapter { 76 77 // 直接调用myTank自己的方法根据相应的按键信息进行移动 78 public void keyPressed(KeyEvent e) { 79 myTank.KeyPressed(e); 80 // 添加了处理键抬起的事件,可以控制坦克起步以后的状态 81 // 而不是一直按照一个方向走下去 82 } 83 public void keyReleased(KeyEvent e){ 84 myTank.keyReleased(e); 85 } 86 87 } 88 }
版本1.1
功能:根据主战坦克的方向和位置,打出子弹,让子弹从坦克的中心打出来;
步骤:
1)增加对Ctrl键的按键处理;
2)根据“坦克打出一发子弹”这句话,来确定Tank中的方法fire,其返回值为Missle;
3)根据Tank方向和位置设定子弹的方向和位置并new出来,然后返回(fire方法的实现)
注意: 掌握面向对象的思维方式来确定类应该具有的方法
下面这个图中左上角是坦克的的位置(x,y),圆心中心是坦克的中心,w是坦克的宽度,h是坦克的高度,我们计算炮弹的位置可以通过下面的公式计算:
注意x轴向右递增,y轴向下递增;
int x=this.x+Tank.WIDTH/2-Missile.WIDTH/2; int y=this.y+Tank.HEIGHT/2-Missile.HEIGHT/2;
具体代码实现:
Tank:
1 import java.awt.*; 2 import java.awt.event.*; 3 4 public class Tank { 5 // 方便后期更改 6 public static final int XSPEED = 5; 7 public static final int YSPEED = 5; 8 // 将坦克的高度和宽度设置为常量 9 public static final int WIDTH = 30; 10 public static final int HEIGHT = 30; 11 TankClient tc = null; 12 private int x; 13 private int y; 14 // 添加记录按键状态的布尔量 15 private boolean bL = false; 16 private boolean bR = false; 17 private boolean bU = false; 18 private boolean bD = false; 19 20 // 添加代表方向的量(使用枚举) 21 enum Direction { 22 L, R, U, D, LU, LD, RU, RD, STOP 23 }; 24 25 private Direction dir = Direction.STOP; 26 27 public Tank(int x, int y) { 28 this.x = x; 29 this.y = y; 30 } 31 32 public Tank(int x, int y, TankClient tc) { 33 // 调用那个有两个参数的构造方法 34 this(x, y); 35 // 在这个位置初始化tc 36 this.tc = tc; 37 } 38 39 // Tank对象的draw方法 40 public void draw(Graphics g) { 41 Color c = g.getColor(); 42 g.setColor(Color.RED); 43 g.fillOval(x, y, WIDTH, HEIGHT); 44 g.setColor(c); 45 move(); 46 } 47 48 public void move() { 49 switch (dir) { 50 case L: 51 x -= XSPEED; 52 break; 53 case R: 54 x += XSPEED; 55 break; 56 case U: 57 y -= YSPEED; 58 break; 59 case D: 60 y += YSPEED; 61 break; 62 case LU: 63 x -= XSPEED; 64 y -= YSPEED; 65 break; 66 case LD: 67 x -= XSPEED; 68 y += YSPEED; 69 break; 70 case RU: 71 x += XSPEED; 72 y -= YSPEED; 73 break; 74 case RD: 75 x += XSPEED; 76 y += YSPEED; 77 break; 78 79 case STOP: 80 break; 81 } 82 } 83 84 public void locateDirection() { 85 if (bL && !bU && !bR && !bD) 86 dir = Direction.L; 87 else if (bL && bU && !bR && !bD) 88 dir = Direction.LU; 89 else if (!bL && bU && !bR && !bD) 90 dir = Direction.U; 91 else if (!bL && bU && bR && !bD) 92 dir = Direction.RU; 93 else if (!bL && !bU && bR && !bD) 94 dir = Direction.R; 95 else if (!bL && !bU && bR && bD) 96 dir = Direction.RD; 97 else if (!bL && !bU && !bR && bD) 98 dir = Direction.D; 99 else if (bL && !bU && !bR && bD) 100 dir = Direction.LD; 101 else if (!bL && !bU && !bR && !bD) 102 dir = Direction.STOP; 103 104 } 105 106 // 坦克自己向哪个方向移动,它自己最清楚; 107 public void KeyPressed(KeyEvent e) { 108 // 获得所按下的键所对应的虚拟码: 109 // Returns the integer keyCode associated with the key in this event 110 int key = e.getKeyCode(); 111 // 判断不同的按键,指挥坦克的运动方向 112 switch (key) { 113 // Ctrl键控制打出炮弹 114 case KeyEvent.VK_CONTROL: 115 // fire函数返回的是一个Missile类型的对象 116 tc.m = fire(); 117 break; 118 case KeyEvent.VK_LEFT: 119 bL = true; 120 break; 121 case KeyEvent.VK_UP: 122 bU = true; 123 break; 124 case KeyEvent.VK_RIGHT: 125 bR = true; 126 break; 127 case KeyEvent.VK_DOWN: 128 bD = true; 129 break; 130 } 131 locateDirection(); 132 } 133 134 public void keyReleased(KeyEvent e) { 135 int key = e.getKeyCode(); 136 // 判断不同的按键,指挥坦克的运动方向 137 // 哪个键按下了,就把对应方向的布尔类型置为false 138 switch (key) { 139 case KeyEvent.VK_LEFT: 140 bL = false; 141 break; 142 case KeyEvent.VK_UP: 143 bU = false; 144 break; 145 case KeyEvent.VK_RIGHT: 146 bR = false; 147 break; 148 case KeyEvent.VK_DOWN: 149 bD = false; 150 break; 151 } 152 // 重新定位一下 153 locateDirection(); 154 } 155 156 public Missile fire() { 157 // 计算子弹的位置,使得子弹从坦克的中间发出来 158 int x = this.x + Tank.WIDTH / 2 - Missile.WIDTH / 2; 159 int y = this.y + Tank.HEIGHT / 2 - Missile.HEIGHT / 2; 160 // 将坦克的位置和方向传递给炮弹 161 Missile m = new Missile(x, y, dir); 162 return m; 163 } 164 }
Missile:
1 import java.awt.Color; 2 import java.awt.Graphics; 3 4 public class Missile { 5 //
以上是关于坦克大战(版本1.0-版本1.6)的主要内容,如果未能解决你的问题,请参考以下文章