JAVA练手小游戏——坦克大战(:唐克大战

简介: JAVA练手小游戏——坦克大战(:唐克大战

1.代码实现

Blood类

1. package com.tank;
2. import java.awt.*;
3. public class Blood {
4.  int x, y, w, h;
5.  TankClient tc;
6. 
7.  int step = 0;
8.  private boolean life = true;
9. 
10.   //指明血块运动的轨迹,由pos中各个点构成
11.   private int[][] pos = {
12.                   {350, 300}, {360, 300}, {375, 275}, {400, 200}, {360, 270}, {365, 290}, {340, 280}  
13.             };
14. 
15.   public Blood() {
16.     x = pos[0][0];
17.     y = pos[0][1];
18.     w = h = 15;
19.   }
20. 
21.   public boolean isLife() {
22.     return life;
23.   }
24. 
25. 
26.   public void setLife(boolean life) {
27.     this.life = life;
28.   }
29. 
30.   public void draw(Graphics g) {
31.     if(!life) return;
32. 
33.     Color c = g.getColor();
34.     g.setColor(Color.MAGENTA);
35.     g.fillRect(x, y, w, h);
36.     g.setColor(c);
37.     move();
38.   }
39. 
40.   private void move() {
41.     step ++;
42.     if(step == pos.length) {
43.       step = 0;
44.     }
45.     x = pos[step][0];
46.     y = pos[step][1];
47.   }
48. 
49.   public Rectangle getRect() {
50.     return new Rectangle(x, y ,w ,h);
51.   }
52. }

Direction类

1. package com.tank;
2. 
3. public enum Direction {
4.  L, LU, U, RU, R, RD, D, LD, STOP
5. }

Explore类

1. package com.tank;
2. import java.awt.Image;
3. import java.awt.Graphics;
4. import java.awt.Toolkit;
5. public class Explode {
6.  int x,y;
7.  private boolean live = true;
8. 
9.  private TankClient tc;
10. 
11.   private static Toolkit tk = Toolkit.getDefaultToolkit();
12. 
13.   private static Image[] imgs = {
14.     //反射    .class实际就是一个Class对象   把资源文件放到classpath的常用方法
15.     tk.getImage(Explode.class.getClassLoader().getResource("images/0.gif")),
16.     tk.getImage(Explode.class.getClassLoader().getResource("images/1.gif")),
17.     tk.getImage(Explode.class.getClassLoader().getResource("images/2.gif")),
18.     tk.getImage(Explode.class.getClassLoader().getResource("images/3.gif")),
19.     tk.getImage(Explode.class.getClassLoader().getResource("images/4.gif")),
20.     tk.getImage(Explode.class.getClassLoader().getResource("images/5.gif")),
21.     tk.getImage(Explode.class.getClassLoader().getResource("images/6.gif")),
22.     tk.getImage(Explode.class.getClassLoader().getResource("images/7.gif")),
23.     tk.getImage(Explode.class.getClassLoader().getResource("images/8.gif")),
24.     tk.getImage(Explode.class.getClassLoader().getResource("images/9.gif")),
25.     tk.getImage(Explode.class.getClassLoader().getResource("images/10.gif"))
26.   };
27.   int step = 0;
28. 
29.   private static boolean init = false;
30. 
31.   public Explode(int x, int y, TankClient tc) {
32.     this.x = x;
33.     this.y = y;
34.     this.tc = tc;
35.   }
36. 
37.   public void draw(Graphics g) {
38.     if(!init) {
39.       for(int i = 0; i < imgs.length; i++) {
40.       g.drawImage(imgs[i], -100, -100, null);
41.       }
42.       init = true;
43.     }
44. 
45.     if(!live) {
46.       tc.explodes.remove(this);
47.       return;
48.     }
49. 
50.     if(step == imgs.length) {
51.       live = false;
52.       step = 0;
53.       return;
54.     }
55. 
56.     g.drawImage(imgs[step], x, y, null);
57. 
58.     step ++;
59.   }
60. 
61. }

Missile类

1. package com.tank;
2. import java.awt.*;
3. import java.util.HashMap;
4. import java.util.List;
5. import java.util.Map;
6. 
7. public class Missile {
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,y;
15.   Direction dir;
16. private boolean good;
17. 
18.   private boolean live = true;
19. 
20.   private TankClient tc;
21. 
22.   private static Toolkit tk = Toolkit.getDefaultToolkit();
23.   private static Image[] missileImgs = null;
24.   private static Map<String, Image> imgs = new HashMap<String, Image>();
25.   //静态代码区              作用是保证class在第一次被load到内存时执行
26.   static {
27.     missileImgs = new Image[] {
28.     //反射    .class实际就是一个Class对象   把资源文件放到classpath的常用方法
29.     tk.getImage(Missile.class.getClassLoader().getResource("images/missileL.gif")),
30.     tk.getImage(Missile.class.getClassLoader().getResource("images/missileLU.gif")),
31.     tk.getImage(Missile.class.getClassLoader().getResource("images/missileU.gif")),
32.     tk.getImage(Missile.class.getClassLoader().getResource("images/missileRU.gif")),
33.     tk.getImage(Missile.class.getClassLoader().getResource("images/missileR.gif")),
34.     tk.getImage(Missile.class.getClassLoader().getResource("images/missileRD.gif")),
35.     tk.getImage(Missile.class.getClassLoader().getResource("images/missileD.gif")),
36.     tk.getImage(Missile.class.getClassLoader().getResource("images/missileLD.gif")),
37.     };
38. 
39.     imgs.put("L", missileImgs[0]);
40.     imgs.put("LU", missileImgs[1]);
41.     imgs.put("U", missileImgs[2]);
42.     imgs.put("RU", missileImgs[3]);
43.     imgs.put("R", missileImgs[4]);
44.     imgs.put("RD", missileImgs[5]);
45.     imgs.put("D", missileImgs[6]);
46.     imgs.put("LD", missileImgs[7]);
47.   }
48. 
49.   public boolean isLive() {
50.     return live;
51.   }
52. 
53.   public Missile(int x, int y, Direction dir) {
54.     this.x = x;
55.     this.y = y;
56.     this.dir = dir;
57.   }
58. 
59.   public Missile(int x, int y, Direction dir, boolean good, TankClient tc) {
60.     this(x, y, dir);
61.     this.good = good;
62.     this.tc = tc;
63.   }
64. 
65.   public void draw(Graphics g) {
66.     if(!live) {
67.       tc.missiles.remove(this);
68.       return;
69.     }
70. 
71.     switch(dir) {
72.     case L:
73.       g.drawImage(imgs.get("L"), x, y, null);
74.       break;
75.     case LU:
76.       g.drawImage(imgs.get("LU"), x, y, null);
77.       break;
78.     case U:
79.       g.drawImage(imgs.get("U"), x, y, null);
80.       break;
81.     case RU:
82.       g.drawImage(imgs.get("RU"), x, y, null);
83.       break;
84.     case R:
85.       g.drawImage(imgs.get("R"), x, y, null);
86.       break;
87.     case RD:
88.       g.drawImage(imgs.get("RD"), x, y, null);
89.       break;
90.     case D:
91.       g.drawImage(imgs.get("D"), x, y, null);
92.       break;
93.     case LD:
94.       g.drawImage(imgs.get("LD"), x, y, null);
95.       break;
96. 
97.     }
98. 
99.     move();
100.  }
101. 
102.  private void move() {
103.    switch(dir) {
104.    case L:
105.      x -= XSPEED;
106.      break;
107.    case LU:
108.      x -= XSPEED;
109.      y -= YSPEED;
110.      break;
111.    case U:
112.      y -= YSPEED;
113.      break;
114.    case RU:
115.      x += XSPEED;
116.      y -= YSPEED;
117.      break;
118.    case R:
119.      x += XSPEED;
120.      break;
121.    case RD:
122.      x += XSPEED;
123.      y += YSPEED;
124.      break;
125.    case D:
126.      y += YSPEED;
127.      break;
128.    case LD:
129.      x -= XSPEED;
130.      y += YSPEED;
131.      break;
132.    }
133.    if(x < 0 || y < 0 || x > TankClient.GAME_WIDTH || y > TankClient.GAME_HEIGHT) {
134.      live = false;
135.      tc.missiles.remove(this);
136.    }
137.  }
138. 
139.  public Rectangle getRect() {
140.    return new Rectangle(x, y, WIDTH, HEIGHT);
141.  }
142. 
143.  //碰撞检测辅助类Rectangle
144.  public boolean hitTank(Tank t) {
145.    if(this.live && this.getRect().intersects(t.getRect()) && t.isLive() && this.good != t.isGood()) {
146.      if(t.isGood()) {
147.        t.setLife(t.getLife()-20);
148.        if(t.getLife() <= 0) t.setLive(false);
149.      } else {
150.        t.setLive(false);
151.      }
152.      this.live = false;
153.      Explode e = new Explode(x, y, tc);
154.      tc.explodes.add(e);
155.      return true;
156.    }
157.    return false;
158.  }
159. 
160.  public boolean hitTanks(List<Tank> tanks) {
161.    for(int i=0; i<tanks.size(); i++) {
162.      if(hitTank(tanks.get(i))) {
163.        return true;
164.      }
165.    }
166.    return false;
167.  }
168. 
169.  public boolean hitWall(Wall w) {
170.    if(this.live && this.getRect().intersects(w.getRect())) {
171.      this.live = false;
172.      return true;
173.    }
174.    return false;
175.  }
176. }

PropertyMgr类

1. package com.tank;
2. import java.io.FileReader;
3. import java.io.IOException;
4. import java.net.URLDecoder;
5. import java.util.Properties;
6. 
7. 
8. public class PropertyMgr {
9.  static Properties props = new Properties();
10.   //单例设计模式
11.   static {
12.     try {
13.       //props.load(PropertyMgr.class.getClass().getClassLoader().getResourceAsStream("config/tank.properties"));
14.       String tankPath = PropertyMgr.class.getClassLoader().getResource("config/tank.properties").getPath();
15.       tankPath = URLDecoder.decode(tankPath, "utf-8");
16.       props.load(new FileReader(tankPath));
17.     } catch (IOException e1) {
18.       e1.printStackTrace();
19.     }
20.   }
21. 
22.   private PropertyMgr() {};
23. 
24.   public static String getProperty(String key) {
25.     return props.getProperty(key);
26.   }
27. }

Tank类

1. package com.tank;
2. import java.awt.Color;
3. import java.awt.Graphics;
4. import java.awt.Image;
5. import java.awt.Rectangle;
6. import java.awt.Toolkit;
7. import java.awt.event.*;
8. import java.util.*;
9. 
10. 
11. public class Tank {
12.   public static final int XSPEED = 5;
13.   public static final int YSPEED = 5;
14. 
15.   private boolean live = true;
16.   private BloodBar bb = new BloodBar();
17.   private int life = 100;
18. 
19.   public int getLife() {
20.     return life;
21.   }
22. 
23.   public void setLife(int life) {
24.     this.life = life;
25.   }
26. 
27.   public boolean isLive() {
28.     return live;
29.   }
30. 
31.   public void setLive(boolean live) {
32.     this.live = live;
33.   }
34. 
35.   TankClient tc;
36. 
37.   private boolean good;
38. 
39.   public boolean isGood() {
40.     return good;
41.   }
42. 
43.   private int x,y;
44.   private int oldX, oldY;
45. 
46.   private static Random r = new Random();
47. 
48.   private boolean bL=false, bU=false, bR=false, bD=false;
49. 
50. 
51.   private Direction dir = Direction.STOP;
52.   private Direction ptDir = Direction.D;     //炮筒方向
53.   private int step = r.nextInt(12) + 3;
54. 
55.   private static Toolkit tk = Toolkit.getDefaultToolkit();
56.   private static Image[] tankImgs = null;
57.   private static Map<String, Image> imgs = new HashMap<String, Image>();
58.   //静态代码区              作用是保证class在第一次被load到内存时执行
59.   static {
60.     tankImgs = new Image[] {
61.     //反射    .class实际就是一个Class对象   把资源文件放到classpath的常用方法
62.     tk.getImage(Tank.class.getClassLoader().getResource("images/tankL.gif")),
63.     tk.getImage(Tank.class.getClassLoader().getResource("images/tankLU.gif")),
64.     tk.getImage(Tank.class.getClassLoader().getResource("images/tankU.gif")),
65.     tk.getImage(Tank.class.getClassLoader().getResource("images/tankRU.gif")),
66.     tk.getImage(Tank.class.getClassLoader().getResource("images/tankR.gif")),
67.     tk.getImage(Tank.class.getClassLoader().getResource("images/tankRD.gif")),
68.     tk.getImage(Tank.class.getClassLoader().getResource("images/tankD.gif")),
69.     tk.getImage(Tank.class.getClassLoader().getResource("images/tankLD.gif")),
70.     };
71. 
72.     imgs.put("L", tankImgs[0]);
73.     imgs.put("LU", tankImgs[1]);
74.     imgs.put("U", tankImgs[2]);
75.     imgs.put("RU", tankImgs[3]);
76.     imgs.put("R", tankImgs[4]);
77.     imgs.put("RD", tankImgs[5]);
78.     imgs.put("D", tankImgs[6]);
79.     imgs.put("LD", tankImgs[7]);
80.   }
81. 
82. 
83.   public static final int WIDTH = 30;
84.   public static final int HEIGHT = 30;
85. 
86. 
87.   public Tank(int x, int y, boolean good) {
88.     this.x = x;
89.     this.y = y;
90.     this.oldX = x;
91.     this.oldY = y;
92.     this.good = good;
93.   }
94. 
95.   public Tank(int x, int y, boolean good, Direction dir, TankClient tc) {
96.     this(x,y,good);
97.     this.dir = dir;
98.     this.tc = tc;
99.   }
100. 
101.  public void draw(Graphics g) {
102.    if(!live) {
103.      if(!good) {
104.        tc.tanks.remove(this);
105.      }
106.      return;
107.    }
108. 
109. 
110.    if(good) bb.draw(g);
111. 
112.    switch(ptDir) {
113.    case L:
114.      g.drawImage(imgs.get("L"), x, y, null);
115.      break;
116.    case LU:
117.      g.drawImage(imgs.get("LU"), x, y, null);
118.      break;
119.    case U:
120.      g.drawImage(imgs.get("U"), x, y, null);
121.      break;
122.    case RU:
123.      g.drawImage(imgs.get("RU"), x, y, null);
124.      break;
125.    case R:
126.      g.drawImage(imgs.get("R"), x, y, null);
127.      break;
128.    case RD:
129.      g.drawImage(imgs.get("RD"), x, y, null);
130.      break;
131.    case D:
132.      g.drawImage(imgs.get("D"), x, y, null);
133.      break;
134.    case LD:
135.      g.drawImage(imgs.get("LD"), x, y, null);
136.      break;
137. 
138.    }
139. 
140.    move();
141. 
142.  }
143. 
144.  void move() {
145.    this.oldX = x;
146.    this.oldY = y;
147.    switch(dir) {
148.    case L:
149.      x -= XSPEED;
150.      break;
151.    case LU:
152.      x -= XSPEED;
153.      y -= YSPEED;
154.      break;
155.    case U:
156.      y -= YSPEED;
157.      break;
158.    case RU:
159.      x += XSPEED;
160.      y -= YSPEED;
161.      break;
162.    case R:
163.      x += XSPEED;
164.      break;
165.    case RD:
166.      x += XSPEED;
167.      y += YSPEED;
168.      break;
169.    case D:
170.      y += YSPEED;
171.      break;
172.    case LD:
173.      x -= XSPEED;
174.      y += YSPEED;
175.      break;
176.    case STOP:
177.      break;
178.    }
179. 
180.    if(this.dir != Direction.STOP) {
181.      this.ptDir = this.dir;
182.    }
183. 
184.    if(x < 0) x = 0;
185.    if(y < 25) y = 25;
186.    if(x + Tank.WIDTH > TankClient.GAME_WIDTH) x = TankClient.GAME_WIDTH - Tank.WIDTH;
187.    if(y + Tank.HEIGHT > TankClient.GAME_HEIGHT) y = TankClient.GAME_HEIGHT - Tank.HEIGHT;
188. 
189.    if(!good) {
190.      Direction[] dirs = Direction.values();
191.      if(step == 0) {
192.        step = r.nextInt(12) + 3;
193.        int rn = r.nextInt(dirs.length);    //产生从0到length的随机数
194.        dir = dirs[rn];
195.      }
196.      step --;
197. 
198.      if(r.nextInt(40) > 35) this.fire();
199.    }
200. 
201.  }
202. 
203.  private void stay() {
204.    x = oldX;
205.    y = oldY;
206.  }
207. 
208.  public void KeyPressed(KeyEvent e) {
209.    int key = e.getKeyCode();
210.    switch(key) {
211.    case KeyEvent.VK_F2:
212.      if(!this.live) {                              //死去的敌方坦克在上面draw方法中已被删除
213.        this.live = true;
214.        this.life = 100;
215.      }
216.      break;
217.    case KeyEvent.VK_LEFT:
218.      bL = true;
219.      break;
220.    case KeyEvent.VK_UP:
221.      bU = true;
222.      break;
223.    case KeyEvent.VK_RIGHT:
224.      bR = true;
225.      break;
226.    case KeyEvent.VK_DOWN:
227.      bD = true;
228.      break;
229.    }
230.    locateDirection();
231.  }
232. 
233.  void locateDirection() {
234.    if(bL && !bU && !bR && !bD) dir = Direction.L;
235.    else if(bL && bU && !bR && !bD) dir = Direction.LU;
236.    else if(!bL && bU && !bR && !bD) dir = Direction.U;
237.    else if(!bL && bU && bR && !bD) dir = Direction.RU;
238.    else if(!bL && !bU && bR && !bD) dir = Direction.R;
239.    else if(!bL && !bU && bR && bD) dir = Direction.RD;
240.    else if(!bL && !bU && !bR && bD) dir = Direction.D;
241.    else if(bL && !bU && !bR && bD) dir = Direction.LD;
242.    else if(!bL && !bU && !bR && !bD) dir = Direction.STOP;
243.  }
244. 
245.  public void keyReleased(KeyEvent e) {
246.    int key = e.getKeyCode();
247.    switch(key) {
248.    case KeyEvent.VK_CONTROL:
249.      fire();
250.      break;
251.    case KeyEvent.VK_LEFT:
252.      bL = false;
253.      break;
254.    case KeyEvent.VK_UP:
255.      bU = false;
256.      break;
257.    case KeyEvent.VK_RIGHT:
258.      bR = false;
259.      break;
260.    case KeyEvent.VK_DOWN:
261.      bD = false;
262.      break;
263.    case KeyEvent.VK_A:
264.      superFire();
265.      break;
266.    }
267.    locateDirection();
268. 
269.  }
270. 
271.  public Missile fire() {
272.    if(!live) return null;
273.    int x = this.x + Tank.WIDTH/2 -Missile.WIDTH/2;
274.    int y = this.y + Tank.HEIGHT/2 -Missile.HEIGHT/2;
275.    Missile m = new Missile(x, y, ptDir, good, this.tc);
276.    tc.missiles.add(m);
277.    return m;
278.  }
279. 
280.  public Missile fire(Direction dir) {
281.    if(!live) return null;
282.    int x = this.x + Tank.WIDTH/2 -Missile.WIDTH/2;
283.    int y = this.y + Tank.HEIGHT/2 -Missile.HEIGHT/2;
284.    Missile m = new Missile(x, y, dir, good, this.tc);
285.    tc.missiles.add(m);
286.    return m;
287.  }
288. 
289.  public Rectangle getRect() {
290.    return new Rectangle(x, y, WIDTH, HEIGHT);
291.  }
292. 
293.  /**
294.   * 
295.   * @param w 被撞的墙
296.   * @return 撞上了返回true,否则false
297.   */
298.  public boolean collidesWithWall(Wall w) {
299.    if(this.live && this.getRect().intersects(w.getRect())) {
300.      this.stay();
301.      return true;
302.    }
303.    return false;
304.  }
305. 
306.  public boolean collidesWithTanks(java.util.List<Tank> tanks) {
307.    for(int i=0; i<tanks.size(); i++) {
308.      Tank t = tanks.get(i);
309.      if(this != t) {
310.        if(this.live && t.isLive() && this.getRect().intersects(t.getRect())) {
311.          this.stay();
312.          t.stay();
313.          return true;
314.        }
315.      }
316.    }
317.    return false;
318.  }
319. 
320.  private void superFire() {
321.    Direction[] dirs = Direction.values();
322.    for(int i=0; i<8; i++) {
323.      fire(dirs[i]);
324.    }
325.  }
326. 
327.  private class BloodBar {
328.    public void draw(Graphics g) {
329.      Color c = g.getColor();
330.      g.setColor(Color.RED);
331.      g.drawRect(x, y-10, WIDTH, 10);
332.      int w = WIDTH * life/100 ;
333.      g.fillRect(x, y-10, w, 10);
334.      g.setColor(c);
335. 
336.    }
337.  }
338. 
339.  public boolean eat(Blood b) {
340.    if(this.live && b.isLife() && this.getRect().intersects(b.getRect())) {
341.      this.life = 100;
342.      b.setLife(false);
343.      return true;
344.    }
345.      return false;
346.  }
347. 
348. }

TankClient类

1. package com.tank;
2. import java.awt.Color;
3. import java.awt.Frame;
4. import java.awt.Graphics;
5. import java.awt.Image;
6. import java.awt.event.KeyAdapter;
7. import java.awt.event.KeyEvent;
8. import java.awt.event.WindowAdapter;
9. import java.awt.event.WindowEvent;
10. import java.io.IOException;
11. import java.util.ArrayList;
12. import java.util.List;
13. import java.util.Properties;
14. 
15. /**
16.  * 这个类的作用是坦克游戏的主窗口
17.  * @author zhangxilin
18.  *
19.  */
20. 
21. public class TankClient extends Frame {
22.   /**
23.    * 整个坦克游戏的宽度
24.    */
25.   public static final int GAME_WIDTH = 800;
26. 
27.   public static final int GAME_HEIGHT = 600;
28. 
29.   Tank myTank = new Tank(300, 250, true, Direction.STOP, this);
30. 
31.   Wall w1 = new Wall(100, 200, 20, 150 ,this), w2 = new Wall(300, 100, 300, 20, this);
32. 
33.   List<Explode> explodes = new ArrayList<Explode>();
34.   List<Missile> missiles = new ArrayList<Missile>();
35.   List<Tank> tanks = new ArrayList<Tank>();
36. 
37.   Image offScreenImage = null;
38. 
39.   Blood b = new Blood();
40. 
41.   public void paint(Graphics g) {
42.     /*
43.      * 指明子弹-爆炸-坦克的数量
44.      * 以及坦克的生命值
45.      */
46.     g.drawString("missiles count:" + missiles.size(), 10, 50);
47.     g.drawString("explodes count:" + explodes.size(), 10, 70);
48.     g.drawString("tanks count:" + tanks.size(), 10, 90);
49.     g.drawString("tanks life:" + myTank.getLife(), 10, 110);
50. 
51.     if(tanks.size() <= 0) {
52.       for(int i=0; i<Integer.parseInt(PropertyMgr.getProperty("reProduceTankCount")); i++) {
53.         tanks.add(new Tank(50 + 40*(i+1), 50, false, Direction.D, this));
54.       }
55.     }
56. 
57.     for(int i=0; i<missiles.size(); i++) {
58.       Missile m = missiles.get(i);
59.       m.hitTanks(tanks);
60.       m.hitTank(myTank);
61.       m.hitWall(w1);
62.       m.hitWall(w2);
63.       m.draw(g);
64.       //if(!m.isLive()) missiles.remove(m);
65.       //else m.draw(g);
66.     }
67. 
68.     for(int i = 0; i<explodes.size(); i++) {
69.       Explode e = explodes.get(i);
70.       e.draw(g);
71.     }
72. 
73.     for(int i= 0;i<tanks.size(); i++) {
74.       Tank t = tanks.get(i);
75.       t.collidesWithWall(w1);
76.       t.collidesWithWall(w2);
77.       t.collidesWithTanks(tanks);
78.       t.draw(g);
79.     }
80.     myTank.draw(g);
81.     myTank.eat(b);
82.     w1.draw(g);
83.     w2.draw(g);
84.     b.draw(g);
85.   }
86. 
87.   public void update(Graphics g) {
88.     if(offScreenImage == null) {
89.       offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT);   //创建图片
90.     }
91.     //获得该图片的画笔
92.     Graphics gOffScreen = offScreenImage.getGraphics();
93.     Color c = gOffScreen.getColor();
94.     gOffScreen.setColor(Color.GREEN);
95.     gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
96.     gOffScreen.setColor(c);
97.     paint(gOffScreen);
98.     g.drawImage(offScreenImage, 0, 0, null);
99.   }
100. 
101.  /**
102.   * 本方法显示坦克主窗口
103.   * 
104.   */
105.  public void lauchFrame() {
106. 
107.    int initTankCount = Integer.parseInt(PropertyMgr.getProperty("initTankCount"));
108. System.out.println(initTankCount);
109.    for(int i=0; i<initTankCount; i++) {
110.      tanks.add(new Tank(50 + 40*(i+1), 50, false, Direction.D, this));
111.    }
112.    this.setLocation(400, 100);
113.    this.setSize(GAME_WIDTH, GAME_HEIGHT);
114.    this.setTitle("TankWar");
115.    //使用匿名类可以关闭窗口
116.    this.addWindowListener(new WindowAdapter() {
117. 
118.      public void windowClosing(WindowEvent e) {
119.        System.exit(0);
120.      }
121.    });
122.    this.setResizable(false);
123.    //设置背景颜色
124.    this.setBackground(Color.GREEN);
125.    this.addKeyListener(new KeyMonitor());
126.    setVisible(true);
127. 
128.    new Thread(new PaintThread()).start();
129.  }
130. 
131.  public static void main(String[] args) {
132.    TankClient tc = new TankClient();
133.    tc.lauchFrame();
134.  }
135. 
136.  private class PaintThread implements Runnable {
137. 
138.    public void run() {
139.      while(true) {
140.        repaint();     //调用的外部类即TankWar的paint()方法,   repaint()首先调用update()方法,再调用paint()方法
141.        try {
142.          Thread.sleep(100);
143.        } catch (InterruptedException e) {
144. 
145.          e.printStackTrace();
146.        }
147.      }
148.    }
149.  }
150. 
151.  private class KeyMonitor extends KeyAdapter {
152. 
153. 
154.    public void keyReleased(KeyEvent e) {
155.      myTank.keyReleased(e);
156.    }
157. 
158.    public void keyPressed(KeyEvent e) {
159.      myTank.KeyPressed(e);
160.    }
161. 
162.  }
163. }

Wall类

1. package com.tank;
2. import java.awt.*;
3. public class Wall {
4.  int x, y, w, h;
5.  TankClient tc;
6. 
7.  public Wall(int x, int y, int w, int h, TankClient tc) {
8.    super();
9.    this.x = x;
10.     this.y = y;
11.     this.w = w;
12.     this.h = h;
13.     this.tc = tc;
14.   }
15. 
16.   public void draw(Graphics g) {
17.     g.fillRect(x, y, w, h);
18.   }
19. 
20.   public Rectangle getRect() {
21.     return new Rectangle(x, y, w, h);
22.   }
23. }

2.实机演示(爆笑流演示:唐克大战)

image.png

实机演示(爆笑流演示:唐克大战)

相关文章
|
6月前
|
Java Android开发
五子棋【小游戏】(Java课设)
五子棋【小游戏】(Java课设)
40 1
|
6月前
|
Java Android开发
扫雷【小游戏】(Java课设)
扫雷【小游戏】(Java课设)
43 1
|
6月前
|
Java Android开发
贪吃蛇【小游戏】(Java课设)
贪吃蛇【小游戏】(Java课设)
40 0
|
5月前
|
Java
Java 实现 捕鱼达人 小游戏【附源码】
Java 实现 捕鱼达人 小游戏【附源码】
267 0
|
5月前
|
Java
Java实现一个坦克大战的小游戏【附源码】
Java实现一个坦克大战的小游戏【附源码】
206 0
|
3月前
|
数据可视化 Java
使用ChatGPT实现可视化操作扫雷小游戏 【java代码实现】
这篇文章介绍了使用Java语言和Swing框架实现的扫雷小游戏的详细代码和实现过程。
使用ChatGPT实现可视化操作扫雷小游戏 【java代码实现】
|
3月前
|
人工智能 Java 定位技术
人工智能ChatGPT 体验案例:使用ChatGPT实现java扫雷小游戏
这篇文章通过一个使用ChatGPT实现的Java扫雷小游戏案例,展示了ChatGPT在编程领域的应用能力。文章中包含了扫雷游戏的Java代码实现,代码中初始化了雷区地图,随机放置雷,计算每个格子周围雷的数量,并提供了一个简单的文本界面与用户交互进行游戏。游戏通过控制台输入接受玩家的指令,并给出相应的反馈。
人工智能ChatGPT 体验案例:使用ChatGPT实现java扫雷小游戏
|
6月前
|
Java 程序员 图形学
程序员教你用代码制作飞翔的小鸟--Java小游戏,正好拿去和给女神一起玩
《飞扬的小鸟》Java实现摘要:使用IntelliJ IDEA和JDK 16开发,包含小鸟类`Bird`,处理小鸟的位置、速度和碰撞检测。代码示例展示小鸟图像的加载、绘制与旋转。同时有`Music`类用于循环播放背景音乐。游戏运行时检查小鸟是否撞到地面、柱子或星星,并实现翅膀煽动效果。简单易懂,可直接复制使用。
129 0
|
3月前
|
Java
05 Java代码实现一个小游戏(剪刀石头布)和一个简易的万年历
05 Java代码实现一个小游戏(剪刀石头布)和一个简易的万年历
72 2
|
4月前
|
Java
[Java]猜数字小游戏
Java生成一个猜数字的小游戏
21 0