diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml
index 11e0b0117..5c3699dc2 100644
--- a/.github/workflows/documentation.yml
+++ b/.github/workflows/documentation.yml
@@ -14,16 +14,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Fetch source code
- uses: actions/checkout@v3.2.0
+ uses: actions/checkout@v4.2.2
- name: Set up JDK 21
- uses: actions/setup-java@v3.9.0
+ uses: actions/setup-java@v4.5.0
with:
distribution: 'zulu'
java-version: 21
- name: Cache Maven packages
- uses: actions/cache@v3.0.11
+ uses: actions/cache@v4.1.2
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 1afddd034..0f6bd02d7 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -14,16 +14,16 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- - uses: actions/checkout@v3.2.0
+ - uses: actions/checkout@v4.2.2
- name: Set up JDK 21
- uses: actions/setup-java@v3.9.0
+ uses: actions/setup-java@v4.5.0
with:
distribution: 'zulu'
java-version: 21
- name: Cache Maven packages
- uses: actions/cache@v3.0.11
+ uses: actions/cache@v4.1.2
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 69dae0b62..1365cd45a 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -17,10 +17,10 @@ jobs:
publish:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3.2.0
+ - uses: actions/checkout@v4.2.2
- name: Set up JDK 21
- uses: actions/setup-java@v3.9.0
+ uses: actions/setup-java@v4.5.0
with:
distribution: 'zulu'
java-version: 21
@@ -29,7 +29,7 @@ jobs:
server-password: MAVEN_CENTRAL_PASSWORD
- name: Cache Maven packages
- uses: actions/cache@v3.0.11
+ uses: actions/cache@v4.1.2
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
@@ -44,7 +44,7 @@ jobs:
run: xvfb-run mvn package -P release -Dgpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }}
- name: Set up Apache Maven Central
- uses: actions/setup-java@v3.9.0
+ uses: actions/setup-java@v4.5.0
with:
distribution: 'zulu'
java-version: 21
diff --git a/README.md b/README.md
index ca4d26b7d..12814fe36 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ Yaeger requires JDK21, and is available through the Maven Central Repository.
com.github.han-yaeger
yaeger
- 2023.2024
+ 2024.2025
```
diff --git a/architecture/class-overview.md b/architecture/class-overview.md
new file mode 100644
index 000000000..9c64798d6
--- /dev/null
+++ b/architecture/class-overview.md
@@ -0,0 +1,15 @@
+# A guide through Yaeger's internals
+
+After reading this guide, you should have a basic picture of how Yaeger's internals work. Not everything will be covered,
+but the basic setup should be clear and it should be possible to figure out how the missing parts work.
+
+## Introduction
+
+To get insight into how Yaeger is built, we will be using different views on its internals. We will base this on the game
+of Pac-Man.
+
+![Pac-Man](images/pacman.png)
+
+## Base classes for Scenes and Entities
+
+
diff --git a/architecture/images/pacman.png b/architecture/images/pacman.png
new file mode 100644
index 000000000..97ebca3a4
Binary files /dev/null and b/architecture/images/pacman.png differ
diff --git a/architecture/plantuml/classdiagrams/user-perspective-base.puml b/architecture/plantuml/classdiagrams/user-perspective-base.puml
new file mode 100644
index 000000000..0f8188217
--- /dev/null
+++ b/architecture/plantuml/classdiagrams/user-perspective-base.puml
@@ -0,0 +1,56 @@
+@startuml
+'https://plantuml.com/class-diagram
+
+class YaegerGame {
+ setupGame(): void
+ setupScenes(): void
+ addScene(int, YaegerScene): void
+}
+
+interface YaegerScene {
+ setupScene(): void
+ setupEntities(): void
+}
+
+abstract class StaticScene implements YaegerScene{
+ addEntity(YaegerEntity): void
+}
+
+abstract class DynamicScene extends StaticScene{
+}
+
+abstract class YaegerEntity {
+}
+
+abstract class CircleEntity extends YaegerEntity {
+}
+
+abstract class DynamicCircleEntity extends CircleEntity {
+}
+
+abstract class EllipseEntity extends YaegerEntity {
+}
+
+abstract class DynamicEllipseEntity extends EllipseEntity {
+}
+
+abstract class RectangleEntity extends YaegerEntity {
+}
+
+abstract class DynamicRectangleEntity extends RectangleEntity {
+}
+
+abstract class SpriteEntity extends YaegerEntity {
+}
+
+abstract class DynamicSpriteEntity extends SpriteEntity {
+}
+
+abstract class TextEntity extends YaegerEntity {
+}
+
+abstract class DynamicTextEntity extends TextEntity {
+}
+
+
+@enduml
\ No newline at end of file
diff --git a/architecture/plantuml/classdiagrams/user-perspective-tilemap.puml b/architecture/plantuml/classdiagrams/user-perspective-tilemap.puml
new file mode 100644
index 000000000..1390e26b5
--- /dev/null
+++ b/architecture/plantuml/classdiagrams/user-perspective-tilemap.puml
@@ -0,0 +1,36 @@
+@startuml
+'https://plantuml.com/class-diagram
+
+class YaegerGame {
+ setupGame(): void
+ setupScenes(): void
+ addScene(int, YaegerScene): void
+}
+
+interface YaegerScene {
+ setupScene(): void
+ setupEntities(): void
+}
+
+abstract class StaticScene implements YaegerScene{
+ addEntity(YaegerEntity): void
+}
+
+abstract class DynamicScene extends StaticScene{
+}
+
+abstract class YaegerEntity {
+}
+
+interface TileMapContainer {
+ setupTileMaps(): void
+ addTileMap(TileMap): void
+}
+
+abstract class TileMap{
+ setupEntities(): void
+ addEntity(int, Class extends YaegerEntity>): void
+}
+
+
+@enduml
\ No newline at end of file
diff --git a/docs/creating-entities.md b/docs/creating-entities.md
index 1d1b90281..08407e951 100644
--- a/docs/creating-entities.md
+++ b/docs/creating-entities.md
@@ -1,6 +1,6 @@
# Creating entities
-All available entities, expect the `TextEntity`, are abstract classes, meaning
+All available entities, except the `TextEntity`, are abstract classes, meaning
they should be extended to create an instance. After creating a class, an
instance should be created, which can then be added to a `YaegerScene`, or a
`CompositeEntity` through the `addEntity(YaegerEntity)` method.
diff --git a/docs/faq.md b/docs/faq.md
index 916afe9a3..ccba40a86 100644
--- a/docs/faq.md
+++ b/docs/faq.md
@@ -52,7 +52,8 @@ group them within their specific methods.
If you have a machine with Apple Silicon you might come across an error in the build process like this:
-![Error building because of libraries that cannot be linked](./images/00-mac-error.png)
+![Error building because of libraries that cannot be linked](images/00-mac-error.png)
+
To solve this you have to change the architecture of your JDK to one that is not specific to an ARM CPU.
diff --git a/docs/timing-things.md b/docs/timing-things.md
index fdc952994..389fd93b1 100644
--- a/docs/timing-things.md
+++ b/docs/timing-things.md
@@ -6,15 +6,22 @@ implementations of `YaegerScene` available: a `StaticScene` and a
contains a Game World Update (GWU) to which all instances of `DynamicEntity`
added to the scene will listen.
-This chapter will discuss the different ways in the GWU can be used within
+This chapter will discuss the different ways in which the GWU can be used within
Yaeger. It will start by discussing how the GWU gets delegated to all
-objects, after which different ways to use in within your scene of entity.
+objects, after which different ways are discussed to use it within your scene or
+entity.
## How the GWU is delegated to all objects
The GWU is initiated by the `DynamicScene`, and handed down to all dynamic
-entities that were added to the scene. This is done in the same order as in
-which they were added to the scene.
+entities, timers, spawners and composite entities that were added to the scene.
+This is done in the same order as in which they were added to the scene.
+
+From a programming point-of-view, the GWU is a timed method call. The
+`DynamicScene` calls its `update()` method, which then calls all the `update()`
+methods of all the dynamic entities, timers, spawners and composite entities. If
+those objects themself also contain child-objects, their `update()` method is
+then also called. And so forth.
![Update Delegation](images/update-delegation.png)
diff --git a/pom.xml b/pom.xml
index d1ef123a3..0c8f83560 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
com.github.han-yaeger
yaeger
- 2023.2024
+ 2024.2025
jar
@@ -15,7 +15,7 @@
UTF-8
21
- 21.0.1
+ 23.0.1
han-yaeger_yaeger
han-yaeger
https://sonarcloud.io
@@ -155,7 +155,7 @@
org.jacoco
jacoco-maven-plugin
- 0.8.10
+ 0.8.12
prepare-agent
@@ -165,13 +165,6 @@
-
-
- org.ow2.asm
- asm
- 9.5
-
-
com/github/hanyaeger/core/guice/**/*
@@ -217,6 +210,7 @@
+
org.openjfx
@@ -258,20 +252,27 @@
org.mockito
mockito-core
- 5.5.0
+ 5.13.0
test
org.testfx
testfx-core
- 4.0.16-alpha
+ 4.0.18
test
org.testfx
openjfx-monocle
- jdk-12.0.1+2
+ 21.0.2
test
+
+
+ com.google.guava
+ guava
+ 33.3.1-jre
+
diff --git a/release.md b/release.md
index 2263e60ee..73df5e93f 100644
--- a/release.md
+++ b/release.md
@@ -1,18 +1,17 @@
# Changes in this release
-## Configuration
-
-* Updated Mockito to 4.8.0
-* Updated jUnit to 5.9.1
-* Updated JavaFX to 19
+This release is mainly focussed on updated the dependencies and fixing bugs.
-## Refactor
-
-## Features
+## Configuration
-* Added a new animation system, in which parts of a sprite-sheet can be
- encapsulated by a Java-object. This will make it far easier to fully animate
- an entity (#239).
+* Updated Jacoco to 0.8.12
+* Updated JavaFX to 23.0.1
+* Updated testfx-code to 5.13.0
+* Updated openjfx-monocle to 21.0.2
+* Updated Guava to 33.3.1-jr so ensure Google Guice does not use the broken version
+* Updated Mockito to 5.13.0
## Bugfixes
+* Fixed two issues related to the bounding boxes in Composite Entities (#249, #268)
+* Fixed #265 (getSpeedInDirection with same direction returns 0 instead of actual speed). Thanks to @Liam-Rougoor.
diff --git a/src/main/java/com/github/hanyaeger/core/entities/Bounded.java b/src/main/java/com/github/hanyaeger/core/entities/Bounded.java
index 65bd3be11..55c819238 100644
--- a/src/main/java/com/github/hanyaeger/core/entities/Bounded.java
+++ b/src/main/java/com/github/hanyaeger/core/entities/Bounded.java
@@ -1,13 +1,11 @@
package com.github.hanyaeger.core.entities;
-import com.github.hanyaeger.api.Coordinate2D;
import com.github.hanyaeger.api.entities.CompositeEntity;
import com.github.hanyaeger.api.scenes.YaegerScene;
import com.github.hanyaeger.core.scenes.DimensionsProvider;
import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;
import javafx.scene.Node;
-import javafx.scene.layout.Pane;
/**
* Implementing this interface exposes the {@link Bounded#getBoundingBox()} and method, which returns the bounds, aka
@@ -25,14 +23,7 @@ public interface Bounded extends DimensionsProvider, GameNode {
* @return the {@link Bounds}
*/
default Bounds getBoundingBox() {
-
- return getNode().map(node -> {
- var newLocation = calculateLocation(node);
- return new BoundingBox(newLocation.getX(),
- newLocation.getY(),
- node.getBoundsInParent().getWidth(),
- node.getBoundsInParent().getHeight());
- }).orElse(new BoundingBox(0, 0, 0, 0));
+ return getNode().map(node -> node.localToScene(node.getLayoutBounds())).orElse(new BoundingBox(0, 0, 0, 0));
}
private Bounds getBounds() {
@@ -48,30 +39,4 @@ default double getWidth() {
default double getHeight() {
return getBounds().getHeight();
}
-
- /**
- * Since a {@link Node} can be either part of the {@link Pane}, or of a {@link javafx.scene.Group}, which itself
- * can also be part of the {@link Pane} or another {@link javafx.scene.Group}, which itself can be... , this
- * method recursively calculates ({@link #translateCoordinates(Node, Coordinate2D)} does the actual recursive work)
- * the coordinate of the {@link} projected on the {@link Pane}. This way it is
- * possible to use the {@link Node#intersects(Bounds)} method to perform collision detection.
- *
- * @param node that {@link Node} for which the coordinates need to be calculated
- * @return the {@link Coordinate2D} of the node, as projected on the {@link Pane}
- */
- private Coordinate2D calculateLocation(final Node node) {
- if (node == null) {
- return new Coordinate2D(10, 10);
- }
-
- return translateCoordinates(node, new Coordinate2D());
- }
-
- private Coordinate2D translateCoordinates(final Node node, final Coordinate2D translatedCoordinate) {
- if (node == null || node instanceof Pane) {
- return translatedCoordinate;
- } else {
- return translateCoordinates(node.getParent(), translatedCoordinate.add(new Coordinate2D(node.getBoundsInParent().getMinX(), node.getBoundsInParent().getMinY())));
- }
- }
}
diff --git a/src/main/java/com/github/hanyaeger/core/entities/motion/MotionApplier.java b/src/main/java/com/github/hanyaeger/core/entities/motion/MotionApplier.java
index 14d5b9ade..1457280b8 100644
--- a/src/main/java/com/github/hanyaeger/core/entities/motion/MotionApplier.java
+++ b/src/main/java/com/github/hanyaeger/core/entities/motion/MotionApplier.java
@@ -67,14 +67,14 @@ public double getSpeedInDirection(final Direction direction) {
@Override
public double getSpeedInDirection(final double direction) {
var calculatedSpeed = 0D;
- if (Double.compare(getDirection(), direction) != 0) {
- final var normalizedVector = createVector(1, direction);
- final var dotProduct = normalizedVector.dotProduct(motion);
- if (dotProduct > 0) {
- calculatedSpeed = calculateDenormalizedVector(normalizedVector, motion).magnitude();
- }
+ final var normalizedVector = createVector(1, direction);
+ final var dotProduct = normalizedVector.dotProduct(motion);
+
+ if (dotProduct > 0) {
+ calculatedSpeed = calculateDenormalizedVector(normalizedVector, motion).magnitude();
}
+
return calculatedSpeed;
}
diff --git a/src/main/java/com/github/hanyaeger/core/scenes/splash/SplashScene.java b/src/main/java/com/github/hanyaeger/core/scenes/splash/SplashScene.java
index 8980947ee..100fcbf4e 100644
--- a/src/main/java/com/github/hanyaeger/core/scenes/splash/SplashScene.java
+++ b/src/main/java/com/github/hanyaeger/core/scenes/splash/SplashScene.java
@@ -31,7 +31,7 @@ public class SplashScene extends DynamicScene implements TimerContainer {
public void setupScene() {
setBrightness(-1);
setBackgroundImage("yaegerimages/splash-bg.jpg");
- var splashSound = new SoundClip("yaegersounds/yaeger.mp3");
+ var splashSound = new SoundClip("yaegersounds/yaeger.wav");
splashSound.play();
}
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index ab945e066..4a624ec88 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -37,4 +37,5 @@
exports com.github.hanyaeger.core.media to com.google.guice;
opens yaegerimages;
+ opens yaegersounds;
}
diff --git a/src/main/resources/yaegersounds/yaeger.mp3 b/src/main/resources/yaegersounds/yaeger.mp3
deleted file mode 100644
index 216cb6fde..000000000
Binary files a/src/main/resources/yaegersounds/yaeger.mp3 and /dev/null differ
diff --git a/src/main/resources/yaegersounds/yaeger.wav b/src/main/resources/yaegersounds/yaeger.wav
new file mode 100644
index 000000000..4189e4a70
Binary files /dev/null and b/src/main/resources/yaegersounds/yaeger.wav differ
diff --git a/src/test/java/com/github/hanyaeger/api/entities/SceneBorderCrossingWatcherTest.java b/src/test/java/com/github/hanyaeger/api/entities/SceneBorderCrossingWatcherTest.java
index b93c46852..f6d228368 100644
--- a/src/test/java/com/github/hanyaeger/api/entities/SceneBorderCrossingWatcherTest.java
+++ b/src/test/java/com/github/hanyaeger/api/entities/SceneBorderCrossingWatcherTest.java
@@ -7,7 +7,6 @@
import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;
import javafx.scene.Node;
-import javafx.scene.Scene;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -18,13 +17,14 @@
class SceneBorderCrossingWatcherTest {
- private final static double SCENE_HEIGHT = 100;
- private final static double SCENE_WIDTH = 100;
- private final static BoundingBox BOUNDS_IN_PARENT = new BoundingBox(10, 10, 10, 10);
- private final static BoundingBox BOUNDS_CROSSED_LEFT = new BoundingBox(-20, 10, 10, 10);
- private final static BoundingBox BOUNDS_CROSSED_RIGHT = new BoundingBox(110, 10, 10, 10);
- private final static BoundingBox BOUNDS_CROSSED_BOTTOM = new BoundingBox(10, 100, 10, 10);
- private final static BoundingBox BOUNDS_CROSSED_TOP = new BoundingBox(10, -20, 10, 10);
+ private static final double SCENE_HEIGHT = 100;
+ private static final double SCENE_WIDTH = 100;
+
+ private static final BoundingBox BOUNDS_IN_PARENT = new BoundingBox(10, 10, 10, 10);
+ private static final BoundingBox BOUNDS_CROSSED_LEFT = new BoundingBox(-20, 10, 10, 10);
+ private static final BoundingBox BOUNDS_CROSSED_RIGHT = new BoundingBox(110, 10, 10, 10);
+ private static final BoundingBox BOUNDS_CROSSED_BOTTOM = new BoundingBox(10, 100, 10, 10);
+ private static final BoundingBox BOUNDS_CROSSED_TOP = new BoundingBox(10, -20, 10, 10);
private SceneBorderCrossingWatcherImpl sut;
private Node node;
private MotionApplier motionApplier;
@@ -55,7 +55,8 @@ void testWatchForBoundaryCrossingReturnsAnUpdatable() {
@Test
void testBoundaryNotCrossed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_IN_PARENT);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_IN_PARENT);
+ when(node.localToScene(BOUNDS_IN_PARENT)).thenReturn(BOUNDS_IN_PARENT);
var updatable = sut.watchForBoundaryCrossing();
@@ -69,7 +70,8 @@ void testBoundaryNotCrossed() {
@Test
void testBoundaryLeftCrossedWithZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_LEFT);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_LEFT);
+ when(node.localToScene(BOUNDS_CROSSED_LEFT)).thenReturn(BOUNDS_CROSSED_LEFT);
when(motionApplier.getSpeed()).thenReturn(0d);
var updatable = sut.watchForBoundaryCrossing();
@@ -84,7 +86,8 @@ void testBoundaryLeftCrossedWithZeroSpeed() {
@Test
void testBoundaryLeftCrossedWithNonZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_LEFT);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_LEFT);
+ when(node.localToScene(BOUNDS_CROSSED_LEFT)).thenReturn(BOUNDS_CROSSED_LEFT);
when(motionApplier.getSpeed()).thenReturn(1d);
var updatable = sut.watchForBoundaryCrossing();
@@ -99,7 +102,8 @@ void testBoundaryLeftCrossedWithNonZeroSpeed() {
@Test
void testBoundaryRightCrossedWithZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_RIGHT);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_RIGHT);
+ when(node.localToScene(BOUNDS_CROSSED_RIGHT)).thenReturn(BOUNDS_CROSSED_RIGHT);
when(motionApplier.getSpeed()).thenReturn(0d);
var updatable = sut.watchForBoundaryCrossing();
@@ -114,7 +118,8 @@ void testBoundaryRightCrossedWithZeroSpeed() {
@Test
void testBoundaryRightCrossedWithNonZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_RIGHT);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_RIGHT);
+ when(node.localToScene(BOUNDS_CROSSED_RIGHT)).thenReturn(BOUNDS_CROSSED_RIGHT);
when(motionApplier.getSpeed()).thenReturn(1d);
var updatable = sut.watchForBoundaryCrossing();
@@ -129,7 +134,8 @@ void testBoundaryRightCrossedWithNonZeroSpeed() {
@Test
void testBoundaryBottomCrossedWithZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_BOTTOM);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_BOTTOM);
+ when(node.localToScene(BOUNDS_CROSSED_BOTTOM)).thenReturn(BOUNDS_CROSSED_BOTTOM);
when(motionApplier.getSpeed()).thenReturn(0d);
var updatable = sut.watchForBoundaryCrossing();
@@ -144,7 +150,8 @@ void testBoundaryBottomCrossedWithZeroSpeed() {
@Test
void testBoundaryBottomCrossedWithNonZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_BOTTOM);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_BOTTOM);
+ when(node.localToScene(BOUNDS_CROSSED_BOTTOM)).thenReturn(BOUNDS_CROSSED_BOTTOM);
when(motionApplier.getSpeed()).thenReturn(1d);
var updatable = sut.watchForBoundaryCrossing();
@@ -159,7 +166,8 @@ void testBoundaryBottomCrossedWithNonZeroSpeed() {
@Test
void testBoundaryTopCrossedWithZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_TOP);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_TOP);
+ when(node.localToScene(BOUNDS_CROSSED_TOP)).thenReturn(BOUNDS_CROSSED_TOP);
when(motionApplier.getSpeed()).thenReturn(0d);
var updatable = sut.watchForBoundaryCrossing();
@@ -174,7 +182,8 @@ void testBoundaryTopCrossedWithZeroSpeed() {
@Test
void testBoundaryTopCrossedWithNonZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_TOP);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_TOP);
+ when(node.localToScene(BOUNDS_CROSSED_TOP)).thenReturn(BOUNDS_CROSSED_TOP);
when(motionApplier.getSpeed()).thenReturn(1d);
var updatable = sut.watchForBoundaryCrossing();
diff --git a/src/test/java/com/github/hanyaeger/api/entities/SceneBorderTouchingWatcherTest.java b/src/test/java/com/github/hanyaeger/api/entities/SceneBorderTouchingWatcherTest.java
index 68730f834..e1ce2e78d 100644
--- a/src/test/java/com/github/hanyaeger/api/entities/SceneBorderTouchingWatcherTest.java
+++ b/src/test/java/com/github/hanyaeger/api/entities/SceneBorderTouchingWatcherTest.java
@@ -5,9 +5,7 @@
import com.github.hanyaeger.core.entities.motion.MotionApplier;
import com.github.hanyaeger.api.scenes.SceneBorder;
import javafx.geometry.BoundingBox;
-import javafx.geometry.Bounds;
import javafx.scene.Node;
-import javafx.scene.Scene;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -19,13 +17,13 @@
class SceneBorderTouchingWatcherTest {
- private final static double SCENE_HEIGHT = 100;
- private final static double SCENE_WIDTH = 100;
- private final static BoundingBox BOUNDS_IN_PARENT = new BoundingBox(10, 10, 10, 10);
- private final static BoundingBox BOUNDS_CROSSED_LEFT = new BoundingBox(-20, 10, 10, 10);
- private final static BoundingBox BOUNDS_CROSSED_RIGHT = new BoundingBox(110, 10, 10, 10);
- private final static BoundingBox BOUNDS_CROSSED_BOTTOM = new BoundingBox(10, 100, 10, 10);
- private final static BoundingBox BOUNDS_CROSSED_TOP = new BoundingBox(10, -20, 10, 10);
+ private static final double SCENE_HEIGHT = 100;
+ private static final double SCENE_WIDTH = 100;
+ private static final BoundingBox BOUNDS_IN_PARENT = new BoundingBox(10, 10, 10, 10);
+ private static final BoundingBox BOUNDS_CROSSED_LEFT = new BoundingBox(-20, 10, 10, 10);
+ private static final BoundingBox BOUNDS_CROSSED_RIGHT = new BoundingBox(110, 10, 10, 10);
+ private static final BoundingBox BOUNDS_CROSSED_BOTTOM = new BoundingBox(10, 100, 10, 10);
+ private static final BoundingBox BOUNDS_CROSSED_TOP = new BoundingBox(10, -20, 10, 10);
private SceneBorderTouchingWatcherImpl sut;
private Node node;
private MotionApplier motionApplier;
@@ -56,7 +54,8 @@ void testWatchForBoundaryTouchingReturnsAnUpdatable() {
@Test
void testBoundaryNotTouched() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_IN_PARENT);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_IN_PARENT);
+ when(node.localToScene(BOUNDS_IN_PARENT)).thenReturn(BOUNDS_IN_PARENT);
var updatable = sut.watchForBoundaryTouching();
// Act
@@ -84,7 +83,8 @@ void testBoundaryLeftCrossedWithZeroSpeed() {
@Test
void testBoundaryLeftCrossedWithNonZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_LEFT);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_LEFT);
+ when(node.localToScene(BOUNDS_CROSSED_LEFT)).thenReturn(BOUNDS_CROSSED_LEFT);
when(motionApplier.getSpeed()).thenReturn(1d);
var updatable = sut.watchForBoundaryTouching();
@@ -99,7 +99,8 @@ void testBoundaryLeftCrossedWithNonZeroSpeed() {
@Test
void testBoundaryRightCrossedWithZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_RIGHT);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_RIGHT);
+ when(node.localToScene(BOUNDS_CROSSED_RIGHT)).thenReturn(BOUNDS_CROSSED_RIGHT);
when(motionApplier.getSpeed()).thenReturn(0d);
var updatable = sut.watchForBoundaryTouching();
@@ -114,7 +115,8 @@ void testBoundaryRightCrossedWithZeroSpeed() {
@Test
void testBoundaryRightCrossedWithNonZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_RIGHT);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_RIGHT);
+ when(node.localToScene(BOUNDS_CROSSED_RIGHT)).thenReturn(BOUNDS_CROSSED_RIGHT);
when(motionApplier.getSpeed()).thenReturn(1d);
var updatable = sut.watchForBoundaryTouching();
@@ -129,7 +131,8 @@ void testBoundaryRightCrossedWithNonZeroSpeed() {
@Test
void testBoundaryBottomTouchedWithZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_BOTTOM);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_BOTTOM);
+ when(node.localToScene(BOUNDS_CROSSED_BOTTOM)).thenReturn(BOUNDS_CROSSED_BOTTOM);
when(motionApplier.getSpeed()).thenReturn(0d);
var updatable = sut.watchForBoundaryTouching();
@@ -144,7 +147,8 @@ void testBoundaryBottomTouchedWithZeroSpeed() {
@Test
void testBoundaryBottomTouchedWithNonZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_BOTTOM);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_BOTTOM);
+ when(node.localToScene(BOUNDS_CROSSED_BOTTOM)).thenReturn(BOUNDS_CROSSED_BOTTOM);
when(motionApplier.getSpeed()).thenReturn(1d);
var updatable = sut.watchForBoundaryTouching();
@@ -159,7 +163,8 @@ void testBoundaryBottomTouchedWithNonZeroSpeed() {
@Test
void testBoundaryTopTouchedWithZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_TOP);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_TOP);
+ when(node.localToScene(BOUNDS_CROSSED_TOP)).thenReturn(BOUNDS_CROSSED_TOP);
when(motionApplier.getSpeed()).thenReturn(0d);
var updatable = sut.watchForBoundaryTouching();
@@ -174,7 +179,8 @@ void testBoundaryTopTouchedWithZeroSpeed() {
@Test
void testBoundaryTopTouchedWithNonZeroSpeed() {
// Arrange
- when(node.getBoundsInParent()).thenReturn(BOUNDS_CROSSED_TOP);
+ when(node.getLayoutBounds()).thenReturn(BOUNDS_CROSSED_TOP);
+ when(node.localToScene(BOUNDS_CROSSED_TOP)).thenReturn(BOUNDS_CROSSED_TOP);
when(motionApplier.getSpeed()).thenReturn(1d);
var updatable = sut.watchForBoundaryTouching();
diff --git a/src/test/java/com/github/hanyaeger/core/entities/BoundedTest.java b/src/test/java/com/github/hanyaeger/core/entities/BoundedTest.java
index 25d1b0824..7a82f689a 100644
--- a/src/test/java/com/github/hanyaeger/core/entities/BoundedTest.java
+++ b/src/test/java/com/github/hanyaeger/core/entities/BoundedTest.java
@@ -66,7 +66,7 @@ void getBoundingBoxDelegatesToGameNodeIfPresent() {
sut.getBoundingBox();
// Assert
- Mockito.verify(node, times(4)).getBoundsInParent();
+ Mockito.verify(node).getLayoutBounds();
}
@Test
@@ -96,7 +96,7 @@ void getHeightReturnValueFromBounds() {
}
@Test
- void getBoundingBoxReturnsMinimalBoxOnDefaultLocationIfNodeIsNull(){
+ void getBoundingBoxReturnsMinimalBoxOnDefaultLocationIfNodeIsNull() {
// Arrange
var emptySut = new EmptyGameNodeBoundedImpl();
diff --git a/src/test/java/com/github/hanyaeger/core/entities/motion/MotionApplierTest.java b/src/test/java/com/github/hanyaeger/core/entities/motion/MotionApplierTest.java
index e16469acd..4090b3e08 100644
--- a/src/test/java/com/github/hanyaeger/core/entities/motion/MotionApplierTest.java
+++ b/src/test/java/com/github/hanyaeger/core/entities/motion/MotionApplierTest.java
@@ -5,6 +5,8 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
import static org.junit.jupiter.api.Assertions.*;
@@ -209,14 +211,14 @@ void alterSpeedWithNegativeValueDecrementsSpeedTest() {
@Test
void getSpeedReturnsCorrectValueTest() {
// Arrange
- var SPEED = 3.7;
- sut.setMotion(SPEED, Direction.UP.getValue());
+ var expected = 3.7;
+ sut.setMotion(expected, Direction.UP.getValue());
// Act
var speed = sut.getSpeed();
// Assert
- assertEquals(SPEED, speed, DELTA);
+ assertEquals(expected, speed, DELTA);
}
@Test
@@ -235,14 +237,14 @@ void setDirectionRIGHTForSpeedOneCreatesRightVectorTest() {
@Test
void setDirectionToUPForSpeedOneCreatesUpVectorTest() {
// Arrange
- sut.setSpeed(1);
+ sut.setSpeed(2);
// Act
sut.setDirection(Direction.UP);
// Assert
assertEquals(0, sut.get().getX(), DELTA);
- assertEquals(-1, sut.get().getY(), DELTA);
+ assertEquals(-2, sut.get().getY(), DELTA);
}
@Test
@@ -327,14 +329,14 @@ void resetSpeedAfterSpeedHasBeenSetToZeroCreatesCorrectVectorTest() {
@Test
void getDirectionForDirectionBelow180TestReturnsCorrectValue() {
// Arrange
- final double DIRECTION = 42;
- sut.setMotion(1, DIRECTION);
+ final double expected = 42;
+ sut.setMotion(1, expected);
// Act
- var direction = sut.getDirection();
+ var actual = sut.getDirection();
// Assert
- assertEquals(DIRECTION, direction, DELTA);
+ assertEquals(expected, actual, DELTA);
}
@Test
@@ -364,14 +366,14 @@ void getDirectionsReturnsNumericValueWhenEnumIsForDirectionWasUsedInMotionTest()
@Test
void getDirectionForDirectionAbove180ReturnsCorrectValueTest() {
// Arrange
- final double DIRECTION = 189;
- sut.setMotion(1, DIRECTION);
+ final double expected = 189;
+ sut.setMotion(1, expected);
// Act
- var direction = sut.getDirection();
+ var actual = sut.getDirection();
// Assert
- assertEquals(DIRECTION, direction, DELTA);
+ assertEquals(expected, actual, DELTA);
}
@Test
@@ -390,7 +392,7 @@ void getDirectionAfterSpeedSetTo0ReturnsCorrectDirection(){
@Test
void changeDirectionWithZeroDoesNotChangeAngleTest() {
// Arrange
- sut.setMotion(1, Direction.DOWN.getValue());
+ sut.setMotion(2, Direction.DOWN.getValue());
// Act
sut.changeDirection(0);
@@ -743,6 +745,20 @@ void nullifySpeedInZeroDirectionDoesNotResultInNaNTest() {
@Nested
class GetSpeedInDirectionTests {
+ @ParameterizedTest
+ @EnumSource(Direction.class)
+ void getSpeedInExactDirectionGivesSpeedTest(Direction direction){
+ // Arrange
+ var speed = 3.7;
+
+ // Act
+ sut.setMotion(speed, direction);
+ var speedInDirection = sut.getSpeedInDirection(direction);
+
+ // Assert
+ assertEquals(3.7, speedInDirection, DELTA);
+ }
+
@Test
void getSpeedInOppositeDirectionGives0Test() {
// Arrange
diff --git a/src/test/java/com/github/hanyaeger/core/scenes/delegates/BackgroundDelegateTest.java b/src/test/java/com/github/hanyaeger/core/scenes/delegates/BackgroundDelegateTest.java
index b2615dfa0..86561baeb 100644
--- a/src/test/java/com/github/hanyaeger/core/scenes/delegates/BackgroundDelegateTest.java
+++ b/src/test/java/com/github/hanyaeger/core/scenes/delegates/BackgroundDelegateTest.java
@@ -7,18 +7,18 @@
import javafx.scene.layout.Background;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;
class BackgroundDelegateTest {
private static final String URL_AUDIO = "audio/testaudio.mp3";
- private static final String URL_AUDIO_2 = "audio/testaudio2.mp3";
private static final String URL_IMAGE = "testImage.png";
private BackgroundDelegate sut;
private BackgroundFactory backgroundFactory;
@@ -62,7 +62,7 @@ void getVolumeReturns0() {
var actual = sut.getVolume();
// Assert
- Assertions.assertEquals(expected, actual);
+ assertEquals(expected, actual);
}
}
@@ -133,7 +133,7 @@ void getVolumeDelegatesToBackgroundAudioPlayer() {
var actual = sut.getVolume();
// Assert
- Assertions.assertEquals(expected, actual);
+ assertEquals(expected, actual);
}
}
@@ -166,7 +166,7 @@ void setBackgroundColorWithNullPaneDoesNotBreak() {
var color = Color.YELLOW;
// Act & Assert
- Assertions.assertAll(() -> paneIsNullSut.setBackgroundColor(color));
+ assertAll(() -> paneIsNullSut.setBackgroundColor(color));
}
@Test