diff --git a/src/main/java/com/example/tankbattle/Bullet.java b/src/main/java/com/example/tankbattle/Bullet.java index 71065c2..5183ef9 100644 --- a/src/main/java/com/example/tankbattle/Bullet.java +++ b/src/main/java/com/example/tankbattle/Bullet.java @@ -8,26 +8,28 @@ public class Bullet { public static int WIDTH = ResourceMgr.bulletD.getWidth(); public static int HEIGHT = ResourceMgr.bulletD.getHeight(); - private Rectangle rect = new Rectangle(); + Rectangle rect = new Rectangle(); private int x, y; private Dir dir; private boolean living = true; - TankFrame tf = null; + GameModel gm = null; private 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, GameModel gm) { this.x = x; this.y = y; this.dir = dir; this.group = group; - this.tf = tf; + this.gm = gm; rect.x = this.x; rect.y = this.y; rect.width = WIDTH; rect.height = HEIGHT; + + gm.bullets.add(this); } public Group getGroup() { @@ -40,7 +42,7 @@ public class Bullet { public void paint(Graphics g) { if (!living) { - tf.bullets.remove(this); + gm.bullets.remove(this); } switch (dir) { case LEFT: @@ -89,12 +91,12 @@ public class Bullet { public void collideWith(Tank tank){ if (this.group == tank.getGroup()) return; - if (this.rect.intersects(tank.rect)) { + 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)); + gm.explodes.add(new Explode(eX, eY, gm)); } } diff --git a/src/main/java/com/example/tankbattle/DefaultFireStrategy.java b/src/main/java/com/example/tankbattle/DefaultFireStrategy.java new file mode 100644 index 0000000..9525c23 --- /dev/null +++ b/src/main/java/com/example/tankbattle/DefaultFireStrategy.java @@ -0,0 +1,13 @@ +package com.example.tankbattle; + +public class DefaultFireStrategy 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; + new Bullet(bX, bY, t.dir, t.group, t.gm); + + if(t.group == Group.GOOD) new Thread(()->new Audio("audio/tank_fire.wav").play()).start(); + } +} diff --git a/src/main/java/com/example/tankbattle/Explode.java b/src/main/java/com/example/tankbattle/Explode.java index ce0c8cc..6f54ef8 100644 --- a/src/main/java/com/example/tankbattle/Explode.java +++ b/src/main/java/com/example/tankbattle/Explode.java @@ -1,6 +1,6 @@ package com.example.tankbattle; -import java.awt.*; +import java.awt.Graphics; public class Explode { public static int WIDTH = ResourceMgr.explodes[0].getWidth(); @@ -8,14 +8,16 @@ public class Explode { private int x, y; - TankFrame tf = null; + GameModel gm = null; private int step = 0; - public Explode(int x, int y, TankFrame tf) { + public Explode(int x, int y, GameModel gm) { this.x = x; this.y = y; - this.tf = tf; + this.gm = gm; + + new Thread(() -> new Audio("audio/explode.wav").play()).start(); } public void paint(Graphics g) { @@ -23,7 +25,7 @@ public class Explode { g.drawImage(ResourceMgr.explodes[step++], x, y, null); if (step >= ResourceMgr.explodes.length) - tf.explodes.remove(this); + gm.explodes.remove(this); } } diff --git a/src/main/java/com/example/tankbattle/FireStrategy.java b/src/main/java/com/example/tankbattle/FireStrategy.java new file mode 100644 index 0000000..ed4b7b6 --- /dev/null +++ b/src/main/java/com/example/tankbattle/FireStrategy.java @@ -0,0 +1,5 @@ +package com.example.tankbattle; + +public interface FireStrategy { + void fire(Tank tank); +} diff --git a/src/main/java/com/example/tankbattle/FourDirFireStrategy.java b/src/main/java/com/example/tankbattle/FourDirFireStrategy.java new file mode 100644 index 0000000..c7d8d5b --- /dev/null +++ b/src/main/java/com/example/tankbattle/FourDirFireStrategy.java @@ -0,0 +1,15 @@ +package com.example.tankbattle; + +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, t.gm); + } + if(t.group == Group.GOOD) new Thread(()->new Audio("audio/tank_fire.wav").play()).start(); + } +} diff --git a/src/main/java/com/example/tankbattle/GameModel.java b/src/main/java/com/example/tankbattle/GameModel.java new file mode 100644 index 0000000..201e2f1 --- /dev/null +++ b/src/main/java/com/example/tankbattle/GameModel.java @@ -0,0 +1,59 @@ +package com.example.tankbattle; + +import java.awt.Color; +import java.awt.Graphics; +import java.util.ArrayList; +import java.util.List; + +public class GameModel { + Tank myTank = new Tank(200, 400, Dir.DOWN, Group.GOOD, this); + + List bullets = new ArrayList<>(); + List tanks = new ArrayList<>(); + List explodes = 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)); + } + } + + 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); + } + + 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(); +// if (!b.live) it.remove(); +// } + } + + public Tank getMainTank() { + return myTank; + } +} diff --git a/src/main/java/com/example/tankbattle/Main.java b/src/main/java/com/example/tankbattle/Main.java index 72ac5d9..b222496 100644 --- a/src/main/java/com/example/tankbattle/Main.java +++ b/src/main/java/com/example/tankbattle/Main.java @@ -4,15 +4,10 @@ public class Main { public static void main(String[] args) throws InterruptedException { TankFrame tf = new TankFrame(); - int initTankCount = Integer.valueOf(PropertyMgr.get("initTankCount")); - - // 初始化敌方坦克 - for (int i = 0; i < initTankCount; i++) { - tf.tanks.add(new Tank(50 + i * 80, 200, Dir.DOWN, Group.BAD, tf)); - } + new Thread(()->new Audio("audio/war1.wav").loop()).start(); while (true) { - Thread.sleep(50); + Thread.sleep(25); tf.repaint(); } } diff --git a/src/main/java/com/example/tankbattle/ResourceMgr.java b/src/main/java/com/example/tankbattle/ResourceMgr.java index 48d911f..233c1a0 100644 --- a/src/main/java/com/example/tankbattle/ResourceMgr.java +++ b/src/main/java/com/example/tankbattle/ResourceMgr.java @@ -5,22 +5,22 @@ import java.io.IOException; import javax.imageio.ImageIO; public class ResourceMgr { - public static BufferedImage GoodTankL, GoodTankU, GoodTankR, GoodTankD; - public static BufferedImage BadTankL, BadTankU, BadTankR, BadTankD; + public static BufferedImage goodTankL, goodTankU, goodTankR, goodTankD; + public static BufferedImage badTankL, badTankU, badTankR, badTankD; public static BufferedImage bulletL, bulletU,bulletR, bulletD; public static BufferedImage[] explodes = new BufferedImage[16]; static { try { - GoodTankU = ImageIO.read(ResourceMgr.class.getClassLoader().getResourceAsStream("images/GoodTank1.png")); - GoodTankL = ImageUtil.rotateImage(GoodTankU, -90); - GoodTankR = ImageUtil.rotateImage(GoodTankU, 90); - GoodTankD = ImageUtil.rotateImage(GoodTankU, 180); + goodTankU = ImageIO.read(ResourceMgr.class.getClassLoader().getResourceAsStream("images/GoodTank1.png")); + goodTankL = ImageUtil.rotateImage(goodTankU, -90); + goodTankR = ImageUtil.rotateImage(goodTankU, 90); + goodTankD = ImageUtil.rotateImage(goodTankU, 180); - BadTankU = ImageIO.read(ResourceMgr.class.getClassLoader().getResourceAsStream("images/BadTank1.png")); - BadTankL = ImageUtil.rotateImage(BadTankU, -90); - BadTankR = ImageUtil.rotateImage(BadTankU, 90); - BadTankD = ImageUtil.rotateImage(BadTankU, 180); + badTankU = ImageIO.read(ResourceMgr.class.getClassLoader().getResourceAsStream("images/BadTank1.png")); + badTankL = ImageUtil.rotateImage(badTankU, -90); + badTankR = ImageUtil.rotateImage(badTankU, 90); + badTankD = ImageUtil.rotateImage(badTankU, 180); bulletU = ImageIO.read(ResourceMgr.class.getClassLoader().getResourceAsStream("images/bulletU.png")); bulletL = ImageUtil.rotateImage(bulletU, -90); diff --git a/src/main/java/com/example/tankbattle/Tank.java b/src/main/java/com/example/tankbattle/Tank.java index 6d83e50..f513842 100644 --- a/src/main/java/com/example/tankbattle/Tank.java +++ b/src/main/java/com/example/tankbattle/Tank.java @@ -4,45 +4,57 @@ import java.awt.*; import java.util.Random; public class Tank { - private static final int SPEED = 1; + private static final int SPEED = 2; - public static int WIDTH = ResourceMgr.GoodTankD.getWidth(); - public static int HEIGHT = ResourceMgr.GoodTankD.getHeight(); + 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; + int x,y; - private Dir dir = Dir.DOWN; + Dir dir = Dir.DOWN; private boolean moving = true; - private TankFrame tf = null; - private boolean living = true; - private Group group = Group.BAD; + Group group = Group.BAD; + + FireStrategy fs; + GameModel gm; - public Tank(int x, int y, Dir dir, Group group, TankFrame tf) { + public Tank(int x, int y, Dir dir, Group group, GameModel gm) { super(); this.x = x; this.y = y; this.dir = dir; this.group = group; - this.tf = tf; + this.gm = gm; rect.x = this.x; rect.y = this.y; rect.width = WIDTH; rect.height = HEIGHT; + + if(group == Group.GOOD) { + String goodFSName = PropertyMgr.get("goodFS"); + + try { + fs = (FireStrategy)Class.forName(goodFSName).getDeclaredConstructor().newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + + } else { + fs = new DefaultFireStrategy(); + } } 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)); + fs.fire(this); } public Dir getDir() { @@ -88,31 +100,23 @@ public class Tank { break; } - rect.x = this.x; - rect.y = this.y; - if (this.group == Group.BAD && random.nextInt(100) > 95) this.fire(); + 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(); + rect.x = this.x; + rect.y = this.y; } private void boundsCheck() { - if (this.x < 0) { - this.x = 2; - } - if (this.y < 28) { - this.y = 28; - } + if (this.x < 2) x = 2; + if (this.y < 28) y = 28; - if (this.x > TankFrame.GAME_WIDTH - Tank.WIDTH) { - this.x = TankFrame.GAME_WIDTH - Tank.WIDTH; - } - if (this.y > TankFrame.GAME_HEIGHT - Tank.HEIGHT) { - this.y = TankFrame.GAME_HEIGHT - Tank.HEIGHT; - } + 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() { @@ -120,19 +124,19 @@ public class Tank { } public void paint(Graphics g) { - if (!living) tf.tanks.remove(this); + if (!living) gm.tanks.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; default: break; diff --git a/src/main/java/com/example/tankbattle/TankFrame.java b/src/main/java/com/example/tankbattle/TankFrame.java index abbc4ab..9d19f29 100644 --- a/src/main/java/com/example/tankbattle/TankFrame.java +++ b/src/main/java/com/example/tankbattle/TankFrame.java @@ -8,17 +8,10 @@ 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; 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 = new GameModel(); static final int GAME_WIDTH = Integer.valueOf(PropertyMgr.get("gameWidth")); static final int GAME_HEIGHT = Integer.valueOf(PropertyMgr.get("gameHeight")); @@ -54,35 +47,7 @@ public class TankFrame extends Frame { @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); - } - - 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(); -// if (!b.live) it.remove(); -// } + gm.paint(g); } @@ -133,7 +98,7 @@ public class TankFrame extends Frame { bD = false; break; case KeyEvent.VK_CONTROL: - myTank.fire(); + gm.getMainTank().fire(); break; default: break; @@ -143,7 +108,7 @@ public class TankFrame extends Frame { } private void setMainTankDir() { - + Tank myTank = gm.getMainTank(); if (!bL && !bU && !bR && !bD) { myTank.setMoving(false); } else { diff --git a/src/main/resources/Config.properties b/src/main/resources/Config.properties index e4efb82..8f8ef51 100644 --- a/src/main/resources/Config.properties +++ b/src/main/resources/Config.properties @@ -3,4 +3,7 @@ initTankCount=10 tankSpeed=5 bulletSpeed=10 gameWidth=1080 -gameHeight=720 \ No newline at end of file +gameHeight=720 +#fireStrategy +goodFS=com.example.tankbattle.FourDirFireStrategy +badFS=com.example.tankbattle.DefaultFireStrategy \ No newline at end of file