坦克大战(版本2.5-版本2.9)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了坦克大战(版本2.5-版本2.9)相关的知识,希望对你有一定的参考价值。

版本2.5

功能:添加“血块”
步骤:
        1)添加blood类
        2)添加必要的方法:eat方法等
        3)让blood对象固定轨迹运动, 并在一定时间后消失

具体代码实现:

新增的blood类:

 1 import java.awt.Color;
 2 import java.awt.Graphics;
 3 import java.awt.Rectangle;
 4 
 5 //模拟血块,坦克吃了可以补血
 6 public class Blood {
 7     int x, y, w, h;
 8 
 9     TankClient tc;
10 
11     private boolean live = true;
12 
13     public void setLive(boolean live) {
14         this.live = live;
15     }
16 
17     public boolean isLive() {
18         return live;
19     }
20 
21     int step = 0;
22 
23     // 定义血块的位置,是不断变化的
24     private int position[][] = { { 350, 300 }, { 360, 300 }, { 375, 275 },
25             { 400, 200 }, { 360, 270 }, { 365, 290 }, { 340, 280 } };
26 
27     public Blood() {
28         x = position[0][0];
29         y = position[0][1];
30         w = h = 15;
31     }
32 
33     //血块的draw方法
34     public void draw(Graphics g) {
35         if (!live) {
36             return;
37         }
38         Color c = g.getColor();
39         g.setColor(Color.MAGENTA);
40         g.fillRect(x, y, w, h);
41         g.setColor(c);
42         move();
43     }
44 
45     private void move() {
46         step++;
47         if (step == position.length) {
48             step = 0;
49         }
50         x = position[step][0];
51         y = position[step][1];
52     }
53 
54     public Rectangle getRect() {
55         return new Rectangle(x, y, w, h);
56     }
57 }

Explode:

技术分享
 1 import java.awt.*;
 2 
 3 public class Explode {
 4     // 爆炸的位置
 5     int x, y;
 6     // 爆炸是否存在
 7     private boolean live = true;
 8 
 9     // 持有一个Tankclient的引用
10     private TankClient tc;
11 
12     // 定义不同直径大小的爆炸
13     int[] diameter = { 4, 7, 12, 18, 26, 32, 49, 30, 14, 6 };
14     // 爆炸发生到哪一个阶段了,对应相应大小的直径
15     int step = 0;
16 
17     public Explode(int x, int y, TankClient tc) {
18         this.x = x;
19         this.y = y;
20         this.tc = tc;
21     }
22 
23     public void draw(Graphics g) {
24         if (!live) {
25             // 爆炸发生,将相应直径的爆炸圆从集合explodes中去除
26             tc.explodes.remove(this);
27             return;
28         }
29 
30         if (step == diameter.length) {
31             live = false;
32             step = 0;
33             return;
34         }
35 
36         Color c = g.getColor();
37         g.setColor(Color.ORANGE);
38 
39         // 把不同的圆画出来
40         g.fillOval(x, y, diameter[step], diameter[step]);
41         g.setColor(c);
42 
43         step++;
44     }
45 }
View Code

Missile:

技术分享
  1 import java.awt.Color;
  2 import java.awt.Graphics;
  3 import java.awt.Rectangle;
  4 import java.util.List;
  5 
  6 public class Missile {
  7     // 炮弹的移动速度,不要比坦克的移动速度慢,不然你看到的是满屏的坦克追着炮弹跑
  8     public static final int XSPEED = 10;
  9     public static final int YSPEED = 10;
 10     // 将子弹的高度和宽度设置为常量
 11     public static final int WIDTH = 10;
 12     public static final int HEIGHT = 10;
 13     // 炮弹自己的三个属性
 14     int x;
 15     int y;
 16     Tank.Direction dir;
 17 
 18     // 同一阵营的的坦克发出的子弹不能伤害自己人
 19     private boolean good;
 20     // 定义一个布尔类型的变量来判断炮弹是否已经消亡
 21     private boolean live = true;
 22     // 我们在Missile类中也持有一个TankClient的引用
 23     // 在炮弹出界的时候就可以从装炮弹的missiles集合中去除该炮弹,不再对其重画
 24     private TankClient tc;
 25 
 26     public boolean isLive() {
 27         return live;
 28     }
 29 
 30     public Missile(int x, int y, Tank.Direction dir) {
 31         this.x = x;
 32         this.y = y;
 33         this.dir = dir;
 34     }
 35 
 36     public Missile(int x, int y, boolean good, Tank.Direction dir, TankClient tc) {
 37         this(x, y, dir);
 38         this.good = good;
 39         this.tc = tc;
 40     }
 41 
 42     // 炮弹自己的draw方法
 43     public void draw(Graphics g) {
 44         // 炮弹消亡就不需要再画出来了
 45         if (!live) {
 46             tc.missiles.remove(this);
 47             return;
 48         }
 49         Color c = g.getColor();
 50         g.setColor(Color.BLACK);
 51         // 炮弹形状不要比坦克大,这里设置成10,10;
 52         g.fillOval(x, y, WIDTH, HEIGHT);
 53         g.setColor(c);
 54         move();
 55     }
 56 
 57     public void move() {
 58         switch (dir) {
 59         case L:
 60             x -= XSPEED;
 61             break;
 62         case R:
 63             x += XSPEED;
 64             break;
 65         case U:
 66             y -= YSPEED;
 67             break;
 68         case D:
 69             y += YSPEED;
 70             break;
 71         case LU:
 72             x -= XSPEED;
 73             y -= YSPEED;
 74             break;
 75         case LD:
 76             x -= XSPEED;
 77             y += YSPEED;
 78             break;
 79         case RU:
 80             x += XSPEED;
 81             y -= YSPEED;
 82             break;
 83         case RD:
 84             x += XSPEED;
 85             y += YSPEED;
 86             break;
 87         // 炮弹就没有STOP这个枚举类型的值了
 88         /*
 89          * case STOP: break;
 90          */
 91         }
 92         // 判断炮弹出边界则消亡
 93         // 注意x,y只有正数值,x向右递增,y向下递增
 94         if (x < 0 || y < 0 || x > TankClient.GAME_WIDTH
 95                 || y > TankClient.GAME_HEIGHT) {
 96             live = false;
 97         }
 98     }
 99 
100     public boolean hitTank(Tank t) {
101         // 炮弹的方框和坦克的方框碰在一起了并且坦克是存活着的,后面的判断我们是一伙的我就不打你了
102         if (this.live && this.getRect().intersects(t.getRect()) && t.isLive()
103                 && this.good != t.isGood()) {
104             if (t.isGood()) {
105                 t.setLife(t.getLife() - 20);
106                 if (t.getLife() <= 0) {
107                     t.setLive(false);
108                 }
109             } else {
110                 t.setLive(false);
111             }
112             this.live = false;
113 
114             // 炮弹击中坦克,发生爆炸
115             Explode e = new Explode(x, y, tc);
116             tc.explodes.add(e);
117             return true;
118         }
119         return false;
120     }
121 
122     // 碰撞检测类Rectangle
123     // 拿到包围在炮弹周围的小方块
124     public Rectangle getRect() {
125         return new Rectangle(x, y, WIDTH, HEIGHT);
126     }
127 
128     // 添加hitTanks方法
129     public boolean hitTanks(List<Tank> tanks) {
130         for (int i = 0; i < tanks.size(); i++) {
131             if (hitTank(tanks.get(i))) {
132                 return true;
133             }
134         }
135         return false;
136 
137     }
138 
139     public boolean hitWall(Wall w) {
140         if (this.live && this.getRect().intersects(w.getRect())) {
141             this.live = false;
142             return true;
143         }
144         return false;
145     }
146 }
View Code

Wall:

技术分享
 1 import java.awt.Graphics;
 2 import java.awt.Rectangle;
 3 
 4 //
 5 public class Wall {
 6     int x, y, w, h;
 7     TankClient tc;
 8 
 9     public Wall(int x, int y, int w, int h, TankClient tc) {
10         super();
11         this.x = x;
12         this.y = y;
13         this.w = w;
14         this.h = h;
15         this.tc = tc;
16     }
17 
18     public void draw(Graphics g) {
19         g.fillRect(x, y, w, h);
20     }
21 
22     // 碰撞检测
23     public Rectangle getRect() {
24         return new Rectangle(x, y, w, h);
25     }
26 }
View Code

Tank:

技术分享
  1 import java.awt.*;
  2 import java.awt.event.*;
  3 import java.util.Random;
  4 
  5 public class Tank {
  6     // 方便后期更改
  7     public static final int XSPEED = 5;
  8     public static final int YSPEED = 5;
  9     // 将坦克的高度和宽度设置为常量
 10     public static final int WIDTH = 30;
 11     public static final int HEIGHT = 30;
 12     TankClient tc;
 13     // 区别是我方坦克还是地方坦克,方便据此进行不同的设置
 14     private boolean good;
 15 
 16     //定义血块
 17     private BloodBar bb = new BloodBar();
 18     // 坦克的生命值
 19     private int life = 100;
 20 
 21     public int getLife() {
 22         return life;
 23     }
 24 
 25     public void setLife(int life) {
 26         this.life = life;
 27     }
 28 
 29     public boolean isGood() {
 30         return good;
 31     }
 32 
 33     public void setGood(boolean good) {
 34         this.good = good;
 35     }
 36 
 37     // 判断坦克生死的变量
 38     private boolean live = true;
 39 
 40     public boolean isLive() {
 41         return live;
 42     }
 43 
 44     public void setLive(boolean live) {
 45         this.live = live;
 46     }
 47 
 48     private int x;
 49     private int y;
 50 
 51     // 记录坦克上一步的位置,防止坦克一碰到wall,就会依附在上面
 52     private int oldx;
 53     private int oldy;
 54 
 55     // 随机数产生器,方便敌方坦克可以任意移动
 56     private static Random r = new Random();
 57     // 添加记录按键状态的布尔量
 58     private boolean bL = false;
 59     private boolean bR = false;
 60     private boolean bU = false;
 61     private boolean bD = false;
 62 
 63     // 添加代表方向的量(使用枚举)
 64     enum Direction {
 65         L, R, U, D, LU, LD, RU, RD, STOP
 66     };
 67 
 68     private Direction dir = Direction.STOP;
 69 
 70     // 定义炮筒的方向,我们想办法将炮筒的方法调整成和坦克移动方向一致;
 71     // 我们这里会用一条直线来表示炮筒:模拟炮筒
 72     // 我们要根据炮筒的方向画直线表示炮筒
 73     Direction ptDir = Direction.D;
 74 
 75     // 为了让敌方坦克在一定方向运动移动时间再自动变换方向
 76     private int step = r.nextInt(12) + 3;
 77 
 78     // 更改构造函数
 79     public Tank(int x, int y, boolean good) {
 80         this.x = x;
 81         this.y = y;
 82         this.oldx = x;
 83         this.oldy = y;
 84         this.good = good;
 85     }
 86 
 87     // 这个位置的构造函数也相应进行了更改
 88     public Tank(int x, int y, boolean good, Direction dir, TankClient tc) {
 89         // 调用那个有两个参数的构造方法
 90         this(x, y, good);
 91         this.dir = dir;
 92         // 在这个位置初始化tc
 93         this.tc = tc;
 94     }
 95 
 96     // Tank对象的draw方法
 97     public void draw(Graphics g) {
 98         if (!live) {
 99             // 如果死亡的是敌方坦克,在tanks集合中去除该坦克
100             if (!good) {
101                 tc.tanks.remove(this);
102             }
103             // 如果是我方坦克,直接返回
104             return;
105         }
106         Color c = g.getColor();
107         if (good) {
108             g.setColor(Color.YELLOW);
109         } else {
110             g.setColor(Color.PINK);
111         }
112         g.fillOval(x, y, WIDTH, HEIGHT);
113         g.setColor(c);
114         // 判断一下,我方坦克才有血条显示
115         if (good) {
116 
117             bb.draw(g);
118         }
119         // 根据炮筒的方向画直线来表示我们坦克的炮筒
120         switch (ptDir) {
121         case L:
122             // 画直线:四个参数分别代表:坦克中心点的坐标 直线的另一头的的坐标
123             g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y
124                     + Tank.HEIGHT / 2);
125             break;
126         case R:
127             g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH,
128                     y + Tank.HEIGHT / 2);
129 
130             break;
131         case U:
132             g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH
133                     / 2, y);
134 
135             break;
136         case D:
137             g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH
138                     / 2, y + Tank.HEIGHT);
139 
140             break;
141         case LU:
142             g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y);
143             break;
144         case LD:
145             g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x, y
146                     + Tank.HEIGHT);
147 
148             break;
149         case RU:
150             g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH,
151                     y);
152 
153             break;
154         case RD:
155             g.drawLine(x + Tank.WIDTH / 2, y + Tank.HEIGHT / 2, x + Tank.WIDTH,
156                     y + Tank.HEIGHT);
157 
158             break;
159         /*
160          * case STOP: break;
161          */
162         }
163         move();
164     }
165 
166     public void move() {
167         // 记录坦克上一步的位置
168         this.oldx = x;
169         this.oldy = y;
170         switch (dir) {
171         case L:
172             x -= XSPEED;
173             break;
174         case R:
175             x += XSPEED;
176             break;
177         case U:
178             y -= YSPEED;
179             break;
180         case D:
181             y += YSPEED;
182             break;
183         case LU:
184             x -= XSPEED;
185             y -= YSPEED;
186             break;
187         case LD:
188             x -= XSPEED;
189             y += YSPEED;
190             break;
191         case RU:
192             x += XSPEED;
193             y -= YSPEED;
194             break;
195         case RD:
196             x += XSPEED;
197             y += YSPEED;
198             break;
199 
200         case STOP:
201             break;
202         }
203         // 如果坦克不是停着的,则将炮筒调整至和坦克移动的方向相同
204         if (this.dir != Direction.STOP) {
205             this.ptDir = this.dir;
206         }
207         if (x < 0) {
208             x = 0;
209         }
210         // 因为我们的游戏

以上是关于坦克大战(版本2.5-版本2.9)的主要内容,如果未能解决你的问题,请参考以下文章

坦克大战(版本1.0-版本1.6)

基于Netty的坦克大战网络版本

2019.04.19 坦克大战

Python游戏开发,pygame模块,Python实现升级版坦克大战小游戏

Tanks坦克大战

韩顺平--Java坦克大战