diff --git a/docs/坦克大战笔记.docx b/docs/坦克大战笔记.docx index b4f50c9..a49639d 100644 Binary files a/docs/坦克大战笔记.docx and b/docs/坦克大战笔记.docx differ diff --git a/src/com/demo/tank/course14/Bullet.java b/src/com/demo/tank/course14/Bullet.java new file mode 100644 index 0000000..40559f9 --- /dev/null +++ b/src/com/demo/tank/course14/Bullet.java @@ -0,0 +1,129 @@ +package com.demo.tank.course14; + +import com.demo.tank.enums.Direction; +import com.demo.tank.enums.Group; +import com.demo.tank.util.ResourceManager; + +import java.awt.*; + +public class Bullet extends GameObject { + 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; + Rectangle rect = new Rectangle(); + + public Bullet(int x, int y, Direction direction, Group group) { + this.x = x; + this.y = y; + this.direction = direction; + this.group = group; + + rect.x = this.x; + rect.y = this.y; + rect.width = Bullet.WIDTH; + rect.height = Bullet.HEIGHT; + GameModel.getInstance().add(this); + } + + public void paint(Graphics g) { + if (!live) { + GameModel.getInstance().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 > TankFrameV14.GAME_WIDTH || y > TankFrameV14.GAME_HEIGHT) { + live = false; + } + rect.x = this.x; + rect.y = this.y; + } + + public 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; + } + + @Override + public int getWidth() { + return WIDTH; + } + + @Override + public int getHeight() { + return HEIGHT; + } +} diff --git a/src/com/demo/tank/course14/BulletTankCollider.java b/src/com/demo/tank/course14/BulletTankCollider.java new file mode 100644 index 0000000..a3b16ac --- /dev/null +++ b/src/com/demo/tank/course14/BulletTankCollider.java @@ -0,0 +1,25 @@ +package com.demo.tank.course14; + +public class BulletTankCollider implements Collider { + @Override + public void collide(GameObject g1, GameObject g2) { + 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)) { + t.die(); + b.die(); + //爆炸 + 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) { + collide(g2, g1); + } else { + return; + } + } +} diff --git a/src/com/demo/tank/course14/BulletWallCollider.java b/src/com/demo/tank/course14/BulletWallCollider.java new file mode 100644 index 0000000..b21ab29 --- /dev/null +++ b/src/com/demo/tank/course14/BulletWallCollider.java @@ -0,0 +1,18 @@ +package com.demo.tank.course14; + +public class BulletWallCollider implements Collider { + @Override + public void collide(GameObject g1, GameObject g2) { + if (g1 instanceof Bullet && g2 instanceof Wall) { + Bullet b = (Bullet) g1; + Wall w = (Wall) g2; + if (b.rect.intersects(w.rect)) { + b.die(); + } + } else if (g1 instanceof Wall && g2 instanceof Bullet) { + collide(g2, g1); + } else { + return; + } + } +} diff --git a/src/com/demo/tank/course14/Collider.java b/src/com/demo/tank/course14/Collider.java new file mode 100644 index 0000000..34204ce --- /dev/null +++ b/src/com/demo/tank/course14/Collider.java @@ -0,0 +1,5 @@ +package com.demo.tank.course14; + +public interface Collider { + void collide(GameObject g1, GameObject g2); +} diff --git a/src/com/demo/tank/course14/ColliderChain.java b/src/com/demo/tank/course14/ColliderChain.java new file mode 100644 index 0000000..b39a5e5 --- /dev/null +++ b/src/com/demo/tank/course14/ColliderChain.java @@ -0,0 +1,25 @@ +package com.demo.tank.course14; + +import java.util.LinkedList; +import java.util.List; + +public class ColliderChain { + private List colliders = new LinkedList<>(); + + public ColliderChain() { + add(new BulletTankCollider()); + add(new TankTankCollider()); + add(new BulletWallCollider()); + add(new TankWallCollider()); + } + + public void add(Collider collider) { + colliders.add(collider); + } + + public void collide(GameObject g1, GameObject g2) { + for (Collider c : colliders) { + c.collide(g1, g2); + } + } +} diff --git a/src/com/demo/tank/course14/DefaultFireStrategy.java b/src/com/demo/tank/course14/DefaultFireStrategy.java new file mode 100644 index 0000000..1fed548 --- /dev/null +++ b/src/com/demo/tank/course14/DefaultFireStrategy.java @@ -0,0 +1,20 @@ +package com.demo.tank.course14; + +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()); +// 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/course14/Explode.java b/src/com/demo/tank/course14/Explode.java new file mode 100644 index 0000000..ecf3a34 --- /dev/null +++ b/src/com/demo/tank/course14/Explode.java @@ -0,0 +1,51 @@ +package com.demo.tank.course14; + +import com.demo.tank.util.Audio; +import com.demo.tank.util.ResourceManager; + +import java.awt.*; + +public class Explode extends GameObject { + public static final int WIDTH = ResourceManager.explodes[0].getWidth(); + public static final int HEIGHT = ResourceManager.explodes[0].getHeight(); + + private int step = 0; + + public Explode(int x, int y) { + this.x = x; + this.y = y; + 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 + GameModel.getInstance().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; + } + + public int getWidth() { + return WIDTH; + } + + public int getHeight() { + return HEIGHT; + } +} diff --git a/src/com/demo/tank/course14/FireStrategy.java b/src/com/demo/tank/course14/FireStrategy.java new file mode 100644 index 0000000..a056530 --- /dev/null +++ b/src/com/demo/tank/course14/FireStrategy.java @@ -0,0 +1,7 @@ +package com.demo.tank.course14; + +import java.io.Serializable; + +public interface FireStrategy extends Serializable { + void fire(Tank tank); +} diff --git a/src/com/demo/tank/course14/FourDirectionFireStrategy.java b/src/com/demo/tank/course14/FourDirectionFireStrategy.java new file mode 100644 index 0000000..ef97685 --- /dev/null +++ b/src/com/demo/tank/course14/FourDirectionFireStrategy.java @@ -0,0 +1,17 @@ +package com.demo.tank.course14; + +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()); + } + if (tank.getGroup() == Group.GOOD) new Thread(() -> new Audio("audio/tank_fire.wav").play()).start(); + } +} diff --git a/src/com/demo/tank/course14/GODecorator.java b/src/com/demo/tank/course14/GODecorator.java new file mode 100644 index 0000000..850fd29 --- /dev/null +++ b/src/com/demo/tank/course14/GODecorator.java @@ -0,0 +1,13 @@ +package com.demo.tank.course14; + +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/course14/GameModel.java b/src/com/demo/tank/course14/GameModel.java new file mode 100644 index 0000000..56178cf --- /dev/null +++ b/src/com/demo/tank/course14/GameModel.java @@ -0,0 +1,114 @@ +package com.demo.tank.course14; + +import com.demo.tank.enums.Direction; +import com.demo.tank.enums.Group; +import com.demo.tank.util.PropertyManager; + +import java.awt.*; +import java.io.*; +import java.util.ArrayList; +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 collider2 = new TankTankCollider(); + ColliderChain chain = new ColliderChain(); + Tank tank; + + private GameModel() { + + } + + 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)); + } + add(new Wall(150, 150, 200, 50)); + add(new Wall(550, 150, 200, 50)); + add(new Wall(300, 300, 50, 200)); + add(new Wall(550, 300, 50, 200)); + } + + public static GameModel getInstance() { + return GM; + } + + public void add(GameObject go) { + gameObjects.add(go); + } + + public void remove(GameObject go) { + gameObjects.remove(go); + } + + public void paint(Graphics g) { + tank.paint(g); + + 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); + } + } + } + + public void save(){ + File file = new File("D:\\workspace\\tank\\src\\com\\demo\\tank\\course14\\tank.data"); + ObjectOutputStream oos = null; + try { + oos = new ObjectOutputStream(new FileOutputStream(file)); + oos.writeObject(tank); + oos.writeObject(gameObjects); + System.out.println("game saved..."); + } catch (IOException e) { + e.printStackTrace(); + }finally { + try { + if(oos != null){ + oos.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public void load(){ + File file = new File("D:\\workspace\\tank\\src\\com\\demo\\tank\\course14\\tank.data"); + ObjectInputStream ois = null; + try { + ois = new ObjectInputStream(new FileInputStream(file)); + tank = (Tank)ois.readObject(); + gameObjects = (List)ois.readObject(); + System.out.println("game load..."); + } catch (IOException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + }finally { + try { + if(ois != null){ + ois.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/com/demo/tank/course14/GameObject.java b/src/com/demo/tank/course14/GameObject.java new file mode 100644 index 0000000..b964bfe --- /dev/null +++ b/src/com/demo/tank/course14/GameObject.java @@ -0,0 +1,14 @@ +package com.demo.tank.course14; + +import java.awt.*; +import java.io.Serializable; + +public abstract class GameObject implements Serializable { + int x, y; + + public abstract void paint(Graphics g); + + public abstract int getWidth(); + + public abstract int getHeight(); +} diff --git a/src/com/demo/tank/course14/MainV14.java b/src/com/demo/tank/course14/MainV14.java new file mode 100644 index 0000000..30bd193 --- /dev/null +++ b/src/com/demo/tank/course14/MainV14.java @@ -0,0 +1,16 @@ +package com.demo.tank.course14; + +import java.io.IOException; + +public class MainV14 { + public static void main(String[] args) throws InterruptedException, IOException { + TankFrameV14 tf = new TankFrameV14(); + +// new Thread(() -> new Audio("audio/war1.wav").loop()).start(); + + while (true) { + Thread.sleep(50); + tf.repaint(); + } + } +} diff --git a/src/com/demo/tank/course14/RectDecorator.java b/src/com/demo/tank/course14/RectDecorator.java new file mode 100644 index 0000000..58916a9 --- /dev/null +++ b/src/com/demo/tank/course14/RectDecorator.java @@ -0,0 +1,32 @@ +package com.demo.tank.course14; + +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/course14/TailDecorator.java b/src/com/demo/tank/course14/TailDecorator.java new file mode 100644 index 0000000..fdd4001 --- /dev/null +++ b/src/com/demo/tank/course14/TailDecorator.java @@ -0,0 +1,31 @@ +package com.demo.tank.course14; + +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/course14/Tank.java b/src/com/demo/tank/course14/Tank.java new file mode 100644 index 0000000..6dbe5a3 --- /dev/null +++ b/src/com/demo/tank/course14/Tank.java @@ -0,0 +1,206 @@ +package com.demo.tank.course14; + +import com.demo.tank.enums.Direction; +import com.demo.tank.enums.Group; +import com.demo.tank.util.ResourceManager; + +import java.awt.*; +import java.sql.Timestamp; +import java.time.Instant; +import java.util.Arrays; +import java.util.Random; + +public class Tank extends GameObject { + int oldX, oldY; + private Direction dir; + private static final int SPEED = 8; + private boolean moving = true; + private boolean living = true; + private Group group = Group.BAD; + 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) { + this.x = x; + this.y = y; + this.dir = dir; + this.group = group; + + 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.course14.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) GameModel.getInstance().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() { + oldX = x; + oldY = y; + //如果没有移动 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; + } + + public void back() { + this.x = oldX; + this.y = oldY; + } + + private void boundsCheck() { + if (x < 0) x = 0; + if (x > TankFrameV14.GAME_WIDTH - Tank.WIDTH) x = TankFrameV14.GAME_WIDTH - Tank.WIDTH; + if (y < 30) y = 30; //算上菜单条 + if (y > TankFrameV14.GAME_HEIGHT - Tank.HEIGHT) y = TankFrameV14.GAME_HEIGHT - Tank.HEIGHT; + } + + private void randomDirection() { + this.dir = Direction.values()[random.nextInt(4)]; + } + + public void fire() { + fireStrategy.fire(this); + } + + public void handleFireKey(){ + java.util.List observers = Arrays.asList(new TankFireHandler()); + TankEvent event = new TankEvent(Timestamp.from(Instant.now()), this); + for (TankFireObserver o : observers){ + o.actionOnFire(event); + } + } + + 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 Rectangle getRect() { + return rect; + } + + public void setRect(Rectangle rect) { + this.rect = rect; + } + + public int getWidth() { + return WIDTH; + } + + public int getHeight() { + return HEIGHT; + } + +} diff --git a/src/com/demo/tank/course14/TankEvent.java b/src/com/demo/tank/course14/TankEvent.java new file mode 100644 index 0000000..bfc9d4e --- /dev/null +++ b/src/com/demo/tank/course14/TankEvent.java @@ -0,0 +1,21 @@ +package com.demo.tank.course14; + +import java.sql.Timestamp; + +public class TankEvent { + private Timestamp timestamp; + private Tank source; + + public TankEvent(Timestamp timestamp, Tank source) { + this.timestamp = timestamp; + this.source = source; + } + + public Timestamp getTimestamp() { + return timestamp; + } + + public Tank getSource() { + return source; + } +} diff --git a/src/com/demo/tank/course14/TankFireHandler.java b/src/com/demo/tank/course14/TankFireHandler.java new file mode 100644 index 0000000..a560232 --- /dev/null +++ b/src/com/demo/tank/course14/TankFireHandler.java @@ -0,0 +1,10 @@ +package com.demo.tank.course14; + +public class TankFireHandler implements TankFireObserver { + @Override + public void actionOnFire(TankEvent event) { + Tank tank = event.getSource(); + System.out.println("my tank fire time: " + event.getTimestamp()); + tank.fire(); + } +} diff --git a/src/com/demo/tank/course14/TankFireObserver.java b/src/com/demo/tank/course14/TankFireObserver.java new file mode 100644 index 0000000..d08b0c7 --- /dev/null +++ b/src/com/demo/tank/course14/TankFireObserver.java @@ -0,0 +1,7 @@ +package com.demo.tank.course14; + +import java.io.Serializable; + +public interface TankFireObserver extends Serializable { + void actionOnFire(TankEvent event); +} diff --git a/src/com/demo/tank/course14/TankFrameV14.java b/src/com/demo/tank/course14/TankFrameV14.java new file mode 100644 index 0000000..586d224 --- /dev/null +++ b/src/com/demo/tank/course14/TankFrameV14.java @@ -0,0 +1,117 @@ +package com.demo.tank.course14; + +import com.demo.tank.enums.Direction; + +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class TankFrameV14 extends Frame { + GameModel gm = GameModel.getInstance(); + public static final int GAME_WIDTH = 1080; + public static final int GAME_HEIGHT = 800; + Image image = null; + + public TankFrameV14() { + 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) { + gm.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; + case KeyEvent.VK_O: + gm.save(); + case KeyEvent.VK_L: + gm.load(); + 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: + gm.tank.handleFireKey(); + break; + default: + break; + } + setTankDirection(); + } + + public void setTankDirection() { + if (!bL && !bR && !bU && !bD) { + gm.tank.setMoving(false); + } 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); + } + } + } +} diff --git a/src/com/demo/tank/course14/TankTankCollider.java b/src/com/demo/tank/course14/TankTankCollider.java new file mode 100644 index 0000000..b10c665 --- /dev/null +++ b/src/com/demo/tank/course14/TankTankCollider.java @@ -0,0 +1,22 @@ +package com.demo.tank.course14; + +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) { + Tank t1 = (Tank) g1; + Tank t2 = (Tank) g2; + if (t1.rect.intersects(t2.rect)) { + // simple deal + t1.back(); + t2.back(); + } + } else { + return; + } + } +} diff --git a/src/com/demo/tank/course14/TankWallCollider.java b/src/com/demo/tank/course14/TankWallCollider.java new file mode 100644 index 0000000..45ccf72 --- /dev/null +++ b/src/com/demo/tank/course14/TankWallCollider.java @@ -0,0 +1,18 @@ +package com.demo.tank.course14; + +public class TankWallCollider implements Collider { + @Override + public void collide(GameObject g1, GameObject g2) { + if (g1 instanceof Tank && g2 instanceof Wall) { + Tank t = (Tank) g1; + Wall w = (Wall) g2; + if (t.rect.intersects(w.rect)) { + t.back(); + } + } else if (g1 instanceof Wall && g2 instanceof Bullet) { + collide(g2, g1); + } else { + return; + } + } +} diff --git a/src/com/demo/tank/course14/Wall.java b/src/com/demo/tank/course14/Wall.java new file mode 100644 index 0000000..e43de7c --- /dev/null +++ b/src/com/demo/tank/course14/Wall.java @@ -0,0 +1,32 @@ +package com.demo.tank.course14; + +import java.awt.*; + +public class Wall extends GameObject { + int width, height; + Rectangle rect; + + public Wall(int x, int y, int width, int height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.rect = new Rectangle(x, y, width, height); + } + + @Override + public void paint(Graphics g) { + Color c = g.getColor(); + g.setColor(Color.DARK_GRAY); + g.fillRect(x, y, width, height); + g.setColor(c); + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } +}