java学习之坦克大战游戏
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java学习之坦克大战游戏相关的知识,希望对你有一定的参考价值。
总结:由于这几天快过年比较忙然后没怎么写,写代码途中一些经验总结现在给忘记了。这次的小项目感觉比上次写的思路清楚了点。没有之前第一次写那么逻辑混乱,结构也搞的比之前的要好,添加功能比较容易。学习了之前的经验,操作对象的方法由对象本身提供。不过这次小项目还有不足和不完善之处,有些可以做的功能没有实现,比如游戏存档,这里应该可以用下对象的序列化,还有游戏难度的设置也可以写个文件弄出来。要过年了,到处走亲戚没什么心思写了,这里只能留个尾巴了。
前言:之前的及时通信项目完成后感觉线程方面和对java的运用还不是很熟悉,在另外一个学习视频中看到一个做坦克游戏的项目视频,便想自己试着做做看,先看视频把游戏规则什么的都搞清楚。然后开始一步一步实现。
主要功能步骤如下
* 1、画出坦克
* 2、我的坦克可以上下移动
* 3、可以发射子弹,子弹连发(或者最多5发)
* 4、当我的坦克击中敌人坦克时,敌人坦克消失(或者爆炸效果)
* 5、我被击中也显示爆炸效果。
* 6、游戏开始和游戏介绍选项
这次游戏界面没有进行设计,直接在一个frame上放个panel。
游戏设计仿mvc 这里不做详细介绍了直接上代码
model包
![技术分享](https://image.cha138.com/20200613/c87b444e0e86477d829c291023c128ec.jpg)
package com.gh.model; /** * 爆炸类 * 考虑到同时爆炸定义个类 * @author ganhang * */ public class Bomb { private int x; private int y;//坐标 public boolean islive=true; private int time=9;//炸弹生命 public Bomb() { super(); } public Bomb(int x, int y) { super(); this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public int getTime() { return time; } //生命递减 public void livedown(){ if(time>0){ time--; }else{ islive=false; } } }
![技术分享](https://image.cha138.com/20200613/c87b444e0e86477d829c291023c128ec.jpg)
1 package com.gh.model; 2 /** 3 * 子弹类, 4 * 因为多个子弹同时运动所以需要个内部类做线程 5 * @author ganhang 6 * 7 */ 8 public class Bullet { 9 private int x; 10 private int y; 11 private int speed; 12 private int drect; 13 public boolean islive=true; 14 public Bullet(int x, int y, int speed, int drect) { 15 super(); 16 this.x = x; 17 this.y = y; 18 this.speed = speed; 19 this.drect = drect; 20 new Thread(new BulletThread()).start(); 21 } 22 public Bullet() { 23 super(); 24 } 25 26 public int getX() { 27 return x; 28 } 29 30 public void setX(int x) { 31 this.x = x; 32 } 33 34 public int getY() { 35 return y; 36 } 37 38 public void setY(int y) { 39 this.y = y; 40 } 41 42 class BulletThread implements Runnable { 43 @Override 44 public void run() { 45 while (true) { 46 try { 47 Thread.sleep(50); 48 } catch (Exception e) { 49 e.printStackTrace(); 50 } 51 switch (drect) {//判断方向坐标移动 52 case 0: 53 y-=speed; 54 break; 55 case 1: 56 x+=speed; 57 break; 58 case 2: 59 y+=speed; 60 break; 61 case 3: 62 x-=speed; 63 break; 64 } 65 if (x < 0 || y < 0 || x > 500 || y > 500||!islive) { 66 islive=false; 67 break; 68 } 69 } 70 } 71 } 72 }
![技术分享](https://image.cha138.com/20200613/c87b444e0e86477d829c291023c128ec.jpg)
package com.gh.model; /** * 地图坐标标记 * 防止敌方坦克重叠 * @author ganhang * */ public class Map { public int[][] location=new int[500][500]; public Map() { for (int i = 0; i < 500; i++) { for (int j = 0; j <500; j++) { location[i][j]=0; } } } }
坦克类,刚才上传发现点问题暂时没改
![技术分享](https://image.cha138.com/20200613/c87b444e0e86477d829c291023c128ec.jpg)
1 package com.gh.model; 2 3 import java.util.Vector; 4 /** 5 * 坦克类 6 * 每个坦克就是一个线程, 7 * 这里自己坦克并没有启动线程 8 * @author ganhang 9 * 10 */ 11 public class Tank implements Runnable { 12 private int x = 0; 13 private int y = 0;// 坐标 14 private int drect = 0;// 方向 0向上,1向右,2向下,3向左; 15 private int type = 0;// 坦克类型 0表示自己 16 private int speed = 3;// 速度 17 public Vector<Bullet> mybs = new Vector<Bullet>();// 子弹集 18 private Bullet myBullet;// 子弹 19 public boolean islive = true; 20 private Map map; 21 public boolean start = true; 22 public Map getMap() { 23 return map; 24 } 25 26 public void setMap(Map map) { 27 this.map = map; 28 } 29 30 public Tank(int x, int y, int drect, int type) { 31 super(); 32 this.x = x; 33 this.y = y; 34 this.drect = drect; 35 this.type = type; 36 } 37 38 public Tank() { 39 super(); 40 } 41 42 public Bullet getMyBullet() { 43 return myBullet; 44 } 45 46 public int getSpeed() { 47 return speed; 48 } 49 50 public void setSpeed(int speed) { 51 this.speed = speed; 52 } 53 54 public int getX() { 55 return x; 56 } 57 58 public int getDrect() { 59 return drect; 60 } 61 62 public void setDrect(int drect) { 63 this.drect = drect; 64 } 65 66 public int getType() { 67 return type; 68 } 69 70 public void setType(int type) { 71 this.type = type; 72 } 73 74 public void setX(int x) { 75 this.x = x; 76 } 77 78 public int getY() { 79 return y; 80 } 81 82 public void setY(int y) { 83 this.y = y; 84 } 85 86 public void moveUp() { 87 if (y - speed < 0) 88 y = 0; 89 else { 90 y -= speed; 91 map.location[x][y]=1;//标记此坦克坐标在地图上防止其他坦克过来占用导致重叠 92 // 这里只标记了坦克坐标那一个点,会有bug,部分坦克还是有重叠现象, 93 // 这里可以遍历整个坦克坐标(x到x+20,y到y+30)设置标记。 94 // for(int i=x;i<x+20;i++){ 95 // for (int j = y; j < y+30; j++) { 96 // map.location[x][y]=1; 97 // } 98 // } 99 } 100 } 101 102 public void moveDown() { 103 if (y + speed > 470) 104 y = 470; 105 else { 106 y += speed; 107 map.location[x][y]=1; 108 } 109 } 110 111 public void moveRight() { 112 if (x + speed > 470) 113 x = 470; 114 else { 115 x += speed; 116 map.location[x][y]=1; 117 } 118 } 119 120 public void moveLeft() { 121 if (x - speed < 0) 122 x = 0; 123 else { 124 x -= speed; 125 map.location[x][y]=1; 126 } 127 } 128 129 public void shot() { 130 switch (drect) { 131 case 0: 132 myBullet = new Bullet(x + 10, y, 5, 0); 133 mybs.add(myBullet); 134 break; 135 case 1: 136 myBullet = new Bullet(x + 30, y + 10, 5, 1); 137 mybs.add(myBullet); 138 break; 139 case 2: 140 myBullet = new Bullet(x + 10, y + 30, 5, 2); 141 mybs.add(myBullet); 142 break; 143 case 3: 144 myBullet = new Bullet(x, y + 10, 5, 3); 145 mybs.add(myBullet); 146 break; 147 } 148 } 149 150 @Override 151 public void run() { 152 while (islive) { 153 if (start) { 154 int step; 155 int s; 156 try { 157 switch (drect) { 158 case 0: 159 step = (int) (Math.random() * 30); 160 for (int i = 0; i < step; i++) { 161 moveUp(); 162 if (y <= 0) 163 break;// 撞墙跳出循环 164 if (y >= 30)// 仿数组越界 165 if (map.location[x][y - 30] == 1 || map.location[x][y - 20] == 1) { 166 map.location[x][y - 30] = 0;//这里没分开判断 167 map.location[x][y - 20] = 0; 168 break; 169 } 170 Thread.sleep(80); 171 } 172 break; 173 case 1: 174 step = (int) (Math.random() * 30); 175 for (int i = 0; i < step; i++) { 176 moveRight(); 177 if (x >= 500) 178 break; 179 if (x < 470) 180 if (map.location[x + 20][y] == 1 || map.location[x + 30][y] == 1) { 181 map.location[x + 20][y] = 0; 182 map.location[x + 30][y] = 0; 183 break; 184 } 185 Thread.sleep(80); 186 } 187 break; 188 case 2: 189 step = (int) (Math.random() * 30); 190 for (int i = 0; i < step; i++) { 191 moveDown(); 192 if (y >= 500) 193 break; 194 if (y < 470) 195 if (map.location[x][y + 30] == 1 || map.location[x][y + 20] == 1) { 196 map.location[x][y + 30] = 0; 197 map.location[x][y + 20] = 0; 198 break; 199 } 200 Thread.sleep(80); 201 } 202 break; 203 case 3: 204 step = (int) (Math.random() * 30); 205 for (int i = 0; i < step; i++) { 206 moveLeft(); 207 if (x <= 0) 208 break; 209 if (x >= 30) 210 if (map.location[x - 20][y] == 1 || map.location[x - 30][y] == 1) { 211 map.location[x - 20][y] = 0; 212 map.location[x - 30][y] = 0; 213 break; 214 } 215 Thread.sleep(80); 216 } 217 break; 218 } 219 } catch (InterruptedException e) { 220 e.printStackTrace(); 221 } 222 drect = (int) (Math.random() * 4);// 随机方向 223 s = (int) (Math.random() * 10); 224 if (s > 8) { 225 shot(); 226 } 227 } 228 } 229 } 230 }
view包
![技术分享](https://image.cha138.com/20200613/c87b444e0e86477d829c291023c128ec.jpg)
1 package com.gh.view; 2 3 import java.awt.Color; 4 import java.awt.Graphics; 5 import java.awt.Image; 6 import java.awt.Toolkit; 7 import java.util.Vector; 8 9 import javax.swing.JOptionPane; 10 import javax.swing.JPanel; 11 12 import com.gh.model.Bomb; 13 import com.gh.model.Bullet; 14 import com.gh.model.Map; 15 import com.gh.model.Tank; 16 17 /** 18 * 游戏显示面板 19 * 20 * @author ganhang 21 * 22 */ 23 24 public class Mypanel extends JPanel implements Runnable { 25 public Tank mytank = null;// 我的坦克 26 Tank ek = null; 27 Image img; 28 Vector<Tank> eks = new Vector<Tank>();//地方坦克集 29 Vector<Bomb> bs = new Vector<Bomb>();//爆炸集合 30 Map map = new Map(); 31 32 public Mypanel() { 33 mytank = new Tank(200, 200, 0, 0); 34 mytank.setMap(map); 35 // 创建敌人坦克 36 for (int i = 0; i < 17; i++) { 37 ek = new Tank(i * 30, 10, 2, 1); 38 eks.add(ek); 39 ek.setMap(map); 40 new Thread(ek).start(); 41 } 42 img = Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("/1.png")); 43 } 44 45 @Override 46 public void paint(Graphics g) { 47 super.paint(g); 48 // 画背景 49 g.fillRect(0, 0, 500, 500); 50 // 画自己的坦克 51 if (mytank.islive) 52 drawTank(mytank.getX(), mytank.getY(), g, mytank.getDrect(), mytank.getType()); 53 // 画自己的子弹 54 for (int i = 0; i < mytank.mybs.size(); i++) {// 循环时删除集合时,不要用foreach,用for 55 Bullet b = new Bullet(); 56 b = mytank.mybs.get(i); 57 if (b.islive) { 58 g.setColor(Color.white); 59 g.fill3DRect(b.getX(), b.getY(), 2, 2, false); 60 } else 61 mytank.mybs.remove(b); 62 } 63 // 画敌人坦克 64 for (int i = 0; i < eks.size(); i++) { 65 Tank ek = new Tank(); 66 ek = eks.get(i); 67 if (ek.islive) 68 drawEnemyTank(ek.getX(), ek.getY(), ek.getDrect(), g); 69 // 画敌人子弹 70 for (int j = 0; j < ek.mybs.size(); j++) { 71 Bullet eb = new Bullet(); 72 eb = ek.mybs.get(j); 73 if (eb.islive) { 74 g.setColor(Color.green); 75 g.fill3DRect(eb.getX(), eb.getY(), 2, 2, false); 76 } else 77 ek.mybs.remove(eb); 78 } 79 } 80 // 画爆炸,这里有个bug第一次爆炸没有爆炸效果图出来,检查原因是只一闪而过 81 // 添加休眠好了点,不过影响后面爆炸效果,不明白为什么第一次画得快些 82 for (int i = 0; i < bs.size(); i++) { 83 // System.out.println(bs.size()); 84 Bomb bb = bs.get(i); 85 if (bb.islive) { 86 if (bb.getTime() > 6) { 87 try { 88 Thread.sleep(50); 89 } catch (Exception e) { 90 e.printStackTrace(); 91 } 92 g.drawImage(img, bb.getX(), bb.getY(), 30, 30, this); 93 } else if (bb.getTime() > 3) { 94 g.drawImage(img, bb.getX(), bb.getY(), 15, 15, this); 95 } else if (bb.getTime() > 0) { 96 g.drawImage(img, bb.getX(), bb.getY(), 1, 1, this); 97 } 98 } 99 bb.livedown(); 100 if (bb.getTime() == 0) 101 bs.remove(bb); 102 } 103 } 104 105 public boolean isHitEnemy(Bullet b, Tank ek) { 106 if (ek.getDrect() == 0 || ek.getDrect() == 2) { 107 // 坦克竖着时宽20,高30 108 if (b.getX() >= ek.getX() && b.getX() <= ek.getX() + 20 && b.getY() >= ek.getY() 109 && b.getY() <= ek.getY() + 30) { 110 b.islive = false; 111 ek.islive = false; 112
以上是关于java学习之坦克大战游戏的主要内容,如果未能解决你的问题,请参考以下文章
韩顺平循序渐进学Java零基础 项目篇(09161820222628)