diff --git a/docs/坦克大战笔记.docx b/docs/坦克大战笔记.docx index 967025f..e73a902 100644 Binary files a/docs/坦克大战笔记.docx and b/docs/坦克大战笔记.docx differ diff --git a/src/com/demo/tank/course7/Bullet.java b/src/com/demo/tank/course7/Bullet.java index 81f27ef..6065c88 100644 --- a/src/com/demo/tank/course7/Bullet.java +++ b/src/com/demo/tank/course7/Bullet.java @@ -1,6 +1,7 @@ package com.demo.tank.course7; import com.demo.tank.course7.abstractFactory.BaseBullet; +import com.demo.tank.course7.abstractFactory.BaseTank; import com.demo.tank.enums.Direction; import com.demo.tank.enums.Group; import com.demo.tank.util.ResourceManager; @@ -74,8 +75,9 @@ public class Bullet extends BaseBullet { rect.y = this.y; } + @Override //检测是否跟坦克碰撞 - public void collideWith(Tank tank){ + public void collideWith(BaseTank tank){ //关闭队友伤害 if(this.group == tank.getGroup()) return; if(rect.intersects(tank.rect)){ diff --git a/src/com/demo/tank/course7/DefaultFireStrategy.java b/src/com/demo/tank/course7/DefaultFireStrategy.java index ac664d4..a0eccdc 100644 --- a/src/com/demo/tank/course7/DefaultFireStrategy.java +++ b/src/com/demo/tank/course7/DefaultFireStrategy.java @@ -1,14 +1,11 @@ package com.demo.tank.course7; -import com.demo.tank.enums.Group; -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(),tank.getTankFrame()); - if (tank.getGroup() == Group.GOOD) new Thread(() -> new Audio("audio/tank_fire.wav").play()).start(); +// if (tank.getGroup() == Group.GOOD) new Thread(() -> new Audio("audio/tank_fire.wav").play()).start(); } } diff --git a/src/com/demo/tank/course7/Explode.java b/src/com/demo/tank/course7/Explode.java index fd54348..3e46c54 100644 --- a/src/com/demo/tank/course7/Explode.java +++ b/src/com/demo/tank/course7/Explode.java @@ -1,7 +1,6 @@ package com.demo.tank.course7; import com.demo.tank.course7.abstractFactory.BaseExplode; -import com.demo.tank.util.Audio; import com.demo.tank.util.ResourceManager; import java.awt.*; @@ -18,7 +17,7 @@ public class Explode extends BaseExplode { this.x = x; this.y = y; this.tf = tf; - new Thread(() -> new Audio("audio/explode.wav").play()).start(); +// new Thread(() -> new Audio("audio/explode.wav").play()).start(); } @Override diff --git a/src/com/demo/tank/course7/FourDirectionFireStrategy.java b/src/com/demo/tank/course7/FourDirectionFireStrategy.java index 82f3433..bb63d3b 100644 --- a/src/com/demo/tank/course7/FourDirectionFireStrategy.java +++ b/src/com/demo/tank/course7/FourDirectionFireStrategy.java @@ -1,8 +1,6 @@ package com.demo.tank.course7; import com.demo.tank.enums.Direction; -import com.demo.tank.enums.Group; -import com.demo.tank.util.Audio; public class FourDirectionFireStrategy implements FireStrategy { @Override @@ -10,8 +8,9 @@ public class FourDirectionFireStrategy implements FireStrategy { 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(),tank.getTankFrame()); + tank.tankFrame.gameFactory.createBullet(bx, by, direction, tank.getGroup(),tank.getTankFrame()); +// new Bullet(bx, by, direction, tank.getGroup(),tank.getTankFrame()); } - if (tank.getGroup() == Group.GOOD) new Thread(() -> new Audio("audio/tank_fire.wav").play()).start(); +// if (tank.getGroup() == Group.GOOD) new Thread(() -> new Audio("audio/tank_fire.wav").play()).start(); } } diff --git a/src/com/demo/tank/course7/MainV7.java b/src/com/demo/tank/course7/MainV7.java index fe18beb..055bea8 100644 --- a/src/com/demo/tank/course7/MainV7.java +++ b/src/com/demo/tank/course7/MainV7.java @@ -11,7 +11,7 @@ public class MainV7 { TankFrameV7 tf = new TankFrameV7(); int enemyTankNum = PropertyManager.getInt("enemy.tank.number"); for(int i = 0; i < enemyTankNum; i++){ - tf.enemyTanks.add(new Tank(50 + i*80, 200, Direction.DOWN, Group.BAD, tf)); + tf.enemyTanks.add(tf.gameFactory.createTank(50 + i*80, 200, Direction.DOWN, Group.BAD, tf)); } // new Thread(() -> new Audio("audio/war1.wav").loop()).start(); diff --git a/src/com/demo/tank/course7/Tank.java b/src/com/demo/tank/course7/Tank.java index 8430ee2..3d70f1a 100644 --- a/src/com/demo/tank/course7/Tank.java +++ b/src/com/demo/tank/course7/Tank.java @@ -19,7 +19,7 @@ public class Tank extends BaseTank { public static final int WIDTH = ResourceManager.tankD.getWidth(); public static final int HEIGHT = ResourceManager.tankD.getHeight(); private Random random = new Random(); - Rectangle rect = new Rectangle(); + public Rectangle rect = new Rectangle(); FireStrategy fireStrategy; @@ -39,7 +39,6 @@ public class Tank extends BaseTank { // String className = PropertyManager.getString("good.tank.fire.strategy"); try { fireStrategy = (FireStrategy) Class.forName("com.demo.tank.course7.FourDirectionFireStrategy").newInstance(); - System.out.println(fireStrategy); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { @@ -114,7 +113,16 @@ public class Tank extends BaseTank { } public void fire() { - fireStrategy.fire(this); +// fireStrategy.fire(this); + int bx = x + Tank.WIDTH/2 - Bullet.WIDTH/2; + int by = y + Tank.HEIGHT/2 - Bullet.HEIGHT/2; + if(this.group == Group.BAD){ + this.tankFrame.gameFactory.createBullet(bx, by, this.dir, this.group,this.tankFrame); + }else{ + for(Direction direction : Direction.values()){ + this.tankFrame.gameFactory.createBullet(bx, by, direction, this.group,this.tankFrame); + } + } } public void die(){ diff --git a/src/com/demo/tank/course7/TankFrameV7.java b/src/com/demo/tank/course7/TankFrameV7.java index ddcebe3..3a8d92f 100644 --- a/src/com/demo/tank/course7/TankFrameV7.java +++ b/src/com/demo/tank/course7/TankFrameV7.java @@ -1,7 +1,9 @@ package com.demo.tank.course7; +import com.demo.tank.course7.abstractFactory.BaseBullet; import com.demo.tank.course7.abstractFactory.BaseExplode; -import com.demo.tank.course7.abstractFactory.DefaultFactory; +import com.demo.tank.course7.abstractFactory.BaseTank; +import com.demo.tank.course7.abstractFactory.CircleFactory; import com.demo.tank.course7.abstractFactory.GameFactory; import com.demo.tank.enums.Direction; import com.demo.tank.enums.Group; @@ -21,12 +23,13 @@ public class TankFrameV7 extends Frame { Tank tank = new Tank(380, 660, Direction.UP, Group.GOOD,this); // Bullet bullet = new Bullet(520, 440, Direction.UP); - List bullets = new ArrayList(); - List enemyTanks = new ArrayList<>(); + public List bullets = new ArrayList(); + public List enemyTanks = new ArrayList<>(); - List explodes = new ArrayList<>(); + public List explodes = new ArrayList<>(); - GameFactory gameFactory = new DefaultFactory(); +// GameFactory gameFactory = new DefaultFactory(); + public GameFactory gameFactory = new CircleFactory(); public TankFrameV7(){ setVisible(true); diff --git a/src/com/demo/tank/course7/abstractFactory/BaseBullet.java b/src/com/demo/tank/course7/abstractFactory/BaseBullet.java new file mode 100644 index 0000000..3eba1e8 --- /dev/null +++ b/src/com/demo/tank/course7/abstractFactory/BaseBullet.java @@ -0,0 +1,8 @@ +package com.demo.tank.course7.abstractFactory; + +import java.awt.*; + +public abstract class BaseBullet { + public abstract void paint(Graphics g); + public abstract void collideWith(BaseTank tank); +} diff --git a/src/com/demo/tank/course7/abstractFactory/BaseExplode.java b/src/com/demo/tank/course7/abstractFactory/BaseExplode.java new file mode 100644 index 0000000..bace5cf --- /dev/null +++ b/src/com/demo/tank/course7/abstractFactory/BaseExplode.java @@ -0,0 +1,7 @@ +package com.demo.tank.course7.abstractFactory; + +import java.awt.*; + +public abstract class BaseExplode { + public abstract void paint(Graphics g); +} diff --git a/src/com/demo/tank/course7/abstractFactory/BaseTank.java b/src/com/demo/tank/course7/abstractFactory/BaseTank.java new file mode 100644 index 0000000..d9ea276 --- /dev/null +++ b/src/com/demo/tank/course7/abstractFactory/BaseTank.java @@ -0,0 +1,18 @@ +package com.demo.tank.course7.abstractFactory; + +import com.demo.tank.enums.Group; + +import java.awt.*; + +public abstract class BaseTank { + public Rectangle rect = new Rectangle(); + + public abstract void paint(Graphics g); + public abstract void die(); + + public abstract Group getGroup(); + + public abstract int getX(); + + public abstract int getY(); +} diff --git a/src/com/demo/tank/course7/abstractFactory/CircleBullet.java b/src/com/demo/tank/course7/abstractFactory/CircleBullet.java new file mode 100644 index 0000000..af4015d --- /dev/null +++ b/src/com/demo/tank/course7/abstractFactory/CircleBullet.java @@ -0,0 +1,128 @@ +package com.demo.tank.course7.abstractFactory; + +import com.demo.tank.course7.Bullet; +import com.demo.tank.course7.Explode; +import com.demo.tank.course7.Tank; +import com.demo.tank.course7.TankFrameV7; +import com.demo.tank.enums.Direction; +import com.demo.tank.enums.Group; +import com.demo.tank.util.ResourceManager; + +import java.awt.*; + +public class CircleBullet extends BaseBullet{ + private int x, y; + private Direction direction; + private static final int SPEED = 10; + public static final int WIDTH = ResourceManager.bulletD.getWidth(); + public static final int HEIGHT = ResourceManager.bulletD.getHeight(); + private boolean live = true; + private Group group = Group.BAD; + private TankFrameV7 tf; + Rectangle rect = new Rectangle(); + + public CircleBullet(int x, int y, Direction direction, Group group, TankFrameV7 tf) { + this.x = x; + this.y = y; + this.direction = direction; + this.group = group; + this.tf = tf; + + rect.x = this.x; + rect.y = this.y; + rect.width = Bullet.WIDTH; + rect.height = Bullet.HEIGHT; + tf.bullets.add(this); + } + + @Override + public void paint(Graphics g){ + if(!live){ + tf.bullets.remove(this); + } + Color c = g.getColor(); + g.setColor(Color.YELLOW); + g.fillOval(x, y, 10, 10); + g.setColor(c); + move(); + } + + private void move() { + switch (direction){ + case UP: y -= SPEED; + break; + case DOWN: y += SPEED; + break; + case LEFT: x -= SPEED; + break; + case RIGHT: x += SPEED; + break; + default: + break; + } + if(x < 0 || y < 0 || x > TankFrameV7.GAME_WIDTH || y > TankFrameV7.GAME_HEIGHT){ + live = false; + } + rect.x = this.x; + rect.y = this.y; + } + + @Override + //检测是否跟坦克碰撞 + public void collideWith(BaseTank 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(tf.gameFactory.createExplode(ex, ey , tf)); + } + } + + private void die() { + this.live = false; + } + + 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 Direction getDirection() { + return direction; + } + + public void setDirection(Direction direction) { + this.direction = direction; + } + + public boolean isLive() { + return live; + } + + public void setLive(boolean live) { + this.live = live; + } + + public Group getGroup() { + return group; + } + + public void setGroup(Group group) { + this.group = group; + } +} diff --git a/src/com/demo/tank/course7/abstractFactory/CircleExplode.java b/src/com/demo/tank/course7/abstractFactory/CircleExplode.java new file mode 100644 index 0000000..794e957 --- /dev/null +++ b/src/com/demo/tank/course7/abstractFactory/CircleExplode.java @@ -0,0 +1,51 @@ +package com.demo.tank.course7.abstractFactory; + +import com.demo.tank.course7.TankFrameV7; +import com.demo.tank.util.ResourceManager; + +import java.awt.*; + +public class CircleExplode extends BaseExplode{ + private int x, y; + public static final int WIDTH = ResourceManager.explodes[0].getWidth(); + public static final int HEIGHT = ResourceManager.explodes[0].getHeight(); + private TankFrameV7 tf; + + private int step = 0; + + public CircleExplode(int x, int y, TankFrameV7 tf) { + this.x = x; + this.y = y; + this.tf = tf; +// new Thread(() -> new Audio("audio/explode.wav").play()).start(); + } + + @Override + public void paint(Graphics g){ + Color c = g.getColor(); + g.setColor(Color.RED); + g.fillOval(x, y, 5*step, 5*step); + step++; + if(step >= 10){ + //播放完爆炸效果图片, remove + tf.explodes.remove(this); + } + g.setColor(c); + } + + 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; + } +} diff --git a/src/com/demo/tank/course7/abstractFactory/CircleFactory.java b/src/com/demo/tank/course7/abstractFactory/CircleFactory.java new file mode 100644 index 0000000..733db9b --- /dev/null +++ b/src/com/demo/tank/course7/abstractFactory/CircleFactory.java @@ -0,0 +1,22 @@ +package com.demo.tank.course7.abstractFactory; + +import com.demo.tank.course7.TankFrameV7; +import com.demo.tank.enums.Direction; +import com.demo.tank.enums.Group; + +public class CircleFactory extends GameFactory{ + @Override + public BaseTank createTank(int x, int y, Direction dir, Group group, TankFrameV7 tf) { + return new CircleTank(x,y,dir,group,tf); + } + + @Override + public BaseBullet createBullet(int x, int y, Direction dir, Group group, TankFrameV7 tf) { + return new CircleBullet(x, y, dir, group, tf); + } + + @Override + public BaseExplode createExplode(int x, int y, TankFrameV7 tf) { + return new CircleExplode(x, y, tf); + } +} diff --git a/src/com/demo/tank/course7/abstractFactory/CircleTank.java b/src/com/demo/tank/course7/abstractFactory/CircleTank.java new file mode 100644 index 0000000..2bf992c --- /dev/null +++ b/src/com/demo/tank/course7/abstractFactory/CircleTank.java @@ -0,0 +1,193 @@ +package com.demo.tank.course7.abstractFactory; + +import com.demo.tank.course7.Bullet; +import com.demo.tank.course7.DefaultFireStrategy; +import com.demo.tank.course7.FireStrategy; +import com.demo.tank.course7.Tank; +import com.demo.tank.course7.TankFrameV7; +import com.demo.tank.enums.Direction; +import com.demo.tank.enums.Group; +import com.demo.tank.util.ResourceManager; + +import java.awt.*; +import java.util.Random; + +public class CircleTank extends BaseTank{ + private int x,y; + private Direction dir; + private static final int SPEED = 8; + private boolean moving = true; + private boolean living = true; + private Group group = Group.BAD; + TankFrameV7 tankFrame = null; + public static final int WIDTH = ResourceManager.tankD.getWidth(); + public static final int HEIGHT = ResourceManager.tankD.getHeight(); + private Random random = new Random(); + public Rectangle rect = new Rectangle(); + FireStrategy fireStrategy; + + + public CircleTank(int x, int y, Direction dir, Group group, TankFrameV7 tankFrame) { + this.x = x; + this.y = y; + this.dir = dir; + this.group = group; + this.tankFrame = tankFrame; + + rect.x = this.x; + rect.y = this.y; + rect.width = Tank.WIDTH; + rect.height = Tank.HEIGHT; + + if(this.group == Group.GOOD) { +// String className = PropertyManager.getString("good.tank.fire.strategy"); + try { + fireStrategy = (FireStrategy) Class.forName("com.demo.tank.course7.FourDirectionFireStrategy").newInstance(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + }else if(this.group == Group.BAD) fireStrategy = new DefaultFireStrategy(); + } + + @Override + public void paint(Graphics g) { + if(!living) tankFrame.enemyTanks.remove(this); + //根据方向绘制坦克 + Color c = g.getColor(); + g.setColor(this.group == Group.BAD ? Color.RED : Color.YELLOW); + g.fillOval(x,y, 40, 40); + g.setColor(c); + move(); + } + + public void move(){ + //如果没有移动 return + if(!moving) return; + switch (dir){ + case UP: y -= SPEED; + break; + case DOWN: y += SPEED; + break; + case LEFT: x -= SPEED; + break; + case RIGHT: x += SPEED; + break; + default: + break; + } + if(this.group == Group.BAD) { + if(random.nextInt(10) == 5){ + this.fire(); + } + if(random.nextInt(100) > 95){ + this.randomDirection(); + } + } + + //边界检测 + boundsCheck(); + + rect.x = this.x; + rect.y = this.y; + } + + private void boundsCheck() { + if(x < 0) x = 0; + if(x > TankFrameV7.GAME_WIDTH - Tank.WIDTH) x = TankFrameV7.GAME_WIDTH - Tank.WIDTH; + if(y < 30) y = 30; //算上菜单条 + if(y > TankFrameV7.GAME_HEIGHT - Tank.HEIGHT) y = TankFrameV7.GAME_HEIGHT - Tank.HEIGHT; + } + + private void randomDirection() { + this.dir = Direction.values()[random.nextInt(4)]; + } + + public void fire() { +// fireStrategy.fire(this); + int bx = x + Tank.WIDTH/2 - Bullet.WIDTH/2; + int by = y + Tank.HEIGHT/2 - Bullet.HEIGHT/2; + if(this.group == Group.BAD){ + this.tankFrame.gameFactory.createBullet(bx, by, this.dir, this.group,this.tankFrame); + }else{ + for(Direction direction : Direction.values()){ + this.tankFrame.gameFactory.createBullet(bx, by, direction, this.group,this.tankFrame); + } + } + } + + @Override + public void die(){ + this.living = false; + } + + @Override + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + @Override + public int getY() { + return y; + } + + public void setY(int y) { + this.y = y; + } + + public Direction getDir() { + return dir; + } + + public void setDir(Direction dir) { + this.dir = dir; + } + + public boolean isMoving() { + return moving; + } + + public void setMoving(boolean moving) { + this.moving = moving; + } + + public boolean isLiving() { + return living; + } + + public void setLiving(boolean living) { + this.living = living; + } + + @Override + public Group getGroup() { + return group; + } + + public void setGroup(Group group) { + this.group = group; + } + + public TankFrameV7 getTankFrame() { + return tankFrame; + } + + public void setTankFrame(TankFrameV7 tankFrame) { + this.tankFrame = tankFrame; + } + + public Rectangle getRect() { + return rect; + } + + public void setRect(Rectangle rect) { + this.rect = rect; + } +} diff --git a/src/com/demo/tank/course7/abstractFactory/DefaultFactory.java b/src/com/demo/tank/course7/abstractFactory/DefaultFactory.java new file mode 100644 index 0000000..b51db46 --- /dev/null +++ b/src/com/demo/tank/course7/abstractFactory/DefaultFactory.java @@ -0,0 +1,25 @@ +package com.demo.tank.course7.abstractFactory; + +import com.demo.tank.course7.Bullet; +import com.demo.tank.course7.Explode; +import com.demo.tank.course7.Tank; +import com.demo.tank.course7.TankFrameV7; +import com.demo.tank.enums.Direction; +import com.demo.tank.enums.Group; + +public class DefaultFactory extends GameFactory{ + @Override + public BaseTank createTank(int x, int y, Direction dir, Group group, TankFrameV7 tf) { + return new Tank(x,y,dir,group,tf); + } + + @Override + public BaseBullet createBullet(int x, int y, Direction dir, Group group, TankFrameV7 tf) { + return new Bullet(x, y, dir, group, tf); + } + + @Override + public BaseExplode createExplode(int x, int y, TankFrameV7 tf) { + return new Explode(x, y, tf); + } +} diff --git a/src/com/demo/tank/course7/abstractFactory/GameFactory.java b/src/com/demo/tank/course7/abstractFactory/GameFactory.java new file mode 100644 index 0000000..b7de0f8 --- /dev/null +++ b/src/com/demo/tank/course7/abstractFactory/GameFactory.java @@ -0,0 +1,11 @@ +package com.demo.tank.course7.abstractFactory; + +import com.demo.tank.course7.TankFrameV7; +import com.demo.tank.enums.Direction; +import com.demo.tank.enums.Group; + +public abstract class GameFactory { + public abstract BaseTank createTank(int x, int y, Direction dir, Group group, TankFrameV7 tf); + public abstract BaseBullet createBullet(int x, int y, Direction dir, Group group, TankFrameV7 tf); + public abstract BaseExplode createExplode(int x, int y, TankFrameV7 tf); +}