diff --git a/docs/坦克大战笔记.docx b/docs/坦克大战笔记.docx index e0753c6..447d4ab 100644 Binary files a/docs/坦克大战笔记.docx and b/docs/坦克大战笔记.docx differ diff --git a/src/com/demo/tank/course9/Bullet.java b/src/com/demo/tank/course9/Bullet.java index 902efe2..897f441 100644 --- a/src/com/demo/tank/course9/Bullet.java +++ b/src/com/demo/tank/course9/Bullet.java @@ -7,7 +7,6 @@ import com.demo.tank.util.ResourceManager; import java.awt.*; public class Bullet extends GameObject { - private int x, y; private Direction direction; private static final int SPEED = 10; public static final int WIDTH = ResourceManager.bulletD.getWidth(); @@ -29,11 +28,11 @@ public class Bullet extends GameObject { GameModel.getInstance().add(this); } - public void paint(Graphics g){ - if(!live){ + public void paint(Graphics g) { + if (!live) { GameModel.getInstance().remove(this); } - switch (direction){ + switch (direction) { case UP: g.drawImage(ResourceManager.bulletU, x, y, null); break; @@ -51,19 +50,23 @@ public class Bullet extends GameObject { } private void move() { - switch (direction){ - case UP: y -= SPEED; + switch (direction) { + case UP: + y -= SPEED; break; - case DOWN: y += SPEED; + case DOWN: + y += SPEED; break; - case LEFT: x -= SPEED; + case LEFT: + x -= SPEED; break; - case RIGHT: x += SPEED; + case RIGHT: + x += SPEED; break; default: break; } - if(x < 0 || y < 0 || x > TankFrameV9.GAME_WIDTH || y > TankFrameV9.GAME_HEIGHT){ + if (x < 0 || y < 0 || x > TankFrameV9.GAME_WIDTH || y > TankFrameV9.GAME_HEIGHT) { live = false; } rect.x = this.x; @@ -114,4 +117,13 @@ public class Bullet extends GameObject { this.group = group; } + @Override + public int getWidth() { + return WIDTH; + } + + @Override + public int getHeight() { + return HEIGHT; + } } diff --git a/src/com/demo/tank/course9/BulletTankCollider.java b/src/com/demo/tank/course9/BulletTankCollider.java index d943f8f..830199b 100644 --- a/src/com/demo/tank/course9/BulletTankCollider.java +++ b/src/com/demo/tank/course9/BulletTankCollider.java @@ -3,22 +3,22 @@ package com.demo.tank.course9; public class BulletTankCollider implements Collider { @Override public void collide(GameObject g1, GameObject g2) { - if(g1 instanceof Bullet && g2 instanceof Tank){ + if (g1 instanceof Bullet && g2 instanceof Tank) { Bullet b = (Bullet) g1; Tank t = (Tank) g2; //关闭队友伤害 - if(b.getGroup() == t.getGroup()) return; - if(b.rect.intersects(t.rect)){ + if (b.getGroup() == t.getGroup()) return; + 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; + int ex = t.getX() + Tank.WIDTH / 2 - Explode.WIDTH / 2; + int ey = t.getY() + Tank.HEIGHT / 2 - Explode.HEIGHT / 2; GameModel.getInstance().add(new Explode(ex, ey)); } - }else if(g1 instanceof Tank && g2 instanceof Bullet){ + } else if (g1 instanceof Tank && g2 instanceof Bullet) { collide(g2, g1); - }else{ + } else { return; } } diff --git a/src/com/demo/tank/course9/BulletWallCollider.java b/src/com/demo/tank/course9/BulletWallCollider.java index 3071f20..7af4ca5 100644 --- a/src/com/demo/tank/course9/BulletWallCollider.java +++ b/src/com/demo/tank/course9/BulletWallCollider.java @@ -3,15 +3,15 @@ package com.demo.tank.course9; public class BulletWallCollider implements Collider { @Override public void collide(GameObject g1, GameObject g2) { - if(g1 instanceof Bullet && g2 instanceof Wall){ + if (g1 instanceof Bullet && g2 instanceof Wall) { Bullet b = (Bullet) g1; Wall w = (Wall) g2; - if(b.rect.intersects(w.rect)){ + if (b.rect.intersects(w.rect)) { b.die(); } - }else if(g1 instanceof Wall && g2 instanceof Bullet){ + } else if (g1 instanceof Wall && g2 instanceof Bullet) { collide(g2, g1); - }else{ + } else { return; } } diff --git a/src/com/demo/tank/course9/ColliderChain.java b/src/com/demo/tank/course9/ColliderChain.java index 3ed6a94..99d2af2 100644 --- a/src/com/demo/tank/course9/ColliderChain.java +++ b/src/com/demo/tank/course9/ColliderChain.java @@ -6,19 +6,19 @@ import java.util.List; public class ColliderChain { private List colliders = new LinkedList<>(); - public ColliderChain(){ + public ColliderChain() { add(new BulletTankCollider()); add(new TankTankCollider()); add(new BulletWallCollider()); add(new TankWallCollider()); } - public void add(Collider collider){ + public void add(Collider collider) { colliders.add(collider); } public void collide(GameObject g1, GameObject g2) { - for (Collider c : colliders){ + for (Collider c : colliders) { c.collide(g1, g2); } } diff --git a/src/com/demo/tank/course9/DefaultFireStrategy.java b/src/com/demo/tank/course9/DefaultFireStrategy.java index ec2d86d..6e6eb4f 100644 --- a/src/com/demo/tank/course9/DefaultFireStrategy.java +++ b/src/com/demo/tank/course9/DefaultFireStrategy.java @@ -6,9 +6,15 @@ import com.demo.tank.util.Audio; public class DefaultFireStrategy implements FireStrategy { @Override public void fire(Tank tank) { - int bx = tank.getX() + Tank.WIDTH/2 - Bullet.WIDTH/2; - int by = tank.getY() + Tank.HEIGHT/2 - Bullet.HEIGHT/2; - new Bullet(bx, by, tank.getDir(), tank.getGroup()); + int bx = tank.getX() + Tank.WIDTH / 2 - Bullet.WIDTH / 2; + int by = tank.getY() + Tank.HEIGHT / 2 - Bullet.HEIGHT / 2; +// new Bullet(bx, by, tank.getDir(), tank.getGroup()); +// GameModel.getInstance().add(new RectDecorator(new Bullet(bx, by, tank.getDir(), tank.getGroup()))); + GameModel.getInstance().add(new RectDecorator( + new TailDecorator( + new Bullet(bx, by, tank.getDir(), tank.getGroup()) + ) + )); if (tank.getGroup() == Group.GOOD) new Thread(() -> new Audio("audio/tank_fire.wav").play()).start(); } } diff --git a/src/com/demo/tank/course9/Explode.java b/src/com/demo/tank/course9/Explode.java index 3a8c16d..5cbe9c8 100644 --- a/src/com/demo/tank/course9/Explode.java +++ b/src/com/demo/tank/course9/Explode.java @@ -6,7 +6,6 @@ import com.demo.tank.util.ResourceManager; import java.awt.*; public class Explode extends GameObject { - private int x, y; public static final int WIDTH = ResourceManager.explodes[0].getWidth(); public static final int HEIGHT = ResourceManager.explodes[0].getHeight(); @@ -18,9 +17,9 @@ public class Explode extends GameObject { new Thread(() -> new Audio("audio/explode.wav").play()).start(); } - public void paint(Graphics g){ + public void paint(Graphics g) { g.drawImage(ResourceManager.explodes[step++], x, y, null); - if(step >= ResourceManager.explodes.length){ + if (step >= ResourceManager.explodes.length) { //播放完爆炸效果图片, remove GameModel.getInstance().remove(this); } @@ -42,4 +41,11 @@ public class Explode extends GameObject { this.y = y; } + public int getWidth() { + return WIDTH; + } + + public int getHeight() { + return HEIGHT; + } } diff --git a/src/com/demo/tank/course9/FourDirectionFireStrategy.java b/src/com/demo/tank/course9/FourDirectionFireStrategy.java index 0b508d1..567665c 100644 --- a/src/com/demo/tank/course9/FourDirectionFireStrategy.java +++ b/src/com/demo/tank/course9/FourDirectionFireStrategy.java @@ -7,9 +7,9 @@ import com.demo.tank.util.Audio; public class FourDirectionFireStrategy implements FireStrategy { @Override public void fire(Tank tank) { - int bx = tank.getX() + Tank.WIDTH/2 - Bullet.WIDTH/2; - int by = tank.getY() + Tank.HEIGHT/2 - Bullet.HEIGHT/2; - for(Direction direction : Direction.values()){ + int bx = tank.getX() + Tank.WIDTH / 2 - Bullet.WIDTH / 2; + int by = tank.getY() + Tank.HEIGHT / 2 - Bullet.HEIGHT / 2; + for (Direction direction : Direction.values()) { new Bullet(bx, by, direction, tank.getGroup()); } if (tank.getGroup() == Group.GOOD) new Thread(() -> new Audio("audio/tank_fire.wav").play()).start(); diff --git a/src/com/demo/tank/course9/GODecorator.java b/src/com/demo/tank/course9/GODecorator.java new file mode 100644 index 0000000..86dbd86 --- /dev/null +++ b/src/com/demo/tank/course9/GODecorator.java @@ -0,0 +1,13 @@ +package com.demo.tank.course9; + +import java.awt.*; + +public abstract class GODecorator extends GameObject { + GameObject go; + + public GODecorator(GameObject go) { + this.go = go; + } + + public abstract void paint(Graphics g); +} diff --git a/src/com/demo/tank/course9/GameModel.java b/src/com/demo/tank/course9/GameModel.java index 1e05609..9afa2ea 100644 --- a/src/com/demo/tank/course9/GameModel.java +++ b/src/com/demo/tank/course9/GameModel.java @@ -10,25 +10,27 @@ import java.util.List; public class GameModel { private static final GameModel GM = new GameModel(); + static { GM.init(); } private List gameObjects = new ArrayList<>(); -// Collider collider = new BulletTankCollider(); + // Collider collider = new BulletTankCollider(); // Collider collider2 = new TankTankCollider(); ColliderChain chain = new ColliderChain(); Tank tank; - private GameModel(){ + private GameModel() { } - private void init(){ + + private void init() { tank = new Tank(380, 660, Direction.UP, Group.GOOD); int enemyTankNum = PropertyManager.getInt("enemy.tank.number"); - for(int i = 0; i < enemyTankNum; i++){ - add(new Tank(50 + i*80, 200, Direction.DOWN, Group.BAD)); + for (int i = 0; i < enemyTankNum; i++) { + add(new Tank(50 + i * 80, 200, Direction.DOWN, Group.BAD)); } add(new Wall(150, 150, 200, 50)); add(new Wall(550, 150, 200, 50)); @@ -36,31 +38,31 @@ public class GameModel { add(new Wall(550, 300, 50, 200)); } - public static GameModel getInstance(){ + public static GameModel getInstance() { return GM; } - public void add(GameObject go){ + public void add(GameObject go) { gameObjects.add(go); } - public void remove(GameObject go){ + public void remove(GameObject go) { gameObjects.remove(go); } - public void paint(Graphics g){ + public void paint(Graphics g) { tank.paint(g); - for(int i = 0; i< gameObjects.size(); i++){ + for (int i = 0; i < gameObjects.size(); i++) { gameObjects.get(i).paint(g); } //碰撞检测 - for(int i = 0; i< gameObjects.size(); i++){ - for(int j=i+1; j< gameObjects.size(); j++){ - GameObject g1 = gameObjects.get(i); - GameObject g2 = gameObjects.get(j); - chain.collide(g1, g2); + for (int i = 0; i < gameObjects.size(); i++) { + for (int j = i + 1; j < gameObjects.size(); j++) { + GameObject g1 = gameObjects.get(i); + GameObject g2 = gameObjects.get(j); + chain.collide(g1, g2); } } } diff --git a/src/com/demo/tank/course9/GameObject.java b/src/com/demo/tank/course9/GameObject.java index 21dce58..aad2061 100644 --- a/src/com/demo/tank/course9/GameObject.java +++ b/src/com/demo/tank/course9/GameObject.java @@ -4,5 +4,10 @@ import java.awt.*; public abstract class GameObject { int x, y; + public abstract void paint(Graphics g); + + public abstract int getWidth(); + + public abstract int getHeight(); } diff --git a/src/com/demo/tank/course9/MainV9.java b/src/com/demo/tank/course9/MainV9.java index 38064b2..dc8fc4a 100644 --- a/src/com/demo/tank/course9/MainV9.java +++ b/src/com/demo/tank/course9/MainV9.java @@ -8,7 +8,7 @@ public class MainV9 { // new Thread(() -> new Audio("audio/war1.wav").loop()).start(); - while (true){ + while (true) { Thread.sleep(50); tf.repaint(); } diff --git a/src/com/demo/tank/course9/RectDecorator.java b/src/com/demo/tank/course9/RectDecorator.java new file mode 100644 index 0000000..feddb5e --- /dev/null +++ b/src/com/demo/tank/course9/RectDecorator.java @@ -0,0 +1,32 @@ +package com.demo.tank.course9; + +import java.awt.*; + +public class RectDecorator extends GODecorator { + + public RectDecorator(GameObject go) { + super(go); + } + + @Override + public void paint(Graphics g) { + //decorator x,y 也要跟随游戏物体 变化 + this.x = go.x; + this.y = go.y; + go.paint(g); + Color c = g.getColor(); + g.setColor(Color.MAGENTA); + g.drawRect(go.x, go.y, getWidth(), getHeight()); + g.setColor(c); + } + + @Override + public int getWidth() { + return super.go.getWidth(); + } + + @Override + public int getHeight() { + return super.go.getHeight(); + } +} diff --git a/src/com/demo/tank/course9/TailDecorator.java b/src/com/demo/tank/course9/TailDecorator.java new file mode 100644 index 0000000..d71eac3 --- /dev/null +++ b/src/com/demo/tank/course9/TailDecorator.java @@ -0,0 +1,31 @@ +package com.demo.tank.course9; + +import java.awt.*; + +public class TailDecorator extends GODecorator { + + public TailDecorator(GameObject go) { + super(go); + } + + @Override + public void paint(Graphics g) { + go.paint(g); + this.x = go.x; + this.y = go.y; + Color c = g.getColor(); + g.setColor(Color.WHITE); + g.drawLine(go.x, go.y, go.x + getWidth(), go.y + getHeight()); + g.setColor(c); + } + + @Override + public int getWidth() { + return super.go.getWidth(); + } + + @Override + public int getHeight() { + return super.go.getHeight(); + } +} diff --git a/src/com/demo/tank/course9/Tank.java b/src/com/demo/tank/course9/Tank.java index 2e36d22..0ba0019 100644 --- a/src/com/demo/tank/course9/Tank.java +++ b/src/com/demo/tank/course9/Tank.java @@ -8,7 +8,6 @@ import java.awt.*; import java.util.Random; public class Tank extends GameObject { - private int x,y; int oldX, oldY; private Direction dir; private static final int SPEED = 8; @@ -33,7 +32,7 @@ public class Tank extends GameObject { rect.width = Tank.WIDTH; rect.height = Tank.HEIGHT; - if(this.group == Group.GOOD) { + if (this.group == Group.GOOD) { // String className = PropertyManager.getString("good.tank.fire.strategy"); try { fireStrategy = (FireStrategy) Class.forName("com.demo.tank.course9.FourDirectionFireStrategy").newInstance(); @@ -42,24 +41,24 @@ public class Tank extends GameObject { } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { - e.printStackTrace(); + e.printStackTrace(); } - }else if(this.group == Group.BAD) fireStrategy = new DefaultFireStrategy(); + } else if (this.group == Group.BAD) fireStrategy = new DefaultFireStrategy(); } @Override public void paint(Graphics g) { - if(!living) GameModel.getInstance().remove(this); + if (!living) GameModel.getInstance().remove(this); //根据方向绘制坦克 - switch (dir){ + switch (dir) { case UP: g.drawImage(this.group == Group.GOOD ? ResourceManager.tankU : ResourceManager.badTankU, x, y, null); - break; + break; case DOWN: g.drawImage(this.group == Group.GOOD ? ResourceManager.tankD : ResourceManager.badTankD, x, y, null); break; case LEFT: - g.drawImage(this.group == Group.GOOD ? ResourceManager.tankL: ResourceManager.badTankL, x, y, null); + g.drawImage(this.group == Group.GOOD ? ResourceManager.tankL : ResourceManager.badTankL, x, y, null); break; case RIGHT: g.drawImage(this.group == Group.GOOD ? ResourceManager.tankR : ResourceManager.badTankR, x, y, null); @@ -68,28 +67,32 @@ public class Tank extends GameObject { move(); } - public void move(){ + public void move() { oldX = x; oldY = y; //如果没有移动 return - if(!moving) return; - switch (dir){ - case UP: y -= SPEED; + if (!moving) return; + switch (dir) { + case UP: + y -= SPEED; break; - case DOWN: y += SPEED; + case DOWN: + y += SPEED; break; - case LEFT: x -= SPEED; + case LEFT: + x -= SPEED; break; - case RIGHT: x += SPEED; + case RIGHT: + x += SPEED; break; default: break; } - if(this.group == Group.BAD) { - if(random.nextInt(10) == 5){ + if (this.group == Group.BAD) { + if (random.nextInt(10) == 5) { this.fire(); } - if(random.nextInt(100) > 95){ + if (random.nextInt(100) > 95) { this.randomDirection(); } } @@ -101,27 +104,27 @@ public class Tank extends GameObject { rect.y = this.y; } - public void back(){ + public void back() { this.x = oldX; this.y = oldY; } private void boundsCheck() { - if(x < 0) x = 0; - if(x > TankFrameV9.GAME_WIDTH - Tank.WIDTH) x = TankFrameV9.GAME_WIDTH - Tank.WIDTH; - if(y < 30) y = 30; //算上菜单条 - if(y > TankFrameV9.GAME_HEIGHT - Tank.HEIGHT) y = TankFrameV9.GAME_HEIGHT - Tank.HEIGHT; + if (x < 0) x = 0; + if (x > TankFrameV9.GAME_WIDTH - Tank.WIDTH) x = TankFrameV9.GAME_WIDTH - Tank.WIDTH; + if (y < 30) y = 30; //算上菜单条 + if (y > TankFrameV9.GAME_HEIGHT - Tank.HEIGHT) y = TankFrameV9.GAME_HEIGHT - Tank.HEIGHT; } private void randomDirection() { - this.dir = Direction.values()[random.nextInt(4)]; + this.dir = Direction.values()[random.nextInt(4)]; } public void fire() { - fireStrategy.fire(this); + fireStrategy.fire(this); } - public void die(){ + public void die() { this.living = false; } @@ -181,4 +184,12 @@ public class Tank extends GameObject { this.rect = rect; } + public int getWidth() { + return WIDTH; + } + + public int getHeight() { + return HEIGHT; + } + } diff --git a/src/com/demo/tank/course9/TankFrameV9.java b/src/com/demo/tank/course9/TankFrameV9.java index 29ec300..29d4a9f 100644 --- a/src/com/demo/tank/course9/TankFrameV9.java +++ b/src/com/demo/tank/course9/TankFrameV9.java @@ -14,9 +14,9 @@ public class TankFrameV9 extends Frame { public static final int GAME_HEIGHT = 800; Image image = null; - public TankFrameV9(){ + public TankFrameV9() { setVisible(true); - setBounds(400, 100 , GAME_WIDTH, GAME_HEIGHT); + setBounds(400, 100, GAME_WIDTH, GAME_HEIGHT); setResizable(false); setTitle("tank war"); this.addKeyListener(new MyKeyListener()); @@ -30,24 +30,24 @@ public class TankFrameV9 extends Frame { @Override public void update(Graphics g) { - if(image == null){ + if (image == null) { image = this.createImage(GAME_WIDTH, GAME_HEIGHT); } - Graphics imgGraphic = image.getGraphics(); + Graphics imgGraphic = image.getGraphics(); Color color = g.getColor(); imgGraphic.setColor(Color.BLACK); - imgGraphic.fillRect(0,0, GAME_WIDTH, GAME_HEIGHT); + imgGraphic.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT); imgGraphic.setColor(color); paint(imgGraphic); g.drawImage(image, 0, 0, null); } @Override - public void paint(Graphics g){ + public void paint(Graphics g) { gm.paint(g); } - class MyKeyListener extends KeyAdapter{ + class MyKeyListener extends KeyAdapter { boolean bL = false; boolean bR = false; boolean bU = false; @@ -55,7 +55,7 @@ public class TankFrameV9 extends Frame { @Override public void keyPressed(KeyEvent e) { - switch (e.getKeyCode()){ + switch (e.getKeyCode()) { case KeyEvent.VK_A: bL = true; break; @@ -63,8 +63,8 @@ public class TankFrameV9 extends Frame { bR = true; break; case KeyEvent.VK_W: - bU = true; - break; + bU = true; + break; case KeyEvent.VK_S: bD = true; break; @@ -76,7 +76,7 @@ public class TankFrameV9 extends Frame { @Override public void keyReleased(KeyEvent e) { - switch (e.getKeyCode()){ + switch (e.getKeyCode()) { case KeyEvent.VK_A: bL = false; break; @@ -98,15 +98,15 @@ public class TankFrameV9 extends Frame { setTankDirection(); } - public void setTankDirection(){ - if(!bL && !bR && !bU && !bD){ + public void setTankDirection() { + if (!bL && !bR && !bU && !bD) { gm.tank.setMoving(false); - }else{ + } else { gm.tank.setMoving(true); - if(bL) gm.tank.setDir(Direction.LEFT); - if(bR) gm.tank.setDir(Direction.RIGHT); - if(bU) gm.tank.setDir(Direction.UP); - if(bD) gm.tank.setDir(Direction.DOWN); + if (bL) gm.tank.setDir(Direction.LEFT); + if (bR) gm.tank.setDir(Direction.RIGHT); + if (bU) gm.tank.setDir(Direction.UP); + if (bD) gm.tank.setDir(Direction.DOWN); } } } diff --git a/src/com/demo/tank/course9/TankTankCollider.java b/src/com/demo/tank/course9/TankTankCollider.java index 310016a..b2101b0 100644 --- a/src/com/demo/tank/course9/TankTankCollider.java +++ b/src/com/demo/tank/course9/TankTankCollider.java @@ -4,17 +4,18 @@ import java.util.Random; public class TankTankCollider implements Collider { Random random = new Random(); + @Override public void collide(GameObject g1, GameObject g2) { - if(g1 instanceof Tank && g2 instanceof Tank){ + if (g1 instanceof Tank && g2 instanceof Tank) { Tank t1 = (Tank) g1; Tank t2 = (Tank) g2; - if(t1.rect.intersects(t2.rect)){ + if (t1.rect.intersects(t2.rect)) { // simple deal t1.back(); t2.back(); } - }else{ + } else { return; } } diff --git a/src/com/demo/tank/course9/TankWallCollider.java b/src/com/demo/tank/course9/TankWallCollider.java index 773713d..f685938 100644 --- a/src/com/demo/tank/course9/TankWallCollider.java +++ b/src/com/demo/tank/course9/TankWallCollider.java @@ -1,17 +1,17 @@ package com.demo.tank.course9; -public class TankWallCollider implements Collider{ +public class TankWallCollider implements Collider { @Override public void collide(GameObject g1, GameObject g2) { - if(g1 instanceof Tank && g2 instanceof Wall){ + if (g1 instanceof Tank && g2 instanceof Wall) { Tank t = (Tank) g1; Wall w = (Wall) g2; - if(t.rect.intersects(w.rect)){ + if (t.rect.intersects(w.rect)) { t.back(); } - }else if(g1 instanceof Wall && g2 instanceof Bullet){ + } else if (g1 instanceof Wall && g2 instanceof Bullet) { collide(g2, g1); - }else{ + } else { return; } } diff --git a/src/com/demo/tank/course9/Wall.java b/src/com/demo/tank/course9/Wall.java index 60910db..f94fb0d 100644 --- a/src/com/demo/tank/course9/Wall.java +++ b/src/com/demo/tank/course9/Wall.java @@ -2,7 +2,7 @@ package com.demo.tank.course9; import java.awt.*; -public class Wall extends GameObject{ +public class Wall extends GameObject { int width, height; Rectangle rect; @@ -21,4 +21,12 @@ public class Wall extends GameObject{ g.fillRect(x, y, width, height); g.setColor(c); } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } }