转载自:http://www.jb51.net/article/88317.htm

利用Java语言中的集合、Swing、线程等知识点编写一个坦克大战游戏。
(1) 画出敌我坦克的原理:
在坦克类里面有一个布尔类型变量good。用于判断坦克的阵营,在创建坦克对象时在Tank类的构造方法中传入good的值。在画坦克的时候判断good的值,区分敌我坦克的颜色;
(2) 坦克运动的原理:
在坦克类里写入了监听键盘摁键的响应事件,对监听到的上下左右键进行记录,并合成坦克移动的八个方向的变量。之后对应每个方向的不同对坦克坐标x,y的值做响应的更改实现我方坦克的移动。而敌方坦克则自动移动,通过随机数对敌方坦克移动方向的随机,并且随机出每次移动的次数。两个随机值相结合即实现了敌方坦克的移动。
(3) 坦克发射子弹的原理:
通过键盘监听,检测到发射子弹命令后将主类的子弹类集合中添加一个子弹类。将炮筒的方向以及坦克的位置以及坦克的阵营传入给子弹类,在主类paint画方法中一直循环子弹类集合,如果集合内有子弹,就画出来。这样就实现了发射子弹。
(4) 坦克、子弹、墙的碰撞原理:
在坦克类子弹类墙类中分别getRect方法获取自身的范围,然后在每次画坦克、子弹时都会进行相应的碰撞检测(在坦克类里有与墙和出自己外的坦克相撞的处理方法、在子弹类里有与墙和坦克相碰撞的处理方法。),如果自身与不该碰撞的物体的范围相重合,则代表两物体相撞。
(5)坦克加血的原理:
 在血块类中有血块与我方坦克相碰撞的处理方法,如果血块范围与坦克范围重合则血块类死亡,并且坦克类的血量回复置满。
(6)坦克复活的原理:
通过键盘监听,检测到我方坦克复活命令后,如果我方坦克处于死亡状态,则将我方坦克存货状态改为活着并且将我方坦克血量回置满血。 

编程思想:
坦克大战的编程思想在主类开启一个线程,没50毫秒循环一次画方法(绘制整个界面内的所有东西)。画的东西有敌我坦克(颜色区分)、子弹、墙、血块、爆炸。所以总共写出了几个类:Tank坦克类、Missile子弹类、Wall墙类、Blood血块类、TankClient主类。在每一个类中均写有画方法实现本类属性的绘制功能。在主类中有键盘监听事件调用这Tank类的键盘监听事件。通过键盘监听判断出对Tank做出相应的移动,而敌方Tank则是随机运动。并且每次刷新都有调用各类的碰撞方法,判断一些不该碰撞的对象的情况时做出处理。而每个对象的创建例如子弹这些是在触发产生之后将新建子弹类加入一个子弹类集合之中,在绘制的时候判断集合中的数量进行绘制,出界或者打死坦克则在集合中删除。其他类也均相似,不在细说。
 代码中每步都注释有相应的解释。

TankClient.java 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
public class TankClient extends JFrame{
   /**
    * @param args
    */
   Image OffScrennImage = null //双缓冲内存图片存储
   /*游戏大小*/
   public static final int GAME_WIDTH = 800;  //界面宽
   public static final int GAME_HEIGTH = 600;  //界面高
   
   Tank myTank = new Tank(500,400,true,Color.red,Tank.Direction.STOP, this);//我方坦克类
   List<Missile> missiles = new ArrayList<Missile>();//子弹的集合
   List<Explode> explode = new ArrayList<Explode>();//爆炸集合
   List<Tank> tanks = new ArrayList<Tank>();  //坦克集合
   Wall wall1 = new Wall(150,200,20,300,this);  //墙1
   Wall wall2 = new Wall(250,500,300,20,this);  //墙2
   Wall wall3 = new Wall(650,200,20,300,this);  //墙2
   Wall wall4 = new Wall(250,300,300,20,this);  //墙2
   Wall wb = new Wall(750,550,40,40,this);  //墙2
   Blood b = new Blood();  //血类
   
   
   public static void main(String[] args) {
     // TODO Auto-generated method stub
     TankClient tc=new TankClient();
     tc.lauchFrame();
   }
   private void lauchFrame() {
     // TODO Auto-generated method stub
     for (int i = 0; i < 10; i++){
       tanks.add(new Tank(50+40*(i+1), 50, false,Color.blue,Tank.Direction.D, this));
     }
     this.setLocation(100, 100);  //窗口初始坐标点
     this.setSize(GAME_WIDTH, GAME_HEIGTH);    //窗口初始大小
     this.setTitle("TankWar");  //窗口名称
     /*窗口监听*/
     this.addWindowListener(new WindowAdapter() {
       @Override
       /*点退出叉之后运行*/
       public void windowClosing(WindowEvent e) {
         // TODO Auto-generated method stub
         System.exit(0);  //退出
       }
     });
     this.addKeyListener(new KeyMoniton());  //设置键盘监听
     this.setVisible(true);  //设置窗口显现
     this.setResizable(false);  //设置窗口不可改变大小
     this.getContentPane().setBackground(Color.green);  //设置窗口前景色为绿色
     new Thread(new PaintThread()).start();  //开始运行PaintThread类run
   }
   @Override
   public void paint(Graphics g) {
     // TODO Auto-generated method stub
     //Graphics为画笔类
     super.paint(g);
     myTank.draw(g);
     wall1.draw(g);
     wall2.draw(g);
     wall3.draw(g);
     wall4.draw(g);
     wb.draw(g);
     b.draw(g);
     myTank.eatBlood(b);
     myTank.hitWall(wall1);
     myTank.hitWall(wall2);
     myTank.hitWall(wall3);
     myTank.hitWall(wall4);
     /*循环子弹集合*/
     for (int i = 0; i < missiles.size(); i++){
       Missile m = missiles.get(i);  //获取当前子弹
       m.hitTanks(tanks);  //自己子弹打死敌方坦克
       m.hitWall(wall1);  //子弹与墙
       m.hitWall(wall2);
       m.hitWall(wall3);
       m.hitWall(wall4);
       m.hitTank(myTank);//敌人子弹打击自己的坦克
       m.draw(g);  //画子弹
     }
     for  (int i = 0; i < explode.size(); i++){
       explode.get(i).draw(g);  //画爆炸
     }
     for (int i = 0; i < tanks.size(); i++){
       Tank t = tanks.get(i);
       t.draw(g);  //画敌方坦克
       t.hitTanks(tanks);
       t.hitWall(wall1);  //坦克与墙
       t.hitWall(wall2);
       t.hitWall(wall3);
       t.hitWall(wall4);
     }
     //g.setFont(new Font("宋体",Font.BOLD,20));
     g.drawString("missiles count:"+missiles.size(), 10, 50);//显示
     g.drawString("explode count:"+explode.size(), 10, 80);//显示
     g.drawString("tanks count:"+tanks.size(),10, 110);
     g.drawString("myTank Life:"+myTank.getLife(), 10, 130);
     g.drawString("回血:", 750, 540);
     g.drawString("方向键移动方向;E:释放移动血快", 10, 590);
     g.drawString("z:发射东风-31;a:发射东风-41;", 10, 570);
     g.drawString("F2:复活;F3:敌方复活(对多20)", 10, 550);
     g.drawString("R:位置还原;Q:血量加满", 10, 530);
   }
   
   @Override
   /*repaint-〉update->paint*/
   public void update(Graphics g) {
     // TODO Auto-generated method stub
     super.update(g);
     if(OffScrennImage == null)
       OffScrennImage = this.createImage(GAME_WIDTH, GAME_HEIGTH);
     Graphics goffscrenn = OffScrennImage.getGraphics();  //设置一个内存画笔颜色为前景图片颜色
     Color c = goffscrenn.getColor();  //还是先保存前景颜色
     goffscrenn.setColor(Color.green);  //设置内存画笔颜色为绿色
     goffscrenn.fillRect(0, 0, GAME_WIDTH, GAME_HEIGTH);  //画成图片,大小为游戏大小
     goffscrenn.setColor(c);  //还原颜色
     g.drawImage(OffScrennImage, 0, 0, null);  //在界面画出保存的图片
     paint(goffscrenn);  //把内存画笔调用给paint
   }
   private class PaintThread implements Runnable{
     @Override
     public void run() {
       // TODO Auto-generated method stub
       while(true){
         repaint();  //运行顺序repaint->update->paint
         try{
           Thread.sleep(50);  //每隔50毫秒刷新画面一次
         }catch(Exception e){
           e.printStackTrace();
         }
       }
     }
     
   }
   /*键盘响应*/
   private class KeyMoniton extends KeyAdapter{
     /*摁下键盘响应*/
     @Override
     public void keyPressed(KeyEvent e) {
       // TODO Auto-generated method stub
       super.keyPressed(e);
       myTank.KeyPressed(e);
     }
     /*抬起键盘响应*/
     @Override
     public void keyReleased(KeyEvent e) {
       // TODO Auto-generated method stub
       super .keyReleased(e);
       myTank.keyReleased(e);
     }
     
   }
}

