diff --git a/tank/src/com/mashibing/tank/Bullet.java b/tank/src/com/mashibing/tank/Bullet.java index 70b3425..f0770f9 100644 --- a/tank/src/com/mashibing/tank/Bullet.java +++ b/tank/src/com/mashibing/tank/Bullet.java @@ -3,31 +3,33 @@ import java.awt.Graphics; import java.awt.Rectangle; -public class Bullet { +public class Bullet extends GameObject { private static final int SPEED = 6; public static int WIDTH = ResourceMgr.bulletD.getWidth(); public static int HEIGHT = ResourceMgr.bulletD.getHeight(); - Rectangle rect = new Rectangle(); + public Rectangle rect = new Rectangle(); + - private int x, y; private Dir dir; private boolean living = true; - TankFrame tf = null; - private Group group = Group.BAD; + + public Group group = Group.BAD; - public Bullet(int x, int y, Dir dir, Group group, TankFrame tf) { + public Bullet(int x, int y, Dir dir, Group group) { this.x = x; this.y = y; this.dir = dir; this.group = group; - this.tf = tf; + rect.x = this.x; rect.y = this.y; rect.width = WIDTH; rect.height = HEIGHT; + + GameModel.getInstance().add(this); } @@ -41,7 +43,7 @@ public void setGroup(Group group) { public void paint(Graphics g) { if(!living) { - tf.bullets.remove(this); + GameModel.getInstance().remove(this); } switch(dir) { @@ -87,20 +89,19 @@ private void move() { } - public void collideWith(Tank tank) { - if(this.group == tank.getGroup()) return; - - if(rect.intersects(tank.rect)) { - tank.die(); - this.die(); - int eX = tank.getX() + Tank.WIDTH/2 - Explode.WIDTH/2; - int eY = tank.getY() + Tank.HEIGHT/2 - Explode.HEIGHT/2; - tf.explodes.add(new Explode(eX, eY, tf)); - } - - } + - private void die() { + public void die() { this.living = false; } + + @Override + public int getWidth() { + return WIDTH; + } + + @Override + public int getHeight() { + return HEIGHT; + } } diff --git a/tank/src/com/mashibing/tank/Explode.java b/tank/src/com/mashibing/tank/Explode.java index f32038c..942a234 100644 --- a/tank/src/com/mashibing/tank/Explode.java +++ b/tank/src/com/mashibing/tank/Explode.java @@ -3,23 +3,22 @@ import java.awt.Graphics; import java.awt.Rectangle; -public class Explode { +public class Explode extends GameObject { public static int WIDTH = ResourceMgr.explodes[0].getWidth(); public static int HEIGHT = ResourceMgr.explodes[0].getHeight(); - private int x, y; + //private boolean living = true; - TankFrame tf = null; private int step = 0; - public Explode(int x, int y, TankFrame tf) { + public Explode(int x, int y) { this.x = x; this.y = y; - this.tf = tf; new Thread(()->new Audio("audio/explode.wav").play()).start(); + GameModel.getInstance().add(this); } @@ -29,11 +28,20 @@ public void paint(Graphics g) { g.drawImage(ResourceMgr.explodes[step++], x, y, null); if(step >= ResourceMgr.explodes.length) - tf.explodes.remove(this); + GameModel.getInstance().remove(this); } + @Override + public int getWidth() { + return WIDTH; + } + + @Override + public int getHeight() { + return HEIGHT; + } } diff --git a/tank/src/com/mashibing/tank/GameModel.java b/tank/src/com/mashibing/tank/GameModel.java new file mode 100644 index 0000000..76c24fd --- /dev/null +++ b/tank/src/com/mashibing/tank/GameModel.java @@ -0,0 +1,139 @@ +package com.mashibing.tank; + +import java.awt.Color; +import java.awt.Graphics; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.List; + +import com.mashibing.tank.cor.ColliderChain; + +public class GameModel { + + private static final GameModel INSTANCE = new GameModel(); + + static { + INSTANCE.init(); + } + + Tank myTank; + + // List bullets = new ArrayList<>(); + // List tanks = new ArrayList<>(); + // List explodes = new ArrayList<>(); + ColliderChain chain = new ColliderChain(); + + private List objects = new ArrayList<>(); + + public static GameModel getInstance() { + return INSTANCE; + } + + private GameModel() {} + + private void init() { + // 初始化主战坦克 + myTank = new Tank(200, 400, Dir.DOWN, Group.GOOD); + + int initTankCount = Integer.parseInt((String) PropertyMgr.get("initTankCount")); + + // 初始化敌方坦克 + for (int i = 0; i < initTankCount; i++) { + new Tank(50 + i * 80, 200, Dir.DOWN, Group.BAD); + } + + // 初始化墙 + add(new Wall(150, 150, 200, 50)); + add(new Wall(550, 150, 200, 50)); + add(new Wall(300, 300, 50, 200)); + add(new Wall(550, 300, 50, 200)); + } + + public void add(GameObject go) { + this.objects.add(go); + } + + public void remove(GameObject go) { + this.objects.remove(go); + } + + public void paint(Graphics g) { + Color c = g.getColor(); + g.setColor(Color.WHITE); + // g.drawString("子弹的数量:" + bullets.size(), 10, 60); + // g.drawString("敌人的数量:" + tanks.size(), 10, 80); + // g.drawString("爆炸的数量:" + explodes.size(), 10, 100); + g.setColor(c); + + myTank.paint(g); + for (int i = 0; i < objects.size(); i++) { + objects.get(i).paint(g); + } + + // 互相碰撞 + for (int i = 0; i < objects.size(); i++) { + for (int j = i + 1; j < objects.size(); j++) { // Comparator.compare(o1,o2) + GameObject o1 = objects.get(i); + GameObject o2 = objects.get(j); + // for + chain.collide(o1, o2); + } + } + + // for (int i = 0; i < bullets.size(); i++) { + // for (int j = 0; j < tanks.size(); j++) + // bullets.get(i).collideWith(tanks.get(j)); + // } + + } + + public Tank getMainTank() { + return myTank; + } + + public void save() { + File f = new File("c:/mashibing/tank.data"); + ObjectOutputStream oos = null; + try { + oos = new ObjectOutputStream(new FileOutputStream(f)); + oos.writeObject(myTank); + oos.writeObject(objects); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if(oos != null) { + try { + oos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + public void load() { + File f = new File("c:/mashibing/tank.data"); + try { + ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f)); + myTank = (Tank)ois.readObject(); + objects = (List)ois.readObject(); + + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + +} diff --git a/tank/src/com/mashibing/tank/GameObject.java b/tank/src/com/mashibing/tank/GameObject.java new file mode 100644 index 0000000..5eb144c --- /dev/null +++ b/tank/src/com/mashibing/tank/GameObject.java @@ -0,0 +1,12 @@ +package com.mashibing.tank; + +import java.awt.Graphics; +import java.io.Serializable; + +public abstract class GameObject implements Serializable { + public int x, y; + + public abstract void paint(Graphics g); + public abstract int getWidth(); + public abstract int getHeight(); +} diff --git a/tank/src/com/mashibing/tank/Main.java b/tank/src/com/mashibing/tank/Main.java index b4692ad..42b8388 100644 --- a/tank/src/com/mashibing/tank/Main.java +++ b/tank/src/com/mashibing/tank/Main.java @@ -5,12 +5,7 @@ public class Main { public static void main(String[] args) throws InterruptedException { TankFrame tf = new TankFrame(); - int initTankCount = Integer.parseInt((String)PropertyMgr.get("initTankCount")); - //初始化敌方坦克 - for(int i=0; inew Audio("audio/war1.wav").loop()).start(); diff --git a/tank/src/com/mashibing/tank/PropertyMgr.java b/tank/src/com/mashibing/tank/PropertyMgr.java index 4fd4e87..0f8b5e0 100644 --- a/tank/src/com/mashibing/tank/PropertyMgr.java +++ b/tank/src/com/mashibing/tank/PropertyMgr.java @@ -19,7 +19,11 @@ public static Object get(String key) { return props.get(key); } + //int getInt(key) + //getString(key) + public static void main(String[] args) { System.out.println(PropertyMgr.get("initTankCount")); + } } diff --git a/tank/src/com/mashibing/tank/Tank.java b/tank/src/com/mashibing/tank/Tank.java index c995a59..fbb7bdb 100644 --- a/tank/src/com/mashibing/tank/Tank.java +++ b/tank/src/com/mashibing/tank/Tank.java @@ -2,64 +2,105 @@ import java.awt.Graphics; import java.awt.Rectangle; +import java.util.Arrays; +import java.util.List; import java.util.Random; -public class Tank { +import com.mashibing.tank.observer.TankFireEvent; +import com.mashibing.tank.observer.TankFireHandler; +import com.mashibing.tank.observer.TankFireObserver; +import com.mashibing.tank.strategy.DefaultFireStrategy; +import com.mashibing.tank.strategy.FireStrategy; + +public class Tank extends GameObject { + private static final int SPEED = 2; public static int WIDTH = ResourceMgr.goodTankU.getWidth(); public static int HEIGHT = ResourceMgr.goodTankU.getHeight(); - - Rectangle rect = new Rectangle(); - - private Random random = new Random(); - private int x, y; + public Rectangle rect = new Rectangle(); + + private Random random = new Random(); + + int oldX, oldY; - private Dir dir = Dir.DOWN; + public Dir dir = Dir.DOWN; private boolean moving = true; - private TankFrame tf = null; + private boolean living = true; - private Group group = Group.BAD; + + public Group group = Group.BAD; + FireStrategy fs; + - public Tank(int x, int y, Dir dir, Group group, TankFrame tf) { + public Tank(int x, int y, Dir dir, Group group) { super(); this.x = x; this.y = y; this.dir = dir; this.group = group; - this.tf = tf; + rect.x = this.x; rect.y = this.y; rect.width = WIDTH; rect.height = HEIGHT; - } - public void fire() { - int bX = this.x + Tank.WIDTH/2 - Bullet.WIDTH/2; - int bY = this.y + Tank.HEIGHT/2 - Bullet.HEIGHT/2; - - tf.bullets.add(new Bullet(bX, bY, this.dir, this.group, this.tf)); + + if (group == Group.GOOD) { + String goodFSName = (String) PropertyMgr.get("goodFS"); + + try { + fs = (FireStrategy) Class.forName(goodFSName).getDeclaredConstructor().newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + + } else { + fs = new DefaultFireStrategy(); + } - if(this.group == Group.GOOD) new Thread(()->new Audio("audio/tank_fire.wav").play()).start(); + GameModel.getInstance().add(this); } - - public Dir getDir() { - return dir; + + private void boundsCheck() { + if (this.x < 2) + x = 2; + if (this.y < 28) + y = 28; + if (this.x > TankFrame.GAME_WIDTH - Tank.WIDTH - 2) + x = TankFrame.GAME_WIDTH - Tank.WIDTH - 2; + if (this.y > TankFrame.GAME_HEIGHT - Tank.HEIGHT - 2) + y = TankFrame.GAME_HEIGHT - Tank.HEIGHT - 2; } - - public int getX() { - return x; + + public void die() { + this.living = false; } + + public void fire() { + fs.fire(this); + } + + public Dir getDir() { + return dir; + } + public Group getGroup() { return group; } - public void setGroup(Group group) { - this.group = group; + + public Rectangle getRect() { + return rect; } + + public int getX() { + return x; + } + public int getY() { return y; } @@ -67,11 +108,20 @@ public int getY() { public boolean isMoving() { return moving; } - + + public void back() { + x = oldX; + y = oldY; + } + private void move() { + //记录移动之前的位置 + oldX = x; + oldY = y; - if(!moving) return ; - + if (!moving) + return; + switch (dir) { case LEFT: x -= SPEED; @@ -86,61 +136,56 @@ private void move() { y += SPEED; break; } - - if(this.group == Group.BAD && random.nextInt(100) > 95) + + if (this.group == Group.BAD && random.nextInt(100) > 95) this.fire(); - - if(this.group == Group.BAD && random.nextInt(100) > 95) + + if (this.group == Group.BAD && random.nextInt(100) > 95) randomDir(); - + boundsCheck(); - //update rect + // update rect rect.x = this.x; rect.y = this.y; - - } - private void boundsCheck() { - if (this.x < 2) x = 2; - if (this.y < 28) y = 28; - if (this.x > TankFrame.GAME_WIDTH- Tank.WIDTH -2) x = TankFrame.GAME_WIDTH - Tank.WIDTH -2; - if (this.y > TankFrame.GAME_HEIGHT - Tank.HEIGHT -2 ) y = TankFrame.GAME_HEIGHT -Tank.HEIGHT -2; } - - private void randomDir() { - - this.dir = Dir.values()[random.nextInt(4)]; - } - + public void paint(Graphics g) { - if(!living) tf.tanks.remove(this); - - - - switch(dir) { + if (!living) + GameModel.getInstance().remove(this); + + switch (dir) { case LEFT: - g.drawImage(this.group == Group.GOOD? ResourceMgr.goodTankL : ResourceMgr.badTankL, x, y, null); + g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankL : ResourceMgr.badTankL, x, y, null); break; case UP: - g.drawImage(this.group == Group.GOOD? ResourceMgr.goodTankU : ResourceMgr.badTankU, x, y, null); + g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankU : ResourceMgr.badTankU, x, y, null); break; case RIGHT: - g.drawImage(this.group == Group.GOOD? ResourceMgr.goodTankR : ResourceMgr.badTankR, x, y, null); + g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankR : ResourceMgr.badTankR, x, y, null); break; case DOWN: - g.drawImage(this.group == Group.GOOD? ResourceMgr.goodTankD : ResourceMgr.badTankD, x, y, null); + g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankD : ResourceMgr.badTankD, x, y, null); break; } - + move(); - + } + private void randomDir() { + + this.dir = Dir.values()[random.nextInt(4)]; + } public void setDir(Dir dir) { this.dir = dir; } + public void setGroup(Group group) { + this.group = group; + } + public void setMoving(boolean moving) { this.moving = moving; } @@ -152,10 +197,27 @@ public void setX(int x) { public void setY(int y) { this.y = y; } - public void die() { - this.living = false; + + public void stop() { + moving = false; } + @Override + public int getWidth() { + return WIDTH; + } + + @Override + public int getHeight() { + return HEIGHT; + } + private List fireObservers = Arrays.asList(new TankFireHandler()); + public void handleFireKey() { + TankFireEvent event = new TankFireEvent(this); + for(TankFireObserver o : fireObservers) { + o.actionOnFire(event); + } + } } diff --git a/tank/src/com/mashibing/tank/TankFrame.java b/tank/src/com/mashibing/tank/TankFrame.java index 94a488e..363974e 100644 --- a/tank/src/com/mashibing/tank/TankFrame.java +++ b/tank/src/com/mashibing/tank/TankFrame.java @@ -13,12 +13,8 @@ import java.util.List; public class TankFrame extends Frame { - - Tank myTank = new Tank(200, 400, Dir.DOWN, Group.GOOD, this); - List bullets = new ArrayList<>(); - List tanks = new ArrayList<>(); - List explodes = new ArrayList<>(); + GameModel gm = GameModel.getInstance(); static final int GAME_WIDTH = 1080, GAME_HEIGHT = 960; @@ -34,6 +30,7 @@ public TankFrame() { @Override public void windowClosing(WindowEvent e) { // bjmashibing/tank + System.exit(0); } @@ -58,42 +55,9 @@ public void update(Graphics g) { @Override public void paint(Graphics g) { - Color c = g.getColor(); - g.setColor(Color.WHITE); - g.drawString("子弹的数量:" + bullets.size(), 10, 60); - g.drawString("敌人的数量:" + tanks.size(), 10, 80); - g.drawString("爆炸的数量:" + explodes.size(), 10, 100); - g.setColor(c); - - myTank.paint(g); - for (int i = 0; i < bullets.size(); i++) { - bullets.get(i).paint(g); - } - - for (int i = 0; i < tanks.size(); i++) { - tanks.get(i).paint(g); - } - - for (int i = 0; i < explodes.size(); i++) { - explodes.get(i).paint(g); - } - //collision detect - - for(int i=0; i it = bullets.iterator(); it.hasNext();) { - // Bullet b = it.next(); - // if(!b.live) it.remove(); - // } - - // for(Bullet b : bullets) { - // b.paint(g); - // } } @@ -120,6 +84,12 @@ public void keyPressed(KeyEvent e) { case KeyEvent.VK_DOWN: bD = true; break; + case KeyEvent.VK_S: + gm.save(); + break; + case KeyEvent.VK_L: + gm.load(); + break; default: break; @@ -132,6 +102,7 @@ public void keyPressed(KeyEvent e) { @Override public void keyReleased(KeyEvent e) { + int key = e.getKeyCode(); switch (key) { case KeyEvent.VK_LEFT: @@ -148,7 +119,7 @@ public void keyReleased(KeyEvent e) { break; case KeyEvent.VK_CONTROL: - myTank.fire(); + gm.getMainTank().handleFireKey(); break; default: @@ -159,6 +130,7 @@ public void keyReleased(KeyEvent e) { } private void setMainTankDir() { + Tank myTank = gm.getMainTank(); if (!bL && !bU && !bR && !bD) myTank.setMoving(false); @@ -177,3 +149,5 @@ private void setMainTankDir() { } } } + +//e.getSource().repaint() \ No newline at end of file diff --git a/tank/src/com/mashibing/tank/Wall.java b/tank/src/com/mashibing/tank/Wall.java new file mode 100644 index 0000000..9c1e0fe --- /dev/null +++ b/tank/src/com/mashibing/tank/Wall.java @@ -0,0 +1,40 @@ +package com.mashibing.tank; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Rectangle; + +public class Wall extends GameObject { + + int w, h; + + public Rectangle rect; + + public Wall(int x, int y, int w, int h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + + this.rect = new Rectangle(x, y, w, h); + } + + @Override + public void paint(Graphics g) { + Color c = g.getColor(); + g.setColor(Color.DARK_GRAY); + g.fillRect(x, y, w, h); + g.setColor(c); + } + + @Override + public int getWidth() { + return w; + } + + @Override + public int getHeight() { + return h; + } + +} diff --git a/tank/src/com/mashibing/tank/cor/BulletTankCollider.java b/tank/src/com/mashibing/tank/cor/BulletTankCollider.java new file mode 100644 index 0000000..de8c8c8 --- /dev/null +++ b/tank/src/com/mashibing/tank/cor/BulletTankCollider.java @@ -0,0 +1,35 @@ +package com.mashibing.tank.cor; + +import com.mashibing.tank.Bullet; +import com.mashibing.tank.Explode; +import com.mashibing.tank.GameObject; +import com.mashibing.tank.Tank; + +public class BulletTankCollider implements Collider { + + @Override + public boolean collide(GameObject o1, GameObject o2) { + if(o1 instanceof Bullet && o2 instanceof Tank) { + Bullet b = (Bullet)o1; + Tank t = (Tank)o2; + //TODO copy code from method collideWith + if(b.group == t.getGroup()) return true; + + if(b.rect.intersects(t.rect)) { + t.die(); + b.die(); + int eX = t.getX() + Tank.WIDTH/2 - Explode.WIDTH/2; + int eY = t.getY() + Tank.HEIGHT/2 - Explode.HEIGHT/2; + new Explode(eX, eY); + return false; + } + + } else if (o1 instanceof Tank && o2 instanceof Bullet) { + return collide(o2, o1); + } + + return true; + + } + +} diff --git a/tank/src/com/mashibing/tank/cor/BulletWallCollider.java b/tank/src/com/mashibing/tank/cor/BulletWallCollider.java new file mode 100644 index 0000000..fcf7a64 --- /dev/null +++ b/tank/src/com/mashibing/tank/cor/BulletWallCollider.java @@ -0,0 +1,28 @@ +package com.mashibing.tank.cor; + +import com.mashibing.tank.Bullet; +import com.mashibing.tank.GameObject; +import com.mashibing.tank.Wall; + +public class BulletWallCollider implements Collider { + + @Override + public boolean collide(GameObject o1, GameObject o2) { + if(o1 instanceof Bullet && o2 instanceof Wall) { + Bullet b = (Bullet)o1; + Wall w = (Wall)o2; + + + if(b.rect.intersects(w.rect)) { + b.die(); + } + + } else if (o1 instanceof Wall && o2 instanceof Bullet) { + return collide(o2, o1); + } + + return true; + + } + +} diff --git a/tank/src/com/mashibing/tank/cor/Collider.java b/tank/src/com/mashibing/tank/cor/Collider.java new file mode 100644 index 0000000..e82a1c7 --- /dev/null +++ b/tank/src/com/mashibing/tank/cor/Collider.java @@ -0,0 +1,7 @@ +package com.mashibing.tank.cor; + +import com.mashibing.tank.GameObject; + +public interface Collider { + boolean collide(GameObject o1, GameObject o2); +} diff --git a/tank/src/com/mashibing/tank/cor/ColliderChain.java b/tank/src/com/mashibing/tank/cor/ColliderChain.java new file mode 100644 index 0000000..8b21c36 --- /dev/null +++ b/tank/src/com/mashibing/tank/cor/ColliderChain.java @@ -0,0 +1,35 @@ +package com.mashibing.tank.cor; + +import java.util.LinkedList; +import java.util.List; + +import com.mashibing.tank.GameObject; + +public class ColliderChain implements Collider { + private List colliders = new LinkedList<>(); + + public ColliderChain() { + add(new BulletTankCollider()); + add(new TankTankCollider()); + add(new BulletWallCollider()); + add(new TankWallCollider()); + } + + + public void add(Collider c) { + colliders.add(c); + } + + + public boolean collide(GameObject o1, GameObject o2) { + for(int i=0; inew Audio("audio/tank_fire.wav").play()).start(); + } + +} diff --git a/tank/src/com/mashibing/tank/strategy/FireStrategy.java b/tank/src/com/mashibing/tank/strategy/FireStrategy.java new file mode 100644 index 0000000..7676c4c --- /dev/null +++ b/tank/src/com/mashibing/tank/strategy/FireStrategy.java @@ -0,0 +1,9 @@ +package com.mashibing.tank.strategy; + +import java.io.Serializable; + +import com.mashibing.tank.Tank; + +public interface FireStrategy extends Serializable { + void fire(Tank t); +} diff --git a/tank/src/com/mashibing/tank/strategy/FourDirFireStrategy.java b/tank/src/com/mashibing/tank/strategy/FourDirFireStrategy.java new file mode 100644 index 0000000..cd0b9ef --- /dev/null +++ b/tank/src/com/mashibing/tank/strategy/FourDirFireStrategy.java @@ -0,0 +1,24 @@ +package com.mashibing.tank.strategy; + +import com.mashibing.tank.Audio; +import com.mashibing.tank.Bullet; +import com.mashibing.tank.Dir; +import com.mashibing.tank.Group; +import com.mashibing.tank.Tank; + +public class FourDirFireStrategy implements FireStrategy { + + @Override + public void fire(Tank t) { + int bX = t.x + Tank.WIDTH/2 - Bullet.WIDTH/2; + int bY = t.y + Tank.HEIGHT/2 - Bullet.HEIGHT/2; + + Dir[] dirs = Dir.values(); + for(Dir dir : dirs) { + new Bullet(bX, bY, dir, t.group); + } + + if(t.group == Group.GOOD) new Thread(()->new Audio("audio/tank_fire.wav").play()).start(); + } + +} diff --git a/tank/src/config b/tank/src/config index 5b7e8c7..dbe8a83 100644 --- a/tank/src/config +++ b/tank/src/config @@ -1,2 +1,11 @@ #tanks count at initialization -initTankCount=10 \ No newline at end of file +initTankCount=10 +tankSpeed=5 +bulletSpeed=10 +gameWidth=1080 +gameHeight=720 +#fireStrategy +goodFS=com.mashibing.tank.strategy.FourDirFireStrategy +badFS=com.mashibing.tank.strategy.DefaultFireStrategy +#colliders +colliders=com.mashibing.tank.cor.BulletTankCollider,com.mashibing.tank.cor.TankTankCollider \ No newline at end of file