diff options
Diffstat (limited to 'src/main/java/fr/umlv/java/wallj/block/RobotBlock.java')
-rw-r--r-- | src/main/java/fr/umlv/java/wallj/block/RobotBlock.java | 73 |
1 files changed, 40 insertions, 33 deletions
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 f81f423..11cf25f 100644 --- a/src/main/java/fr/umlv/java/wallj/block/RobotBlock.java +++ b/src/main/java/fr/umlv/java/wallj/block/RobotBlock.java | |||
@@ -4,17 +4,16 @@ import fr.umlv.java.wallj.board.Board; | |||
4 | import fr.umlv.java.wallj.board.PathFinder; | 4 | import fr.umlv.java.wallj.board.PathFinder; |
5 | import fr.umlv.java.wallj.board.TileVec2; | 5 | import fr.umlv.java.wallj.board.TileVec2; |
6 | import fr.umlv.java.wallj.context.Context; | 6 | import fr.umlv.java.wallj.context.Context; |
7 | import fr.umlv.java.wallj.context.GraphicsContext; | ||
8 | import fr.umlv.java.wallj.context.Stage; | 7 | import fr.umlv.java.wallj.context.Stage; |
8 | import fr.umlv.java.wallj.context.Updateables; | ||
9 | import fr.umlv.java.wallj.event.*; | 9 | import fr.umlv.java.wallj.event.*; |
10 | import fr.umlv.java.wallj.event.Event; | 10 | import fr.umlv.java.wallj.event.Event; |
11 | import org.jbox2d.common.Vec2; | 11 | import org.jbox2d.common.Vec2; |
12 | import org.jbox2d.dynamics.World; | 12 | import org.jbox2d.dynamics.World; |
13 | 13 | ||
14 | import java.awt.*; | 14 | import java.awt.*; |
15 | import java.time.Duration; | ||
16 | import java.util.*; | 15 | import java.util.*; |
17 | import java.util.List; | 16 | import java.util.stream.Stream; |
18 | 17 | ||
19 | /** | 18 | /** |
20 | * A robot block. | 19 | * A robot block. |
@@ -50,47 +49,55 @@ public class RobotBlock extends Block { | |||
50 | } | 49 | } |
51 | 50 | ||
52 | @Override | 51 | @Override |
53 | public List<Event> update(Context context) { | 52 | public Stream<Event> update(Context context) { |
54 | Events.findFirst(context.getEvents(), MoveRobotOrder.class) | 53 | return Updateables.updateAll(context, |
55 | .ifPresent(event -> updatePath(context.getGame().getCurrentStage().getBoard(), event.getTarget())); | 54 | this::updatePath, |
56 | 55 | this::move, | |
57 | move(context.getTimeDelta()); | 56 | this::paint, |
58 | paint(context.getGraphicsContext()); | 57 | this::setupBomb); |
59 | return setupBomb(context.getEvents(), context.getGame().getCurrentStage()); | ||
60 | } | 58 | } |
61 | 59 | ||
62 | private List<Event> setupBomb(List<Event> events, Stage stage) { | 60 | private Stream<Event> setupBomb(Context context) { |
63 | return Events.findFirst(events, BombSetupOrder.class) | 61 | return Events.findFirst(context.getEvents(), BombSetupOrder.class) |
64 | .map(event -> isOnBomb(stage) ? | 62 | .flatMap(event -> isOnBomb(context.getGame().getCurrentStage()) ? |
65 | Collections.<Event>singletonList(new BombTimerIncrEvent(getTile())) : | 63 | Optional.of(new BombTimerIncrEvent(getTile())) : |
66 | dropBomb(event)) | 64 | dropBomb()) |
67 | .orElse(Collections.emptyList()); | 65 | .map(Stream::of) // Optional.stream() only available in Java 9 |
66 | .orElseGet(Stream::empty); | ||
68 | } | 67 | } |
69 | 68 | ||
70 | private List<Event> dropBomb(BombSetupOrder order) { | 69 | private Optional<Event> dropBomb() { |
71 | if (droppedBombCount >= Stage.BOMB_PLACEMENTS) return Collections.emptyList(); | 70 | if (droppedBombCount >= Stage.BOMB_PLACEMENTS) return Optional.empty(); |
72 | |||
73 | droppedBombCount++; | 71 | droppedBombCount++; |
74 | return Collections.singletonList(new BlockCreateEvent(BlockType.BOMB, getTile())); | 72 | return Optional.of(new BlockCreateEvent(BlockType.BOMB, getTile())); |
75 | } | 73 | } |
76 | 74 | ||
77 | private void updatePath(Board board, TileVec2 target) { | 75 | private Stream<Event> updatePath(Context context) { |
78 | if (!board.inside(target) || !board.getBlockTypeAt(target).isTraversable()) return; | 76 | Events.findFirst(context.getEvents(), MoveRobotOrder.class) |
79 | if (pathFinder == null) pathFinder = new PathFinder(board); | 77 | .ifPresent(event -> { |
80 | path = new LinkedList<>(pathFinder.findPath(TileVec2.of(pos), target)); | 78 | Board board = context.getGame().getCurrentStage().getBoard(); |
79 | TileVec2 target = event.getTarget(); | ||
80 | if (!board.inside(target) || !board.getBlockTypeAt(target).isTraversable()) return; | ||
81 | if (pathFinder == null) pathFinder = new PathFinder(board); | ||
82 | path = new LinkedList<>(pathFinder.findPath(TileVec2.of(pos), target)); | ||
83 | }); | ||
84 | return Stream.empty(); | ||
81 | } | 85 | } |
82 | 86 | ||
83 | private void move(Duration timeDelta) { | 87 | private Stream<Event> move(Context context) { |
84 | if (path.isEmpty()) return; | 88 | if (!path.isEmpty()) { |
85 | Vec2 dest = path.getFirst().toVec2(); | 89 | Vec2 dest = path.getFirst().toVec2(); |
86 | Vec2 dir = dest.sub(pos); | 90 | Vec2 dir = dest.sub(pos); |
87 | float dist = dir.normalize(); | 91 | float dist = dir.normalize(); |
88 | Vec2 dp = dir.mul(timeDelta.toMillis() * SPEED); | 92 | Vec2 dp = dir.mul(context.getTimeDelta().toMillis() * SPEED); |
89 | pos = dp.length() < dist ? pos.add(dp) : path.removeFirst().toVec2(); | 93 | pos = dp.length() < dist ? pos.add(dp) : path.removeFirst().toVec2(); |
94 | } | ||
95 | return Stream.empty(); | ||
90 | } | 96 | } |
91 | 97 | ||
92 | private void paint(GraphicsContext graphicsContext) { | 98 | private Stream<Event> paint(Context context) { |
93 | graphicsContext.paintCircle(Color.BLUE, getPos(), TileVec2.TILE_DIM / 2); | 99 | context.getGraphicsContext().paintCircle(Color.BLUE, getPos(), TileVec2.TILE_DIM / 2); |
100 | return Stream.empty(); | ||
94 | } | 101 | } |
95 | 102 | ||
96 | /** | 103 | /** |