diff --git a/src/main/java/com/example/tankbattle/Bullet.java b/src/main/java/com/example/tankbattle/Bullet.java index 5183ef9..e7a4f65 100644 --- a/src/main/java/com/example/tankbattle/Bullet.java +++ b/src/main/java/com/example/tankbattle/Bullet.java @@ -3,14 +3,13 @@ package com.example.tankbattle; 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(); - private int x, y; private Dir dir; private boolean living = true; @@ -29,7 +28,7 @@ public class Bullet { rect.width = WIDTH; rect.height = HEIGHT; - gm.bullets.add(this); + gm.add(this); } public Group getGroup() { @@ -40,9 +39,10 @@ public class Bullet { this.group = group; } + @Override public void paint(Graphics g) { if (!living) { - gm.bullets.remove(this); + gm.remove(this); } switch (dir) { case LEFT: @@ -89,15 +89,17 @@ public class Bullet { if (x < 0 || y < 0 || x > TankFrame.GAME_WIDTH || y > TankFrame.GAME_HEIGHT) living = false; } - public void collideWith(Tank tank){ - if (this.group == tank.getGroup()) return; + public boolean collideWith(Tank tank){ + if (this.group == tank.getGroup()) return false; 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; - gm.explodes.add(new Explode(eX, eY, gm)); + gm.add(new Explode(eX, eY, gm)); + return true; } + return false; } private void die() { diff --git a/src/main/java/com/example/tankbattle/Explode.java b/src/main/java/com/example/tankbattle/Explode.java index 6f54ef8..096d5ca 100644 --- a/src/main/java/com/example/tankbattle/Explode.java +++ b/src/main/java/com/example/tankbattle/Explode.java @@ -2,12 +2,10 @@ package com.example.tankbattle; import java.awt.Graphics; -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; - GameModel gm = null; private int step = 0; @@ -20,12 +18,13 @@ public class Explode { new Thread(() -> new Audio("audio/explode.wav").play()).start(); } + @Override public void paint(Graphics g) { g.drawImage(ResourceMgr.explodes[step++], x, y, null); if (step >= ResourceMgr.explodes.length) - gm.explodes.remove(this); + gm.remove(this); } } diff --git a/src/main/java/com/example/tankbattle/GameModel.java b/src/main/java/com/example/tankbattle/GameModel.java index 201e2f1..7c7696f 100644 --- a/src/main/java/com/example/tankbattle/GameModel.java +++ b/src/main/java/com/example/tankbattle/GameModel.java @@ -1,5 +1,10 @@ package com.example.tankbattle; +import com.example.tankbattle.cor.BulletTankCollider; +import com.example.tankbattle.cor.Collider; +import com.example.tankbattle.cor.ColliderChain; +import com.example.tankbattle.cor.TankTankCollider; + import java.awt.Color; import java.awt.Graphics; import java.util.ArrayList; @@ -11,16 +16,27 @@ public class GameModel { List bullets = new ArrayList<>(); List tanks = new ArrayList<>(); List explodes = new ArrayList<>(); + ColliderChain chain = new ColliderChain(); + + List objects = new ArrayList<>(); public GameModel() { int initTankCount = Integer.valueOf(PropertyMgr.get("initTankCount")); // 初始化敌方坦克 for (int i = 0; i < initTankCount; i++) { - tanks.add(new Tank(50 + i * 80, 200, Dir.DOWN, Group.BAD, this)); + add(new Tank(50 + i * 80, 200, Dir.DOWN, Group.BAD, this)); } } + 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); @@ -30,22 +46,25 @@ public class GameModel { 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 < objects.size(); i++) { + objects.get(i).paint(g); } - for (int i = 0; i < explodes.size(); i++) { - explodes.get(i).paint(g); + // 互相碰撞逻辑 + for (int i = 0; i < objects.size(); i++) { + for (int j = i + 1; j < objects.size(); j++) { + GameObject o1 = objects.get(i); + GameObject o2 = objects.get(j); +// collider.collide(o1, o2); +// collider2.collide(o1, o2); + 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)); - } +// for (int i = 0; i < bullets.size(); i++) { +// for (int j = 0; j < tanks.size(); j++) +// bullets.get(i).collideWith(tanks.get(j)); +// } // for (Iterator it = bullets.iterator(); it.hasNext()) { // Bullet b = it.next(); diff --git a/src/main/java/com/example/tankbattle/GameObject.java b/src/main/java/com/example/tankbattle/GameObject.java new file mode 100644 index 0000000..10d51b5 --- /dev/null +++ b/src/main/java/com/example/tankbattle/GameObject.java @@ -0,0 +1,10 @@ +package com.example.tankbattle; + +import java.awt.Graphics; + +public abstract class GameObject { + public int x; + public int y; + + public abstract void paint(Graphics g); +} diff --git a/src/main/java/com/example/tankbattle/Tank.java b/src/main/java/com/example/tankbattle/Tank.java index f513842..480c148 100644 --- a/src/main/java/com/example/tankbattle/Tank.java +++ b/src/main/java/com/example/tankbattle/Tank.java @@ -1,9 +1,12 @@ package com.example.tankbattle; +import com.example.tankbattle.strategy.DefaultFireStrategy; +import com.example.tankbattle.strategy.FireStrategy; + import java.awt.*; import java.util.Random; -public class Tank { +public class Tank extends GameObject{ private static final int SPEED = 2; public static int WIDTH = ResourceMgr.goodTankU.getWidth(); @@ -13,18 +16,16 @@ public class Tank { private Random random = new Random(); - int x,y; - - Dir dir = Dir.DOWN; + public Dir dir = Dir.DOWN; private boolean moving = true; private boolean living = true; - Group group = Group.BAD; + public Group group = Group.BAD; FireStrategy fs; - GameModel gm; + public GameModel gm; public Tank(int x, int y, Dir dir, Group group, GameModel gm) { super(); @@ -53,6 +54,10 @@ public class Tank { } } + public Rectangle getRect() { + return rect; + } + public void fire(){ fs.fire(this); } @@ -123,8 +128,10 @@ public class Tank { this.dir = Dir.values()[random.nextInt(4)]; } + + @Override public void paint(Graphics g) { - if (!living) gm.tanks.remove(this); + if (!living) gm.remove(this); switch (dir) { case LEFT: g.drawImage(this.group == Group.GOOD ? ResourceMgr.goodTankL : ResourceMgr.badTankL, x, y, null); @@ -163,4 +170,9 @@ public class Tank { public void die() { this.living = false; } + + public void stop() { + this.moving = false; + } + } diff --git a/src/main/java/com/example/tankbattle/cor/BulletTankCollider.java b/src/main/java/com/example/tankbattle/cor/BulletTankCollider.java new file mode 100644 index 0000000..7cf008e --- /dev/null +++ b/src/main/java/com/example/tankbattle/cor/BulletTankCollider.java @@ -0,0 +1,26 @@ +package com.example.tankbattle.cor; + +import com.example.tankbattle.Bullet; +import com.example.tankbattle.GameObject; +import com.example.tankbattle.Tank; + +public class BulletTankCollider implements Collider { + + + @Override + public boolean collide(GameObject o1, GameObject o2) { + if (o1 instanceof Bullet && o2 instanceof Tank) { + Bullet bullet = (Bullet) o1; + Tank t = (Tank) o2; + if (bullet.collideWith(t)){ + return false; + } else { + return true; + } + } else if (o1 instanceof Tank && o2 instanceof Bullet) { + return collide(o2, o1); + } else { + return true; + } + } +} diff --git a/src/main/java/com/example/tankbattle/cor/Collider.java b/src/main/java/com/example/tankbattle/cor/Collider.java new file mode 100644 index 0000000..a78be63 --- /dev/null +++ b/src/main/java/com/example/tankbattle/cor/Collider.java @@ -0,0 +1,7 @@ +package com.example.tankbattle.cor; + +import com.example.tankbattle.GameObject; + +public interface Collider { + boolean collide(GameObject o1, GameObject o2); +} diff --git a/src/main/java/com/example/tankbattle/cor/ColliderChain.java b/src/main/java/com/example/tankbattle/cor/ColliderChain.java new file mode 100644 index 0000000..e513a43 --- /dev/null +++ b/src/main/java/com/example/tankbattle/cor/ColliderChain.java @@ -0,0 +1,30 @@ +package com.example.tankbattle.cor; + +import com.example.tankbattle.GameObject; + +import java.util.LinkedList; +import java.util.List; + +public class ColliderChain implements Collider { + + private List colliders = new LinkedList<>(); + + public ColliderChain() { + add(new BulletTankCollider()); + add(new TankTankCollider()); + } + + public void add(Collider c) { + colliders.add(c); + } + + @Override + public boolean collide(GameObject o1, GameObject o2) { + for (int i = 0; i < colliders.size(); i++) { + if (!colliders.get(i).collide(o1, o2)) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/com/example/tankbattle/cor/TankTankCollider.java b/src/main/java/com/example/tankbattle/cor/TankTankCollider.java new file mode 100644 index 0000000..08ae70f --- /dev/null +++ b/src/main/java/com/example/tankbattle/cor/TankTankCollider.java @@ -0,0 +1,21 @@ +package com.example.tankbattle.cor; + +import com.example.tankbattle.GameObject; +import com.example.tankbattle.Tank; + +public class TankTankCollider implements Collider { + + + @Override + public boolean collide(GameObject o1, GameObject o2) { + if (o1 instanceof Tank && o2 instanceof Tank) { + Tank t1 = (Tank) o1; + Tank t2 = (Tank) o2; + if ( t1.getRect().intersects(t2.getRect())){ + t1.stop(); +// t2.stop(); + } + } + return true; + } +} diff --git a/src/main/resources/Config.properties b/src/main/resources/Config.properties index 8f8ef51..c0dab71 100644 --- a/src/main/resources/Config.properties +++ b/src/main/resources/Config.properties @@ -5,5 +5,7 @@ bulletSpeed=10 gameWidth=1080 gameHeight=720 #fireStrategy -goodFS=com.example.tankbattle.FourDirFireStrategy -badFS=com.example.tankbattle.DefaultFireStrategy \ No newline at end of file +goodFS=com.example.tankbattle.strategy.FourDirFireStrategy +badFS=com.example.tankbattle.strategy.DefaultFireStrategy +#colliders +colliders=com.example.tankbattle.cor.BulletTankCollider,com.example.tankbattle.cor.TankTankCollider \ No newline at end of file