diff --git a/docs/坦克大战笔记.docx b/docs/坦克大战笔记.docx index 7056eb6..967025f 100644 Binary files a/docs/坦克大战笔记.docx and b/docs/坦克大战笔记.docx differ diff --git a/src/com/demo/tank/strategy/DefaultFireStrategy.java b/src/com/demo/tank/course6/DefaultFireStrategy.java similarity index 82% rename from src/com/demo/tank/strategy/DefaultFireStrategy.java rename to src/com/demo/tank/course6/DefaultFireStrategy.java index d2480f0..72ff122 100644 --- a/src/com/demo/tank/strategy/DefaultFireStrategy.java +++ b/src/com/demo/tank/course6/DefaultFireStrategy.java @@ -1,8 +1,6 @@ -package com.demo.tank.strategy; +package com.demo.tank.course6; -import com.demo.tank.course6.Bullet; import com.demo.tank.enums.Group; -import com.demo.tank.course6.Tank; import com.demo.tank.util.Audio; public class DefaultFireStrategy implements FireStrategy{ diff --git a/src/com/demo/tank/strategy/FireStrategy.java b/src/com/demo/tank/course6/FireStrategy.java similarity index 75% rename from src/com/demo/tank/strategy/FireStrategy.java rename to src/com/demo/tank/course6/FireStrategy.java index fa656fd..6731424 100644 --- a/src/com/demo/tank/strategy/FireStrategy.java +++ b/src/com/demo/tank/course6/FireStrategy.java @@ -1,4 +1,4 @@ -package com.demo.tank.strategy; +package com.demo.tank.course6; import com.demo.tank.course6.Tank; diff --git a/src/com/demo/tank/strategy/FourDirectionFireStrategy.java b/src/com/demo/tank/course6/FourDirectionFireStrategy.java similarity index 85% rename from src/com/demo/tank/strategy/FourDirectionFireStrategy.java rename to src/com/demo/tank/course6/FourDirectionFireStrategy.java index c364119..7617b6f 100644 --- a/src/com/demo/tank/strategy/FourDirectionFireStrategy.java +++ b/src/com/demo/tank/course6/FourDirectionFireStrategy.java @@ -1,9 +1,7 @@ -package com.demo.tank.strategy; +package com.demo.tank.course6; -import com.demo.tank.course6.Bullet; import com.demo.tank.enums.Direction; import com.demo.tank.enums.Group; -import com.demo.tank.course6.Tank; import com.demo.tank.util.Audio; public class FourDirectionFireStrategy implements FireStrategy{ diff --git a/src/com/demo/tank/course6/Tank.java b/src/com/demo/tank/course6/Tank.java index de73c5c..a0604e9 100644 --- a/src/com/demo/tank/course6/Tank.java +++ b/src/com/demo/tank/course6/Tank.java @@ -1,7 +1,5 @@ package com.demo.tank.course6; -import com.demo.tank.strategy.DefaultFireStrategy; -import com.demo.tank.strategy.FireStrategy; import com.demo.tank.enums.Direction; import com.demo.tank.enums.Group; import com.demo.tank.util.PropertyManager; diff --git a/src/com/demo/tank/course7/Bullet.java b/src/com/demo/tank/course7/Bullet.java new file mode 100644 index 0000000..10bd485 --- /dev/null +++ b/src/com/demo/tank/course7/Bullet.java @@ -0,0 +1,132 @@ +package com.demo.tank.course7; + +import com.demo.tank.enums.Direction; +import com.demo.tank.enums.Group; +import com.demo.tank.util.ResourceManager; + +import java.awt.*; + +public class Bullet { + 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 TankFrameV6 tf; + Rectangle rect = new Rectangle(); + + public Bullet(int x, int y, Direction direction, Group group, TankFrameV6 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); + } + + public void paint(Graphics g){ + if(!live){ + tf.bullets.remove(this); + } + switch (direction){ + case UP: + g.drawImage(ResourceManager.bulletU, x, y, null); + break; + case DOWN: + g.drawImage(ResourceManager.bulletD, x, y, null); + break; + case LEFT: + g.drawImage(ResourceManager.bulletL, x, y, null); + break; + case RIGHT: + g.drawImage(ResourceManager.bulletR, x, y, null); + break; + } + 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 > TankFrameV6.GAME_WIDTH || y > TankFrameV6.GAME_HEIGHT){ + live = false; + } + rect.x = this.x; + rect.y = this.y; + } + + //检测是否跟坦克碰撞 + 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() { + 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/DefaultFireStrategy.java b/src/com/demo/tank/course7/DefaultFireStrategy.java new file mode 100644 index 0000000..ac664d4 --- /dev/null +++ b/src/com/demo/tank/course7/DefaultFireStrategy.java @@ -0,0 +1,14 @@ +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(); + } +} diff --git a/src/com/demo/tank/course7/Explode.java b/src/com/demo/tank/course7/Explode.java new file mode 100644 index 0000000..c63c76b --- /dev/null +++ b/src/com/demo/tank/course7/Explode.java @@ -0,0 +1,47 @@ +package com.demo.tank.course7; + +import com.demo.tank.util.Audio; +import com.demo.tank.util.ResourceManager; + +import java.awt.*; + +public class Explode { + private int x, y; + public static final int WIDTH = ResourceManager.explodes[0].getWidth(); + public static final int HEIGHT = ResourceManager.explodes[0].getHeight(); + private TankFrameV6 tf; + + private int step = 0; + + public Explode(int x, int y, TankFrameV6 tf) { + this.x = x; + this.y = y; + this.tf = tf; + new Thread(() -> new Audio("audio/explode.wav").play()).start(); + } + + public void paint(Graphics g){ + g.drawImage(ResourceManager.explodes[step++], x, y, null); + if(step >= ResourceManager.explodes.length){ + //播放完爆炸效果图片, remove + tf.explodes.remove(this); + } + } + + 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/FireStrategy.java b/src/com/demo/tank/course7/FireStrategy.java new file mode 100644 index 0000000..91b5ce2 --- /dev/null +++ b/src/com/demo/tank/course7/FireStrategy.java @@ -0,0 +1,5 @@ +package com.demo.tank.course7; + +public interface FireStrategy { + void fire(Tank tank); +} diff --git a/src/com/demo/tank/course7/FourDirectionFireStrategy.java b/src/com/demo/tank/course7/FourDirectionFireStrategy.java new file mode 100644 index 0000000..82f3433 --- /dev/null +++ b/src/com/demo/tank/course7/FourDirectionFireStrategy.java @@ -0,0 +1,17 @@ +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 + 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()){ + new Bullet(bx, by, direction, tank.getGroup(),tank.getTankFrame()); + } + if (tank.getGroup() == Group.GOOD) new Thread(() -> new Audio("audio/tank_fire.wav").play()).start(); + } +} diff --git a/src/com/demo/tank/course7/MainV6.java b/src/com/demo/tank/course7/MainV6.java new file mode 100644 index 0000000..a997a2b --- /dev/null +++ b/src/com/demo/tank/course7/MainV6.java @@ -0,0 +1,24 @@ +package com.demo.tank.course7; + +import com.demo.tank.enums.Direction; +import com.demo.tank.enums.Group; +import com.demo.tank.util.PropertyManager; + +import java.io.IOException; + +public class MainV6 { + public static void main(String[] args) throws InterruptedException, IOException { + TankFrameV6 tf = new TankFrameV6(); + 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)); + } + +// new Thread(() -> new Audio("audio/war1.wav").loop()).start(); + + while (true){ + Thread.sleep(50); + tf.repaint(); + } + } +} diff --git a/src/com/demo/tank/course7/Tank.java b/src/com/demo/tank/course7/Tank.java new file mode 100644 index 0000000..cbdd1d4 --- /dev/null +++ b/src/com/demo/tank/course7/Tank.java @@ -0,0 +1,186 @@ +package com.demo.tank.course7; + +import com.demo.tank.enums.Direction; +import com.demo.tank.enums.Group; +import com.demo.tank.util.PropertyManager; +import com.demo.tank.util.ResourceManager; + +import java.awt.*; +import java.util.Random; + +public class Tank { + 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; + TankFrameV6 tankFrame = null; + 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(); + FireStrategy fireStrategy; + + + public Tank(int x, int y, Direction dir, Group group, TankFrameV6 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(className).newInstance(); + System.out.println(fireStrategy); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + }else if(this.group == Group.BAD) fireStrategy = new DefaultFireStrategy(); + } + + public void paint(Graphics g) { + if(!living) tankFrame.enemyTanks.remove(this); + //根据方向绘制坦克 + switch (dir){ + case UP: + g.drawImage(this.group == Group.GOOD ? ResourceManager.tankU : ResourceManager.badTankU, x, y, null); + 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); + break; + case RIGHT: + g.drawImage(this.group == Group.GOOD ? ResourceManager.tankR : ResourceManager.badTankR, x, y, null); + break; + } + 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 > TankFrameV6.GAME_WIDTH - Tank.WIDTH) x = TankFrameV6.GAME_WIDTH - Tank.WIDTH; + if(y < 30) y = 30; //算上菜单条 + if(y > TankFrameV6.GAME_HEIGHT - Tank.HEIGHT) y = TankFrameV6.GAME_HEIGHT - Tank.HEIGHT; + } + + private void randomDirection() { + this.dir = Direction.values()[random.nextInt(4)]; + } + + public void fire() { + fireStrategy.fire(this); + } + + public void die(){ + this.living = 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 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; + } + + public Group getGroup() { + return group; + } + + public void setGroup(Group group) { + this.group = group; + } + + public TankFrameV6 getTankFrame() { + return tankFrame; + } + + public void setTankFrame(TankFrameV6 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/TankFrameV6.java b/src/com/demo/tank/course7/TankFrameV6.java new file mode 100644 index 0000000..62cc714 --- /dev/null +++ b/src/com/demo/tank/course7/TankFrameV6.java @@ -0,0 +1,159 @@ +package com.demo.tank.course7; + +import com.demo.tank.enums.Direction; +import com.demo.tank.enums.Group; + +import java.awt.*; +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 TankFrameV6 extends Frame { + public static final int GAME_WIDTH = 1080; + public static final int GAME_HEIGHT = 800; + Image image = null; + + 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<>(); + + List explodes = new ArrayList<>(); + + public TankFrameV6(){ + setVisible(true); + setBounds(400, 100 , GAME_WIDTH, GAME_HEIGHT); + setResizable(false); + setTitle("tank war"); + this.addKeyListener(new MyKeyListener()); + this.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + } + + @Override + public void update(Graphics g) { + if(image == null){ + image = this.createImage(GAME_WIDTH, GAME_HEIGHT); + } + Graphics imgGraphic = image.getGraphics(); + Color color = g.getColor(); + imgGraphic.setColor(Color.BLACK); + 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){ + //打印出子弹数量 + Color color = g.getColor(); + g.setColor(Color.WHITE); + g.drawString("当前子弹数量:" + bullets.size(), 60, 50); + g.drawString("当前敌人数量:" + enemyTanks.size(), 60, 80); + g.drawString("当前爆炸数量:" + explodes.size(), 60, 100); + g.setColor(color); + + tank.paint(g); + + for(int i = 0; i< enemyTanks.size(); i++){ + enemyTanks.get(i).paint(g); + } + + for (int i = 0; i< bullets.size(); i++){ + bullets.get(i).paint(g); + } + + //碰撞检测 + for(int i = 0; i< bullets.size(); i++){ + for(int j=0; j< enemyTanks.size(); j++){ + bullets.get(i).collideWith(enemyTanks.get(j)); + } + } + + for (int i = 0; i< explodes.size(); i++){ + explodes.get(i).paint(g); + } +// for(Iterator it = bullets.iterator(); it.hasNext();){ +// Bullet b = it.next(); +// if(!b.isLive()){ +// it.remove(); +// } +// } +// +// for (Bullet b : bullets){ +// b.paint(g); +// } + } + + class MyKeyListener extends KeyAdapter{ + boolean bL = false; + boolean bR = false; + boolean bU = false; + boolean bD = false; + + @Override + public void keyPressed(KeyEvent e) { + switch (e.getKeyCode()){ + case KeyEvent.VK_A: + bL = true; + break; + case KeyEvent.VK_D: + bR = true; + break; + case KeyEvent.VK_W: + bU = true; + break; + case KeyEvent.VK_S: + bD = true; + break; + default: + break; + } + setTankDirection(); + } + + @Override + public void keyReleased(KeyEvent e) { + switch (e.getKeyCode()){ + case KeyEvent.VK_A: + bL = false; + break; + case KeyEvent.VK_D: + bR = false; + break; + case KeyEvent.VK_W: + bU = false; + break; + case KeyEvent.VK_S: + bD = false; + break; + case KeyEvent.VK_SPACE: + tank.fire(); + break; + default: + break; + } + setTankDirection(); + } + + public void setTankDirection(){ + if(!bL && !bR && !bU && !bD){ + tank.setMoving(false); + }else{ + tank.setMoving(true); + if(bL) tank.setDir(Direction.LEFT); + if(bR) tank.setDir(Direction.RIGHT); + if(bU) tank.setDir(Direction.UP); + if(bD) tank.setDir(Direction.DOWN); + } + } + } +} diff --git a/src/config b/src/config index 0fb47e7..2f65c27 100644 --- a/src/config +++ b/src/config @@ -3,5 +3,5 @@ tank.speed=5 bullet.speed=5 game.width=1080 game.height=720 -good.tank.fire.strategy=com.demo.tank.strategy.FourDirectionFireStrategy -bad.tank.fire.strategy=com.demo.tank.strategy.DefaultFireStrategy \ No newline at end of file +good.tank.fire.strategy=com.demo.tank.course6.FourDirectionFireStrategy +bad.tank.fire.strategy=com.demo.tank.course6.DefaultFireStrategy \ No newline at end of file