diff options
author | pacien | 2018-02-04 13:40:07 +0100 |
---|---|---|
committer | pacien | 2018-02-04 13:40:07 +0100 |
commit | 6c0fa25c9d6829e9a3990d952571433751616bee (patch) | |
tree | 9a8f6a32cf2187db96d2f7eabb953787d6d76a5d | |
parent | d214d357ff0b03205ba9a8d753c93c9fa17094f3 (diff) | |
download | wallj-6c0fa25c9d6829e9a3990d952571433751616bee.tar.gz |
Handle simulation start
Signed-off-by: pacien <pacien.trangirard@pacien.net>
-rw-r--r-- | src/main/java/fr/umlv/java/wallj/block/BombBlock.java | 10 | ||||
-rw-r--r-- | src/main/java/fr/umlv/java/wallj/block/RobotBlock.java | 21 | ||||
-rw-r--r-- | src/main/java/fr/umlv/java/wallj/context/Stage.java | 45 |
3 files changed, 60 insertions, 16 deletions
diff --git a/src/main/java/fr/umlv/java/wallj/block/BombBlock.java b/src/main/java/fr/umlv/java/wallj/block/BombBlock.java index 4f310eb..5570583 100644 --- a/src/main/java/fr/umlv/java/wallj/block/BombBlock.java +++ b/src/main/java/fr/umlv/java/wallj/block/BombBlock.java | |||
@@ -26,6 +26,7 @@ public class BombBlock extends JBoxBlock { | |||
26 | private static final Duration MAX_TIME = Duration.ofSeconds(9); | 26 | private static final Duration MAX_TIME = Duration.ofSeconds(9); |
27 | 27 | ||
28 | private Duration timer = MIN_TIME; | 28 | private Duration timer = MIN_TIME; |
29 | private boolean ignited = false; | ||
29 | 30 | ||
30 | BombBlock(Vec2 pos) { | 31 | BombBlock(Vec2 pos) { |
31 | super(BlockType.BOMB, BodyType.STATIC, SolidDef.squareShape(), pos); | 32 | super(BlockType.BOMB, BodyType.STATIC, SolidDef.squareShape(), pos); |
@@ -44,6 +45,7 @@ public class BombBlock extends JBoxBlock { | |||
44 | public Stream<Event> update(Context context) { | 45 | public Stream<Event> update(Context context) { |
45 | return Updateables.updateAll(context, | 46 | return Updateables.updateAll(context, |
46 | this::handleBombConfiguration, | 47 | this::handleBombConfiguration, |
48 | this::handleSimulationStart, | ||
47 | this::consume, | 49 | this::consume, |
48 | this::paint); | 50 | this::paint); |
49 | } | 51 | } |
@@ -55,8 +57,14 @@ public class BombBlock extends JBoxBlock { | |||
55 | return Stream.empty(); | 57 | return Stream.empty(); |
56 | } | 58 | } |
57 | 59 | ||
60 | private Stream<Event> handleSimulationStart(Context context) { | ||
61 | Events.findFirst(context.getEvents(), SimulationStartEvent.class) | ||
62 | .ifPresent(startEvent -> ignited = true); | ||
63 | return Stream.empty(); | ||
64 | } | ||
65 | |||
58 | private Stream<Event> consume(Context context) { | 66 | private Stream<Event> consume(Context context) { |
59 | decrementTimer(context.getTimeDelta()); | 67 | if (ignited) decrementTimer(context.getTimeDelta()); |
60 | return timer.isNegative() ? | 68 | return timer.isNegative() ? |
61 | Stream.of(new BombExplosionEvent(TileVec2.of(getPos())), new BlockDestroyEvent(this)) : | 69 | Stream.of(new BombExplosionEvent(TileVec2.of(getPos())), new BlockDestroyEvent(this)) : |
62 | Stream.empty(); | 70 | Stream.empty(); |
diff --git a/src/main/java/fr/umlv/java/wallj/block/RobotBlock.java b/src/main/java/fr/umlv/java/wallj/block/RobotBlock.java index 11cf25f..6909555 100644 --- a/src/main/java/fr/umlv/java/wallj/block/RobotBlock.java +++ b/src/main/java/fr/umlv/java/wallj/block/RobotBlock.java | |||
@@ -23,13 +23,16 @@ import java.util.stream.Stream; | |||
23 | public class RobotBlock extends Block { | 23 | public class RobotBlock extends Block { |
24 | private static final float SPEED = 10f; // px/ms | 24 | private static final float SPEED = 10f; // px/ms |
25 | 25 | ||
26 | private final TileVec2 initialPos; | ||
26 | private Vec2 pos; | 27 | private Vec2 pos; |
27 | private PathFinder pathFinder; | 28 | private PathFinder pathFinder; |
28 | private Deque<TileVec2> path = new LinkedList<>(); | 29 | private Deque<TileVec2> path = new LinkedList<>(); |
29 | private int droppedBombCount = 0; | 30 | private int droppedBombCount = 0; |
31 | private boolean isHiding = false; | ||
30 | 32 | ||
31 | RobotBlock(Vec2 pos) { | 33 | RobotBlock(Vec2 pos) { |
32 | super(BlockType.ROBOT); | 34 | super(BlockType.ROBOT); |
35 | this.initialPos = TileVec2.of(pos); | ||
33 | this.pos = pos; | 36 | this.pos = pos; |
34 | } | 37 | } |
35 | 38 | ||
@@ -51,12 +54,29 @@ public class RobotBlock extends Block { | |||
51 | @Override | 54 | @Override |
52 | public Stream<Event> update(Context context) { | 55 | public Stream<Event> update(Context context) { |
53 | return Updateables.updateAll(context, | 56 | return Updateables.updateAll(context, |
57 | this::handleSimulationStart, | ||
54 | this::updatePath, | 58 | this::updatePath, |
55 | this::move, | 59 | this::move, |
60 | this::disappear, | ||
56 | this::paint, | 61 | this::paint, |
57 | this::setupBomb); | 62 | this::setupBomb); |
58 | } | 63 | } |
59 | 64 | ||
65 | private Stream<Event> handleSimulationStart(Context context) { | ||
66 | return Events.findFirst(context.getEvents(), SimulationStartEvent.class) | ||
67 | .map(startEvent -> { | ||
68 | isHiding = true; | ||
69 | return Stream.<Event>of(new MoveRobotOrder(initialPos)); | ||
70 | }) | ||
71 | .orElse(Stream.empty()); | ||
72 | } | ||
73 | |||
74 | private Stream<Event> disappear(Context context) { | ||
75 | return isHiding && Objects.equals(TileVec2.of(pos), initialPos) ? | ||
76 | Stream.of(new BlockDestroyEvent(this)) : | ||
77 | Stream.empty(); | ||
78 | } | ||
79 | |||
60 | private Stream<Event> setupBomb(Context context) { | 80 | private Stream<Event> setupBomb(Context context) { |
61 | return Events.findFirst(context.getEvents(), BombSetupOrder.class) | 81 | return Events.findFirst(context.getEvents(), BombSetupOrder.class) |
62 | .flatMap(event -> isOnBomb(context.getGame().getCurrentStage()) ? | 82 | .flatMap(event -> isOnBomb(context.getGame().getCurrentStage()) ? |
@@ -78,6 +98,7 @@ public class RobotBlock extends Block { | |||
78 | Board board = context.getGame().getCurrentStage().getBoard(); | 98 | Board board = context.getGame().getCurrentStage().getBoard(); |
79 | TileVec2 target = event.getTarget(); | 99 | TileVec2 target = event.getTarget(); |
80 | if (!board.inside(target) || !board.getBlockTypeAt(target).isTraversable()) return; | 100 | if (!board.inside(target) || !board.getBlockTypeAt(target).isTraversable()) return; |
101 | if (isHiding && !Objects.equals(target, initialPos)) return; | ||
81 | if (pathFinder == null) pathFinder = new PathFinder(board); | 102 | if (pathFinder == null) pathFinder = new PathFinder(board); |
82 | path = new LinkedList<>(pathFinder.findPath(TileVec2.of(pos), target)); | 103 | path = new LinkedList<>(pathFinder.findPath(TileVec2.of(pos), target)); |
83 | }); | 104 | }); |
diff --git a/src/main/java/fr/umlv/java/wallj/context/Stage.java b/src/main/java/fr/umlv/java/wallj/context/Stage.java index 44fad7b..9b66e03 100644 --- a/src/main/java/fr/umlv/java/wallj/context/Stage.java +++ b/src/main/java/fr/umlv/java/wallj/context/Stage.java | |||
@@ -6,10 +6,7 @@ import fr.umlv.java.wallj.block.BlockType; | |||
6 | import fr.umlv.java.wallj.board.Board; | 6 | import fr.umlv.java.wallj.board.Board; |
7 | import fr.umlv.java.wallj.board.BoardConverter; | 7 | import fr.umlv.java.wallj.board.BoardConverter; |
8 | import fr.umlv.java.wallj.board.TileVec2; | 8 | import fr.umlv.java.wallj.board.TileVec2; |
9 | import fr.umlv.java.wallj.event.BlockCreateEvent; | 9 | import fr.umlv.java.wallj.event.*; |
10 | import fr.umlv.java.wallj.event.BlockDestroyEvent; | ||
11 | import fr.umlv.java.wallj.event.Event; | ||
12 | import fr.umlv.java.wallj.event.Events; | ||
13 | import org.jbox2d.common.Vec2; | 10 | import org.jbox2d.common.Vec2; |
14 | import org.jbox2d.dynamics.World; | 11 | import org.jbox2d.dynamics.World; |
15 | 12 | ||
@@ -27,6 +24,7 @@ public class Stage implements Updateable { | |||
27 | private final World world = new World(new Vec2()); | 24 | private final World world = new World(new Vec2()); |
28 | private final List<Block> blocks = new LinkedList<>(); | 25 | private final List<Block> blocks = new LinkedList<>(); |
29 | private final Board board; | 26 | private final Board board; |
27 | private boolean running = false; | ||
30 | 28 | ||
31 | /** | 29 | /** |
32 | * @param board the base board | 30 | * @param board the base board |
@@ -69,30 +67,38 @@ public class Stage implements Updateable { | |||
69 | } | 67 | } |
70 | 68 | ||
71 | /** | 69 | /** |
72 | * @return T(the physics simulation can start, i.e. the player has placed all their bombs) | ||
73 | */ | ||
74 | public boolean isReady() { | ||
75 | return blocks.stream() | ||
76 | .filter(block -> block.getType() == BlockType.BOMB) | ||
77 | .count() == BOMB_PLACEMENTS; | ||
78 | } | ||
79 | |||
80 | /** | ||
81 | * @param context the current context | 70 | * @param context the current context |
82 | * @return the stream of newly generated events | 71 | * @return the stream of newly generated events |
83 | */ | 72 | */ |
84 | @Override | 73 | @Override |
85 | public Stream<Event> update(Context context) { | 74 | public Stream<Event> update(Context context) { |
86 | return Updateables.updateAll(context, | 75 | return Updateables.updateAll(context, |
76 | this::handleSimulationStartOrder, | ||
77 | this::handleSimulationStartEvent, | ||
87 | this::updatePhysicalWorld, | 78 | this::updatePhysicalWorld, |
88 | this::handleBlockDestruction, | 79 | this::handleBlockDestruction, |
89 | this::handleBlockCreation, | 80 | this::handleBlockCreation, |
90 | ctx -> Updateables.updateAll(ctx, blocks)); | 81 | ctx -> Updateables.updateAll(ctx, blocks)); |
91 | } | 82 | } |
92 | 83 | ||
84 | private Stream<Event> handleSimulationStartOrder(Context context) { | ||
85 | return Events.findFirst(context.getEvents(), SimulationStartOrder.class) | ||
86 | .flatMap(order -> isReady() ? Optional.<Event>of(new SimulationStartEvent()) : Optional.empty()) | ||
87 | .map(Stream::of) // Optional.stream() only available in Java 9 | ||
88 | .orElseGet(Stream::empty); | ||
89 | } | ||
90 | |||
91 | private Stream<Event> handleSimulationStartEvent(Context context) { | ||
92 | Events.findFirst(context.getEvents(), SimulationStartEvent.class) | ||
93 | .ifPresent(startEvent -> running = true); | ||
94 | return Stream.empty(); | ||
95 | } | ||
96 | |||
93 | private Stream<Event> updatePhysicalWorld(Context context) { | 97 | private Stream<Event> updatePhysicalWorld(Context context) { |
94 | int dt = (int) context.getTimeDelta().toMillis(); | 98 | if (running) { |
95 | world.step(dt, dt * VELOCITY_TICK_PER_MS, dt * POSITION_TICK_PER_MS); | 99 | int dt = (int) context.getTimeDelta().toMillis(); |
100 | world.step(dt, dt * VELOCITY_TICK_PER_MS, dt * POSITION_TICK_PER_MS); | ||
101 | } | ||
96 | return Stream.empty(); | 102 | return Stream.empty(); |
97 | } | 103 | } |
98 | 104 | ||
@@ -112,6 +118,15 @@ public class Stage implements Updateable { | |||
112 | return Stream.empty(); | 118 | return Stream.empty(); |
113 | } | 119 | } |
114 | 120 | ||
121 | /** | ||
122 | * @implNote TODO: profile this and consider a bomb block counter | ||
123 | */ | ||
124 | private boolean isReady() { | ||
125 | return blocks.stream() | ||
126 | .filter(block -> block.getType() == BlockType.BOMB) | ||
127 | .count() == BOMB_PLACEMENTS; | ||
128 | } | ||
129 | |||
115 |