Tank.java

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

Missile.java 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.List;
public class Missile {
   /*子弹本身数据*/
   Tank.Direction dir;  //子弹方向
   Color c;  //子弹颜色
   int x,y;  //子弹位置
   public static final int XSPEED = 15;  //横向移动速度
   public static final int YSPEED = 15;  //纵向移动速度
   public static final int Whith = 10;    //子弹宽
   public static final int Higth = 10;    //子弹高
   private boolean live = true;  //判断子弹的存活
   private boolean good;  //判断子弹和阵营
   
   private TankClient tc;//主类权限
   
   public Missile(Tank.Direction dir,Color c, int x, int y) {
     super();
       this.dir = dir;
       this.x = x;
       this.y = y;
       this.c = c;
   }
   public Missile(Tank.Direction dir,Color c, int x, int y,boolean good,TankClient tc){
     this(dir,c,x,y);
     this.good = good;
     this.tc = tc;
   }
   
   /*获取子弹的存活*/
   public boolean isLive() {
     return live;
   }
   /*设置子弹的存活*/
   public void setLive(boolean live) {
     this.live = live;
   }
   public void draw(Graphics g){
     /*如果子弹死亡状态将这个子弹在子弹集合中删除*/
     if(!live){
       tc.missiles.remove(this);  //集合中删除
       return;
     }
     /*先保存之前的画笔颜色,画完之后再还原画笔颜色*/
     Color d = g.getColor();  //获取当前画笔颜色
     g.setColor(c);  //设置画笔颜色为红色
     /*画子弹*/
     g.fillOval(x, y, Whith, Higth); 
     
     g.setColor(d);  //还原画笔颜色
     move();  //移动
   }
   
   public void move(){
     /*判断移动方向移动坦克位置*/
     switch(dir){
     case L:
       x-=XSPEED;
       break;
     case LU:
       x-=XSPEED;
       y-=YSPEED;
       break;
     case U:
       y-=YSPEED;
       break;
     case RU:
       x+=XSPEED;
       y-=YSPEED;
       break;
     case R:
       x+=XSPEED;
       break;
     case RD:
       x+=XSPEED;
       y+=YSPEED;
       break;
     case D:
       y+=YSPEED;
       break;
     case LD:
       x-=XSPEED;
       y+=YSPEED;
       break;
     case STOP:
       break;
     }
     /*判断子弹的越界情况;出界则子弹死亡,在子弹集合中删去*/
     if(x<0||y<0||x>TankClient.GAME_WIDTH||y>TankClient.GAME_HEIGTH)
       live = false;
   }
   /*碰撞;获取子弹的范围*/
   public Rectangle getRect(){
     return new Rectangle(x,y,Whith,Higth);
   }
   /*子弹与坦克碰撞过程*/
   public boolean hitTank(Tank t){
     /*如果子弹与坦克在同一范围则子弹和坦克同时死亡;且子弹只能杀死对方坦克*/
     if(this.live&&this.getRect().intersects(t.getRect())&&t.isLive()&&this.good!=t.isGood()){
       if(t.isGood()){ //好坦克
         /*我方坦克子弹射中会减少生命值,生命值0的时候会死亡*/
         t.setLife(t.getLife()-20);
         if(t.getLife()<=0)
           t.setLive(false);
       }else{ //坏坦克
         t.setLive(false);//死亡
       }
       this.live=false;//子弹死亡
       tc.explode.add(new Explode(x, y, tc));//新建爆炸加入集合
       return true;
     }
     return false;
   }
   /*循环坦克集合分别进行判断子弹碰撞*/
   public boolean hitTanks(List<Tank> tanks){
     for  (int i = 0; i < tanks.size(); i++){
       if(hitTank(tanks.get(i)))
         return true;
     }
     return false;
   }
   /*子弹与墙的碰撞过程*/
   public boolean hitWall(Wall w){
     /*如果子弹与墙的范围重合子弹死亡*/
     if ( this .live&& this .getRect().intersects(w.getRect())){
       this .live= false //子弹死亡
       return true ;
     }
     return false ;
   }
}

Wall.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.awt.Graphics;
import java.awt.Rectangle;
public class Wall {
   /*墙数据*/
   int x,y,w,h;  //位置和宽高
   private TankClient tc;  //主类权限
   
   public Wall(int x, int y, int w, int h, TankClient tc) {
     super();
     this.x = x;
     this.y = y;
     this.w = w;
     this.h = h;
     this.tc = tc;
   }
   /*获取墙的范围*/
   public Rectangle getRect(){
     return new Rectangle(x,y,w,h);
   }
   /*画墙*/
   public void draw(Graphics g){
     g.fillRect(x, y, w, h);
   }
}

Explode.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.awt.Color;
import java.awt.Graphics;
public class Explode {
   /*坦克爆炸属性*/
   int x,y;  //爆炸位置
   private boolean live = true;  //爆炸是否存在
   int step = 0;  //爆炸时间控制
   int [] diameter = new int[] {4, 7, 12, 18, 26, 32, 49, 56, 65, 77, 80, 50, 40, 30, 14, 6};//爆炸范围
   
   private TankClient tc;  //主类权限
   public Explode(int x, int y, TankClient tc) { 
     super();
     this.x = x;
     this.y = y;
     this.tc = tc;
   }
   
   /*画爆炸*/
   public void draw(Graphics g){
     if(!live) return;  //如果爆炸死亡状态不画结束
     /*如果爆炸时间结束爆炸不存在并在集合中删除*/
     if(step == diameter.length){
       live = false;  //爆炸死亡
       step = 0;  //步骤时间归0
       tc.explode.remove(this);  //集合中删除
       return;
     }
     /*画爆炸*/
     Color c = g.getColor();
     g.setColor(Color.orange);
     g.fillOval(x, y, diameter[step], diameter[step]);
     g.setColor(c);
     
     step++;
   }
   
}

Blood.java 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
public class Blood {
   /*血块数据*/
   int x, y, w, h;//血块位置和大小
   private TankClient tc;  //主类权限
   private boolean live=true;//血块的存活
   private static Random r = new Random();//设置一个随机值变量
   /*获取血块的存活状态*/
   public boolean isLive() {
     return live;
   }
   /*设置血块的存活状态*/
   public void setLive(boolean live) {
     this.live = live;
   }
   /*血块位置初值随机一个数值*/
   public Blood(){
     x=r.nextInt(600)+100;
     y=r.nextInt(400)+100;
     w=h=15;
   }
   /*画血块*/
   public void draw(Graphics g){
     if(!live) return;
     Color c=g.getColor();
     g.setColor(Color.magenta);
     g.fillRect(x, y, w, h);
     g.setColor(c);
   }
   /*释放血块*/
   public void fh(){
     if(!live){
       x = r.nextInt(600)+100;
       y = r.nextInt(400)+100;
       live = true;
     }
   }
   /*获取血块范围*/
   public Rectangle getRect(){
     return new Rectangle(x, y, w, h);
   }
}

java简单坦克大战制作代码相关推荐

  1. java视频 坦克大战制作

    学习一门编程语言入门,什么方法比较快,那肯定是跟着老师一起来找一个项目入手了,下面是java  坦克大战制作视频链接地址,该视频报包裹了本地版坦克大战,局域网版坦克大战,网络版坦克大战,有需求的同学可 ...

  2. java坦克大战登录界面设计_基于JAVA的坦克大战设计和实现-代码.doc

    JISHOU UNIVERSITY 本科生毕业设计 题 目:基于JAVA的坦克大战设计与实现作 者:学 号:所属学院:专业年级:指导教师:职 称:完成时间:2012年5月7日 吉首大学 基于JAVA的 ...

  3. java小组坦克大战游戏开发文档开发日志_java实现坦克大战游戏

    本文实例为大家分享了java实现坦克大战游戏的具体代码,供大家参考,具体内容如下 一.实现的功能 1.游戏玩法介绍 2.自定义游戏(选择游戏难度.关卡等) 3.自定义玩家姓名 4.数据的动态显示 二. ...

  4. Unity3D项目十:简单坦克大战

    简单坦克大战 作业要求 坦克对战游戏 AI 设计 从商店下载游戏:"Kawaii" Tank 或 其他坦克模型,构建 AI 对战坦克.具体要求 使用"感知-思考-行为&q ...

  5. C#坦克大战网络版代码

    简单C#坦克大战网络版代码 写完单机版 [url=http://blog.csdn.net/xiaoxiao108/archive/2010/12/18/6084473.aspx]http://blo ...

  6. 100行JS代码实现❤坦克大战js小游戏源码 HTML5坦克大战游戏代码(HTML+CSS+JavaScript )

    坦克大战js小游戏源码 HTML5坦克大战游戏代码(HTML+CSS+JavaScript ) HTML5坦克大战网页小游戏,完美还原小霸王学习机效果,以坦克战斗及保卫基地为主题,属于策略型类游戏. ...

  7. java 坦克大战 教程_[Java教程]坦克大战(一)

    [Java教程]坦克大战(一) 0 2016-09-16 08:00:05 坦克大战(一) 相信大家对坦克大战都不陌生,并且网上也有很多用java实现的小程序,最近用了几天时间将其使用javaScri ...

  8. java怎么连发子弹_【Java_项目篇1】--JAVA实现坦克大战游戏--子弹连发+爆炸效果(四)...

    前期相关文章 [Java_项目篇<1>]–JAVA实现坦克大战游戏–画出坦克(一) [Java_项目篇<1>]–JAVA实现坦克大战游戏–坦克移动+添加敌方坦克(二) [Jav ...

  9. 【Java_项目篇1】--JAVA实现坦克大战游戏--坦克移动+添加敌方坦克(二)

    前期文章: [Java_项目篇<1>]--JAVA实现坦克大战游戏--画出坦克(一) 控制小球移动 1.外部类 实现KeyListener监听接口写法 package com.test3; ...

最新文章

  1. java double转换符_java中字符串怎么转换成double类型
  2. 水稻微生物组时间序列分析2a-相关分析
  3. Gradle的安装和在idea的配置
  4. 谷歌又孵化出黑科技项目!押注工业机器人方向,上海交大校友参与
  5. python3 dict 字典 合并
  6. sort,uniq,wc,history命令简介
  7. 【Python】选取二维列表的第一列
  8. 神州英才战略盈利竞争力总结
  9. java log4j 多个文件_java – Log4j:每个请求一个日志文件
  10. 区块链在供应链领域的应用
  11. mysql自带订阅功能_为博客提供订阅功能
  12. 浅谈Java的Nio以及报Connection refused: no further information异常原因?
  13. python拦截数据包_使用Python进行TCP数据包注入(伪造)
  14. 第一章 项目管理引论
  15. VTD软件说明书阅读之OpenDRIVE Scenario Editor
  16. 科学计算机sd mode使用方法,科学计算器使用方法
  17. 计算机网络波动大,电脑网络总是不稳定的解决方法
  18. stm32实现心电监测-原理图单片机程序C#上位机程序
  19. iOS - 监控键盘高度、屏蔽字符、限制字符个数
  20. 本地调试微信授权跳转

热门文章

  1. 曝RTX4090电源接口过热烧毁,用户称烧到冒烟有焦味,网友:战术核显卡回来了...
  2. 商业解决方案策划专家(区块链)
  3. Z-stack3.0 Power Green的使用
  4. 【附源码】计算机毕业设计java音蕾心动设计与实现
  5. 【总结】CSP2022总结
  6. 了解苹果自动驾驶“窃密”事件始末,嫌疑人或将面临10年监禁、 25 万美元罚款...
  7. 如何在前端调试模式下禁用JavaScript
  8. Android 深入实现基于socket套接字的即时聊天
  9. 解决win7安装VMTools失败
  10. react-native打包发布发行(Realease)版apk,出现unable to process incoming event 'ProcessComplete'