Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05c57efc52 | ||
|
|
3c45ca9de8 | ||
|
|
117589b17b | ||
|
|
bca92faa88 | ||
|
|
4febf41721 | ||
|
|
8082817860 | ||
|
|
21513f69ed | ||
|
|
87389e78eb | ||
|
|
73228ed05a | ||
|
|
b39b2f1d10 |
@@ -26,3 +26,5 @@ buildNumber.properties
|
|||||||
.factorypath
|
.factorypath
|
||||||
.project
|
.project
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
|
*.jar
|
||||||
|
|||||||
+9
-9
@@ -19,8 +19,8 @@
|
|||||||
<!-- JaCoCo thresholds. Increase gradually as you add tests. -->
|
<!-- JaCoCo thresholds. Increase gradually as you add tests. -->
|
||||||
<jacoco.unit-tests.limit.instruction-ratio>0%</jacoco.unit-tests.limit.instruction-ratio>
|
<jacoco.unit-tests.limit.instruction-ratio>0%</jacoco.unit-tests.limit.instruction-ratio>
|
||||||
<jacoco.unit-tests.limit.branch-ratio>0%</jacoco.unit-tests.limit.branch-ratio>
|
<jacoco.unit-tests.limit.branch-ratio>0%</jacoco.unit-tests.limit.branch-ratio>
|
||||||
<jacoco.unit-tests.limit.class-complexity>20</jacoco.unit-tests.limit.class-complexity>
|
<jacoco.unit-tests.limit.class-complexity>2100</jacoco.unit-tests.limit.class-complexity>
|
||||||
<jacoco.unit-tests.limit.method-complexity>5</jacoco.unit-tests.limit.method-complexity>
|
<jacoco.unit-tests.limit.method-complexity>1000</jacoco.unit-tests.limit.method-complexity>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -38,12 +38,12 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>nz.ac.massey.javaecs</groupId>
|
<groupId>nz.ac.massey.javaecs</groupId>
|
||||||
<artifactId>javaecs</artifactId>
|
<artifactId>javaecs</artifactId>
|
||||||
<version>0.9.2-PRERELEASE</version>
|
<version>1.0.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<!-- <plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-enforcer-plugin</artifactId>
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
<version>${maven-enforcer-plugin.version}</version>
|
<version>${maven-enforcer-plugin.version}</version>
|
||||||
@@ -93,8 +93,8 @@
|
|||||||
</goals>
|
</goals>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin> -->
|
||||||
<plugin>
|
<!--<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<version>${maven-surefire-plugin.version}</version>
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
@@ -165,7 +165,7 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin> -->
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<reporting>
|
<reporting>
|
||||||
@@ -179,7 +179,7 @@
|
|||||||
</reporting>
|
</reporting>
|
||||||
<profiles>
|
<profiles>
|
||||||
<!-- Publish coverage report to Coveralls, only when running in Travis. -->
|
<!-- Publish coverage report to Coveralls, only when running in Travis. -->
|
||||||
<profile>
|
<!-- <profile>
|
||||||
<id>travis</id>
|
<id>travis</id>
|
||||||
<activation>
|
<activation>
|
||||||
<property>
|
<property>
|
||||||
@@ -195,6 +195,6 @@
|
|||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile> -->
|
||||||
</profiles>
|
</profiles>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package nz.ac.massey.javaecs.examples;
|
package nz.ac.massey.javaecs.examples;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import nz.ac.massey.javaecs.*;
|
import nz.ac.massey.javaecs.*;
|
||||||
@@ -14,6 +15,8 @@ public final class App {
|
|||||||
private App() {
|
private App() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Semaphore rendererReadySemaphore = new Semaphore(0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple physics simulation.
|
* Simple physics simulation.
|
||||||
* @param args The arguments of the program.
|
* @param args The arguments of the program.
|
||||||
@@ -52,7 +55,7 @@ public final class App {
|
|||||||
LogUpdateSystem logUpdateSystem = new LogUpdateSystem(gameEngine);
|
LogUpdateSystem logUpdateSystem = new LogUpdateSystem(gameEngine);
|
||||||
gameEngine.registerSystem(LogUpdateSystem.class, logUpdateSystem);
|
gameEngine.registerSystem(LogUpdateSystem.class, logUpdateSystem);
|
||||||
|
|
||||||
RenderSystem renderSystem = new RenderSystem(gameEngine, 10.);
|
RenderSystem renderSystem = new RenderSystem(gameEngine, 5.);
|
||||||
gameEngine.registerSystem(RenderSystem.class, renderSystem);
|
gameEngine.registerSystem(RenderSystem.class, renderSystem);
|
||||||
|
|
||||||
ExistenceSystem existenceSystem = new ExistenceSystem(gameEngine);
|
ExistenceSystem existenceSystem = new ExistenceSystem(gameEngine);
|
||||||
@@ -70,28 +73,28 @@ public final class App {
|
|||||||
// Bottom boundary
|
// Bottom boundary
|
||||||
Entity newEnt = gameEngine.createEntity();
|
Entity newEnt = gameEngine.createEntity();
|
||||||
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(-50., -50.,0));
|
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(-50., -50.,0));
|
||||||
gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(0., 0., 0., 0., 0.f, 0., -1.));
|
gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(0., 0., 0., 0., 0.f, 0.25, -1.));
|
||||||
gameEngine.addComponent(newEnt, Collider.class, new Collider(200., 50.)); // 200 along, 50 up
|
gameEngine.addComponent(newEnt, Collider.class, new Collider(200., 50.)); // 200 along, 50 up
|
||||||
gameEngine.addComponent(newEnt, Render.class, new Render(BoxRender.class));
|
gameEngine.addComponent(newEnt, Render.class, new Render(BoxRender.class));
|
||||||
gameEngine.addComponent(newEnt, BoxRender.class, new BoxRender(200, 50, 64, 64, 64));
|
gameEngine.addComponent(newEnt, BoxRender.class, new BoxRender(200, 50, 64, 64, 64));
|
||||||
// Left boundary
|
// Left boundary
|
||||||
newEnt = gameEngine.createEntity();
|
newEnt = gameEngine.createEntity();
|
||||||
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(-50., -50.,0));
|
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(-50., -50.,0));
|
||||||
gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(0., 0., 0., 0., 0.f, 0., -1.));
|
gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(0., 0., 0., 0., 0.f, 0.25, -1.));
|
||||||
gameEngine.addComponent(newEnt, Collider.class, new Collider(50., 200.));
|
gameEngine.addComponent(newEnt, Collider.class, new Collider(50., 200.));
|
||||||
gameEngine.addComponent(newEnt, Render.class, new Render(BoxRender.class));
|
gameEngine.addComponent(newEnt, Render.class, new Render(BoxRender.class));
|
||||||
gameEngine.addComponent(newEnt, BoxRender.class, new BoxRender(50, 200, 64, 64, 64));
|
gameEngine.addComponent(newEnt, BoxRender.class, new BoxRender(50, 200, 64, 64, 64));
|
||||||
// Top boundary
|
// Top boundary
|
||||||
newEnt = gameEngine.createEntity();
|
newEnt = gameEngine.createEntity();
|
||||||
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(-50., 100.,0));
|
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(-50., 100.,0));
|
||||||
gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(0., 0., 0., 0., 0.f, 0., -1.));
|
gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(0., 0., 0., 0., 0.f, 0.25, -1.));
|
||||||
gameEngine.addComponent(newEnt, Collider.class, new Collider(200., 50.));
|
gameEngine.addComponent(newEnt, Collider.class, new Collider(200., 50.));
|
||||||
gameEngine.addComponent(newEnt, Render.class, new Render(BoxRender.class));
|
gameEngine.addComponent(newEnt, Render.class, new Render(BoxRender.class));
|
||||||
gameEngine.addComponent(newEnt, BoxRender.class, new BoxRender(200, 50, 64, 64, 64));
|
gameEngine.addComponent(newEnt, BoxRender.class, new BoxRender(200, 50, 64, 64, 64));
|
||||||
// Right boundary
|
// Right boundary
|
||||||
newEnt = gameEngine.createEntity();
|
newEnt = gameEngine.createEntity();
|
||||||
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(100., -50.,0));
|
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(100., -50.,0));
|
||||||
gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(0., 0., 0., 0., 0.f, 0., -1.));
|
gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(0., 0., 0., 0., 0.f, 0.25, -1.));
|
||||||
gameEngine.addComponent(newEnt, Collider.class, new Collider(50., 200.));
|
gameEngine.addComponent(newEnt, Collider.class, new Collider(50., 200.));
|
||||||
gameEngine.addComponent(newEnt, Render.class, new Render(BoxRender.class));
|
gameEngine.addComponent(newEnt, Render.class, new Render(BoxRender.class));
|
||||||
gameEngine.addComponent(newEnt, BoxRender.class, new BoxRender(50, 200, 64, 64, 64));
|
gameEngine.addComponent(newEnt, BoxRender.class, new BoxRender(50, 200, 64, 64, 64));
|
||||||
@@ -110,7 +113,7 @@ public final class App {
|
|||||||
gameEngine.addComponent(newEnt, Reporter.class, new Reporter());
|
gameEngine.addComponent(newEnt, Reporter.class, new Reporter());
|
||||||
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(5,5,0));
|
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(5,5,0));
|
||||||
|
|
||||||
/* // Uncomment this block to enable the stress-test (runs 500 square entities, with physics etc.)
|
// Uncomment this block to enable the stress-test (runs 500 square entities, with physics etc.)
|
||||||
Random rand = new Random();
|
Random rand = new Random();
|
||||||
for (int i = 0; i < 500; i++) {
|
for (int i = 0; i < 500; i++) {
|
||||||
newEnt = gameEngine.createEntity();
|
newEnt = gameEngine.createEntity();
|
||||||
@@ -122,15 +125,16 @@ public final class App {
|
|||||||
gameEngine.addComponent(newEnt, Render.class, new Render(BoxRender.class));
|
gameEngine.addComponent(newEnt, Render.class, new Render(BoxRender.class));
|
||||||
gameEngine.addComponent(newEnt, BoxRender.class, new BoxRender(size, size, 30 + rand.nextInt(225), 30 + rand.nextInt(225), 30 + rand.nextInt(225)));
|
gameEngine.addComponent(newEnt, BoxRender.class, new BoxRender(size, size, 30 + rand.nextInt(225), 30 + rand.nextInt(225), 30 + rand.nextInt(225)));
|
||||||
gameEngine.addComponent(newEnt, TimedExistence.class, new TimedExistence(25 + rand.nextDouble() * 90));
|
gameEngine.addComponent(newEnt, TimedExistence.class, new TimedExistence(25 + rand.nextDouble() * 90));
|
||||||
} */
|
}
|
||||||
|
|
||||||
/************************************
|
/************************************
|
||||||
** Run init() on the systems **
|
** Run init() on the systems **
|
||||||
*************************************/
|
*************************************/
|
||||||
|
renderSystem.init();
|
||||||
|
rendererReadySemaphore.acquire();
|
||||||
physicsSystem.init();
|
physicsSystem.init();
|
||||||
collisionSystem.init();
|
collisionSystem.init();
|
||||||
logUpdateSystem.init();
|
logUpdateSystem.init();
|
||||||
renderSystem.init();
|
|
||||||
existenceSystem.init();
|
existenceSystem.init();
|
||||||
reportSystem.init();
|
reportSystem.init();
|
||||||
|
|
||||||
@@ -142,14 +146,15 @@ public final class App {
|
|||||||
double frameRate = 1.0 / 144; // 1 second divided by target number of frames
|
double frameRate = 1.0 / 144; // 1 second divided by target number of frames
|
||||||
|
|
||||||
boolean exit = false;
|
boolean exit = false;
|
||||||
|
Thread.sleep(5000);
|
||||||
long startTime = System.nanoTime();
|
long startTime = System.nanoTime();
|
||||||
while (!exit){
|
while (!exit){
|
||||||
// Run system updates
|
// Run system updates
|
||||||
collisionSystem.update();
|
collisionSystem.update(dt);
|
||||||
physicsSystem.update(dt);
|
physicsSystem.update(dt);
|
||||||
existenceSystem.update(dt);
|
existenceSystem.update(dt);
|
||||||
reportSystem.update();
|
reportSystem.update(dt);
|
||||||
renderSystem.update();
|
renderSystem.update(dt);
|
||||||
|
|
||||||
dt = (System.nanoTime() - startTime) / 1e9; // convert nanoseconds to seconds
|
dt = (System.nanoTime() - startTime) / 1e9; // convert nanoseconds to seconds
|
||||||
startTime = System.nanoTime();
|
startTime = System.nanoTime();
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
package nz.ac.massey.javaecs.examples.Systems;
|
package nz.ac.massey.javaecs.examples.Systems;
|
||||||
|
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import nz.ac.massey.javaecs.ECSSystem;
|
import nz.ac.massey.javaecs.ECSSystem;
|
||||||
import nz.ac.massey.javaecs.Engine;
|
import nz.ac.massey.javaecs.Engine;
|
||||||
import nz.ac.massey.javaecs.Entity;
|
import nz.ac.massey.javaecs.Entity;
|
||||||
import nz.ac.massey.javaecs.examples.Components.Collider;
|
import nz.ac.massey.javaecs.examples.Components.Collider;
|
||||||
import nz.ac.massey.javaecs.examples.Components.Gravity;
|
|
||||||
import nz.ac.massey.javaecs.examples.Components.RidgidBody;
|
import nz.ac.massey.javaecs.examples.Components.RidgidBody;
|
||||||
import nz.ac.massey.javaecs.examples.Components.Vec2D;
|
import nz.ac.massey.javaecs.examples.Components.Vec2D;
|
||||||
|
|
||||||
@@ -28,41 +25,35 @@ public class CollisionSystem extends ECSSystem {
|
|||||||
public void init() {
|
public void init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a quick & naive physics implementation. Not all collision states are accurately calculated
|
// This is a quick & naive physics implementation.
|
||||||
// I also expect it is highly inefficient, though I was able to run it with 500 subscribed entities
|
// I expect it is highly inefficient, though it is able to run it with 500
|
||||||
|
// subscribed entities
|
||||||
// with no major performance issues
|
// with no major performance issues
|
||||||
// Replace this with a proper system as required
|
// Replace this with a proper system as required - I.e. Box2D or etc.
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update(double dt) {
|
||||||
Set<Entity> processed = new HashSet<>();
|
|
||||||
// Gets all items we have collided with
|
|
||||||
for (Entity entity : entities) {
|
for (Entity entity : entities) {
|
||||||
Vec2D pos = (Vec2D) gameEngine.getComponentData(entity, Vec2D.class);
|
Vec2D pos = (Vec2D) gameEngine.getComponentData(entity, Vec2D.class);
|
||||||
RidgidBody ridgidBody = (RidgidBody) gameEngine.getComponentData(entity, RidgidBody.class);
|
RidgidBody ridgidBody = (RidgidBody) gameEngine.getComponentData(entity, RidgidBody.class);
|
||||||
Collider collider = (Collider) gameEngine.getComponentData(entity, Collider.class);
|
Collider collider = (Collider) gameEngine.getComponentData(entity, Collider.class);
|
||||||
if (ridgidBody.mass >= 0) {
|
if (ridgidBody.mass >= 0) {
|
||||||
// Only ignore non-static colliders
|
// Only ignore non-static colliders
|
||||||
//processed.add(entity);
|
|
||||||
for (Entity entity2 : entities) {
|
for (Entity entity2 : entities) {
|
||||||
if (!processed.contains(entity2)) {
|
|
||||||
// skip entities that have already been processed
|
// skip entities that have already been processed
|
||||||
Vec2D otherPos = (Vec2D) gameEngine.getComponentData(entity2, Vec2D.class);
|
Vec2D otherPos = (Vec2D) gameEngine.getComponentData(entity2, Vec2D.class);
|
||||||
RidgidBody otherRidgidBody = (RidgidBody) gameEngine.getComponentData(entity2,
|
RidgidBody otherRidgidBody = (RidgidBody) gameEngine.getComponentData(entity2, RidgidBody.class);
|
||||||
RidgidBody.class);
|
|
||||||
Collider otherCollider = (Collider) gameEngine.getComponentData(entity2, Collider.class);
|
Collider otherCollider = (Collider) gameEngine.getComponentData(entity2, Collider.class);
|
||||||
|
|
||||||
if (ridgidBody.mass >= 0 || otherRidgidBody.mass >= 0) {
|
if (otherRidgidBody.mass < 0) {
|
||||||
// Evaluate a collision in the top-left
|
// Evaluate a collision in the top-left
|
||||||
boolean tlCollide = pos.x > otherPos.x && pos.x < otherPos.x + otherCollider.x
|
boolean tlCollide = pos.x > otherPos.x && pos.x < otherPos.x + otherCollider.x
|
||||||
&& pos.y > otherPos.y && pos.y < otherPos.y + otherCollider.y;
|
&& pos.y > otherPos.y && pos.y < otherPos.y + otherCollider.y;
|
||||||
// Evaluate a collision in the bottom-left
|
// Evaluate a collision in the bottom-left
|
||||||
boolean blCollide = pos.x > otherPos.x && pos.x < otherPos.x + otherCollider.x
|
boolean blCollide = pos.x > otherPos.x && pos.x < otherPos.x + otherCollider.x
|
||||||
&& pos.y + collider.y > otherPos.y
|
&& pos.y + collider.y > otherPos.y && pos.y + collider.y < otherPos.y + otherCollider.y;
|
||||||
&& pos.y + collider.y < otherPos.y + otherCollider.y;
|
|
||||||
// Evaluate a collision in the bottom-right
|
// Evaluate a collision in the bottom-right
|
||||||
boolean brCollide = pos.x + collider.x > otherPos.x
|
boolean brCollide = pos.x + collider.x > otherPos.x
|
||||||
&& pos.x + collider.x < otherPos.x + otherCollider.x
|
&& pos.x + collider.x < otherPos.x + otherCollider.x && pos.y + collider.y > otherPos.y
|
||||||
&& pos.y + collider.y > otherPos.y
|
|
||||||
&& pos.y + collider.y < otherPos.y + otherCollider.y;
|
&& pos.y + collider.y < otherPos.y + otherCollider.y;
|
||||||
// Evaluate a collision in the top-right
|
// Evaluate a collision in the top-right
|
||||||
boolean trCollide = pos.x + collider.x > otherPos.x
|
boolean trCollide = pos.x + collider.x > otherPos.x
|
||||||
@@ -74,8 +65,7 @@ public class CollisionSystem extends ECSSystem {
|
|||||||
double totalYVel = Math.abs(ridgidBody.yVel) + Math.abs(otherRidgidBody.yVel);
|
double totalYVel = Math.abs(ridgidBody.yVel) + Math.abs(otherRidgidBody.yVel);
|
||||||
double xMult = 0;
|
double xMult = 0;
|
||||||
double yMult = 0;
|
double yMult = 0;
|
||||||
double multTot = (1 + ridgidBody.bounciness);
|
double multTot = 1;
|
||||||
double totalMass = ridgidBody.mass + otherRidgidBody.mass;
|
|
||||||
boolean fullEdge = false;
|
boolean fullEdge = false;
|
||||||
// left-hand collision
|
// left-hand collision
|
||||||
if (tlCollide && blCollide) {
|
if (tlCollide && blCollide) {
|
||||||
@@ -90,40 +80,26 @@ public class CollisionSystem extends ECSSystem {
|
|||||||
xMult = -multTot;
|
xMult = -multTot;
|
||||||
}
|
}
|
||||||
// Bottom collision
|
// Bottom collision
|
||||||
if (blCollide && brCollide) {
|
else if (blCollide && brCollide) {
|
||||||
fullEdge = true;
|
fullEdge = true;
|
||||||
//pos.y = otherPos.y + otherCollider.y;
|
// pos.y = otherPos.y + otherCollider.y;
|
||||||
pos.y = otherPos.y - collider.y;
|
pos.y = otherPos.y - collider.y;
|
||||||
yMult = -multTot;
|
yMult = -multTot;
|
||||||
}
|
}
|
||||||
// top collision
|
// top collision
|
||||||
else if (trCollide && tlCollide) {
|
else if (trCollide && tlCollide) {
|
||||||
fullEdge = true;
|
fullEdge = true;
|
||||||
//pos.y = otherPos.y - collider.y;
|
// pos.y = otherPos.y - collider.y;
|
||||||
pos.y = otherPos.y + otherCollider.y;
|
pos.y = otherPos.y + otherCollider.y;
|
||||||
yMult = multTot;
|
yMult = multTot;
|
||||||
}
|
}
|
||||||
if (fullEdge) {
|
if (fullEdge) {
|
||||||
// Finally, actuate the calculation
|
double newXVel = totalXVel * (xMult
|
||||||
// entity 2 is immovable; full acceleration applied to the current entity
|
* (Math.abs(xMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness)));
|
||||||
|
double newYVel = totalYVel * (yMult
|
||||||
if (otherRidgidBody.mass > 0){
|
* (Math.abs(yMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness)));
|
||||||
ridgidBody.xVel += totalXVel * xMult * ((totalMass - ridgidBody.mass) / totalMass);
|
ridgidBody.xVel += newXVel;
|
||||||
ridgidBody.yVel += totalYVel * yMult * ((totalMass - ridgidBody.mass) / totalMass);
|
ridgidBody.yVel += newYVel;
|
||||||
|
|
||||||
otherRidgidBody.xVel -= totalXVel * xMult * ((totalMass - otherRidgidBody.mass) / totalMass);
|
|
||||||
otherRidgidBody.yVel -= totalYVel * yMult * ((totalMass - otherRidgidBody.mass) / totalMass);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
ridgidBody.xVel += totalXVel * xMult;
|
|
||||||
ridgidBody.yVel += totalYVel * yMult;
|
|
||||||
}
|
|
||||||
Object grav = gameEngine.getComponentData(entity, Gravity.class);
|
|
||||||
if (grav != null) {
|
|
||||||
// negate gravity while collided
|
|
||||||
Gravity gravity = (Gravity) grav;
|
|
||||||
ridgidBody.xAcc += gravity.x * -1.;
|
|
||||||
ridgidBody.yAcc += gravity.y * -1.;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,30 +107,4 @@ public class CollisionSystem extends ECSSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Zero degrees is straight up, 90 east -90 (270) = west 180 south
|
|
||||||
*
|
|
||||||
* @param xVel
|
|
||||||
* @param yVel
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static double calcAngle(double xVel, double yVel) {
|
|
||||||
if (xVel == 0) { // Div zero; = +- 90
|
|
||||||
return yVel < 0 ? 270 : 90;
|
|
||||||
} else if (xVel < 0 && yVel < 0) { // bottom-left quad (180 - 270)
|
|
||||||
return 180. + Math.tanh(yVel / xVel);
|
|
||||||
} else if (xVel < 0) { // Top left quad (270 - 360)
|
|
||||||
return 360 - Math.tanh(yVel / xVel);
|
|
||||||
} else if (yVel < 0) {
|
|
||||||
return 180 - Math.tanh(yVel / xVel);
|
|
||||||
} else {
|
|
||||||
return Math.tanh(yVel / xVel);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,9 +34,6 @@ public class ExistenceSystem extends ECSSystem{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(double dt){
|
public void update(double dt){
|
||||||
Queue<Entity> deletions = new LinkedList<>();
|
Queue<Entity> deletions = new LinkedList<>();
|
||||||
for (Entity entity : entities) {
|
for (Entity entity : entities) {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class LogUpdateSystem extends ECSSystem{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update(double dt) {
|
||||||
for (Entity entity : entities) {
|
for (Entity entity : entities) {
|
||||||
Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class);
|
Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class);
|
||||||
System.out.println(String.format("X: %.6g, Y: %.6g", pos.x, pos.y));
|
System.out.println(String.format("X: %.6g, Y: %.6g", pos.x, pos.y));
|
||||||
|
|||||||
@@ -30,11 +30,6 @@ public class PhysicsSystem extends ECSSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(double dt){
|
public void update(double dt){
|
||||||
for (Entity entity : entities) {
|
for (Entity entity : entities) {
|
||||||
Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class);
|
Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import javafx.stage.Stage;
|
|||||||
import nz.ac.massey.javaecs.ECSSystem;
|
import nz.ac.massey.javaecs.ECSSystem;
|
||||||
import nz.ac.massey.javaecs.Engine;
|
import nz.ac.massey.javaecs.Engine;
|
||||||
import nz.ac.massey.javaecs.Entity;
|
import nz.ac.massey.javaecs.Entity;
|
||||||
|
import nz.ac.massey.javaecs.examples.App;
|
||||||
import nz.ac.massey.javaecs.examples.Components.BoxRender;
|
import nz.ac.massey.javaecs.examples.Components.BoxRender;
|
||||||
import nz.ac.massey.javaecs.examples.Components.Render;
|
import nz.ac.massey.javaecs.examples.Components.Render;
|
||||||
import nz.ac.massey.javaecs.examples.Components.TextRender;
|
import nz.ac.massey.javaecs.examples.Components.TextRender;
|
||||||
@@ -24,8 +25,8 @@ public class RenderSystem extends ECSSystem{
|
|||||||
Engine gameEngine;
|
Engine gameEngine;
|
||||||
Thread renderThread;
|
Thread renderThread;
|
||||||
double renderScale;
|
double renderScale;
|
||||||
int screenX = 1024;
|
int screenX = 512;
|
||||||
int screenY = 1024;
|
int screenY = 512;
|
||||||
|
|
||||||
public RenderSystem(Engine gameEngine, double renderScale){
|
public RenderSystem(Engine gameEngine, double renderScale){
|
||||||
this.gameEngine = gameEngine;
|
this.gameEngine = gameEngine;
|
||||||
@@ -44,7 +45,8 @@ public class RenderSystem extends ECSSystem{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update(double dt) {
|
||||||
|
// This approach needs reconsidering, as it creates an excessive amount of objects that
|
||||||
Group renderScene = new Group();
|
Group renderScene = new Group();
|
||||||
for (Entity entity : entities) {
|
for (Entity entity : entities) {
|
||||||
if (((Render)gameEngine.getComponentData(entity, Render.class)).renderType == BoxRender.class){
|
if (((Render)gameEngine.getComponentData(entity, Render.class)).renderType == BoxRender.class){
|
||||||
@@ -53,8 +55,8 @@ public class RenderSystem extends ECSSystem{
|
|||||||
|
|
||||||
Rectangle rect = new Rectangle(box.xSize* renderScale, box.ySize * renderScale);
|
Rectangle rect = new Rectangle(box.xSize* renderScale, box.ySize * renderScale);
|
||||||
rect.setFill(new Color(box.r, box.g, box.b, box.a));
|
rect.setFill(new Color(box.r, box.g, box.b, box.a));
|
||||||
rect.setX(12 + (vec2d.x * renderScale));
|
rect.setX(6 + (vec2d.x * renderScale));
|
||||||
rect.setY(1012 - (vec2d.y * renderScale) - rect.getHeight());
|
rect.setY(506 - (vec2d.y * renderScale) - rect.getHeight());
|
||||||
renderScene.getChildren().add(rect);
|
renderScene.getChildren().add(rect);
|
||||||
}
|
}
|
||||||
else if (((Render)gameEngine.getComponentData(entity, Render.class)).renderType == TextRender.class){
|
else if (((Render)gameEngine.getComponentData(entity, Render.class)).renderType == TextRender.class){
|
||||||
@@ -99,9 +101,11 @@ public class RenderSystem extends ECSSystem{
|
|||||||
public void start(Stage primaryStage) throws Exception {
|
public void start(Stage primaryStage) throws Exception {
|
||||||
// based on the colorful circles sample at https://docs.oracle.com/javase/8/javafx/get-started-tutorial/animation.htm
|
// based on the colorful circles sample at https://docs.oracle.com/javase/8/javafx/get-started-tutorial/animation.htm
|
||||||
root = new Group();
|
root = new Group();
|
||||||
Scene scene = new Scene(root, 1024, 1024, Color.BLACK);
|
Scene scene = new Scene(root, 512, 512, Color.BLACK);
|
||||||
primaryStage.setScene(scene);
|
primaryStage.setScene(scene);
|
||||||
primaryStage.show();
|
primaryStage.show();
|
||||||
|
// Signal the renderer is ready
|
||||||
|
App.rendererReadySemaphore.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void run(){
|
public static void run(){
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ public class ReportSystem extends ECSSystem{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update(double dt) {
|
||||||
for (Entity entity : entities) {
|
for (Entity entity : entities) {
|
||||||
TextRender text = (TextRender)gameEngine.getComponentData(entity, TextRender.class);
|
TextRender text = (TextRender)gameEngine.getComponentData(entity, TextRender.class);
|
||||||
text.content = "Num Entities: " + gameEngine.getNumEntities();
|
text.content = "Num Entities: " + gameEngine.getNumEntities();
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Editor configuration, see http://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
max_line_length = 80
|
||||||
|
|
||||||
|
[*.sh]
|
||||||
|
end_of_line = lf
|
||||||
|
|
||||||
|
[*.java]
|
||||||
|
indent_size = 4
|
||||||
|
max_line_length = 120
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# When shell scripts end in CRLF, bash gives a cryptic error message
|
||||||
|
*.sh text eol=lf
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#
|
||||||
|
# Standard Maven .gitignore
|
||||||
|
#
|
||||||
|
target/
|
||||||
|
pom.xml.tag
|
||||||
|
pom.xml.releaseBackup
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
pom.xml.next
|
||||||
|
release.properties
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
buildNumber.properties
|
||||||
|
.mvn/timing.properties
|
||||||
|
|
||||||
|
#
|
||||||
|
# IntelliJ
|
||||||
|
#
|
||||||
|
*.iml
|
||||||
|
.idea/*
|
||||||
|
!.idea/runConfigurations/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Visual Studio Code
|
||||||
|
#
|
||||||
|
.settings/
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.vscode/
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
language: java
|
||||||
|
jdk: openjdk8
|
||||||
|
after_success:
|
||||||
|
- mvn coveralls:report
|
||||||
+200
@@ -0,0 +1,200 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>nz.ac.massey.javaecs.examples</groupId>
|
||||||
|
<artifactId>demo2</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<junit.version>5.6.0</junit.version>
|
||||||
|
<maven-enforcer-plugin.version>3.0.0-M3</maven-enforcer-plugin.version>
|
||||||
|
<maven-checkstyle-plugin.version>3.1.0</maven-checkstyle-plugin.version>
|
||||||
|
<checkstyle.version>8.29</checkstyle.version>
|
||||||
|
<checkstyle-rules.version>4.0.1</checkstyle-rules.version>
|
||||||
|
<maven-surefire-plugin.version>3.0.0-M4</maven-surefire-plugin.version>
|
||||||
|
<jacoco-maven-plugin.version>0.8.4</jacoco-maven-plugin.version>
|
||||||
|
<maven-javadoc-plugin.version>3.0.0</maven-javadoc-plugin.version>
|
||||||
|
<coveralls-maven-plugin.version>4.3.0</coveralls-maven-plugin.version>
|
||||||
|
<!-- JaCoCo thresholds. Increase gradually as you add tests. -->
|
||||||
|
<jacoco.unit-tests.limit.instruction-ratio>0%</jacoco.unit-tests.limit.instruction-ratio>
|
||||||
|
<jacoco.unit-tests.limit.branch-ratio>0%</jacoco.unit-tests.limit.branch-ratio>
|
||||||
|
<jacoco.unit-tests.limit.class-complexity>20</jacoco.unit-tests.limit.class-complexity>
|
||||||
|
<jacoco.unit-tests.limit.method-complexity>5</jacoco.unit-tests.limit.method-complexity>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>nz.ac.massey.javaecs</groupId>
|
||||||
|
<artifactId>javaecs</artifactId>
|
||||||
|
<version>1.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
|
<version>${maven-enforcer-plugin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>enforce</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<rules>
|
||||||
|
<requireMavenVersion>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
</requireMavenVersion>
|
||||||
|
</rules>
|
||||||
|
<fail>true</fail>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
|
<version>${maven-checkstyle-plugin.version}</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.puppycrawl.tools</groupId>
|
||||||
|
<artifactId>checkstyle</artifactId>
|
||||||
|
<version>${checkstyle.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.ngeor</groupId>
|
||||||
|
<artifactId>checkstyle-rules</artifactId>
|
||||||
|
<version>${checkstyle-rules.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<configuration>
|
||||||
|
<configLocation>com/github/ngeor/checkstyle.xml</configLocation>
|
||||||
|
<includeTestSourceDirectory>true</includeTestSourceDirectory>
|
||||||
|
<skip>${skipTests}</skip>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>checkstyle</id>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<version>${jacoco-maven-plugin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>pre-unit-test</id>
|
||||||
|
<goals>
|
||||||
|
<goal>prepare-agent</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>post-unit-test</id>
|
||||||
|
<phase>test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>report</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>check-unit-test</id>
|
||||||
|
<phase>test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<dataFile>${project.build.directory}/jacoco.exec</dataFile>
|
||||||
|
<rules>
|
||||||
|
<rule>
|
||||||
|
<element>BUNDLE</element>
|
||||||
|
<limits>
|
||||||
|
<limit>
|
||||||
|
<counter>INSTRUCTION</counter>
|
||||||
|
<value>COVEREDRATIO</value>
|
||||||
|
<minimum>${jacoco.unit-tests.limit.instruction-ratio}</minimum>
|
||||||
|
</limit>
|
||||||
|
<limit>
|
||||||
|
<counter>BRANCH</counter>
|
||||||
|
<value>COVEREDRATIO</value>
|
||||||
|
<minimum>${jacoco.unit-tests.limit.branch-ratio}</minimum>
|
||||||
|
</limit>
|
||||||
|
</limits>
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<element>CLASS</element>
|
||||||
|
<limits>
|
||||||
|
<limit>
|
||||||
|
<counter>COMPLEXITY</counter>
|
||||||
|
<value>TOTALCOUNT</value>
|
||||||
|
<maximum>${jacoco.unit-tests.limit.class-complexity}</maximum>
|
||||||
|
</limit>
|
||||||
|
</limits>
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<element>METHOD</element>
|
||||||
|
<limits>
|
||||||
|
<limit>
|
||||||
|
<counter>COMPLEXITY</counter>
|
||||||
|
<value>TOTALCOUNT</value>
|
||||||
|
<maximum>${jacoco.unit-tests.limit.method-complexity}</maximum>
|
||||||
|
</limit>
|
||||||
|
</limits>
|
||||||
|
</rule>
|
||||||
|
</rules>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<reporting>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>${maven-javadoc-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</reporting>
|
||||||
|
<profiles>
|
||||||
|
<!-- Publish coverage report to Coveralls, only when running in Travis. -->
|
||||||
|
<profile>
|
||||||
|
<id>travis</id>
|
||||||
|
<activation>
|
||||||
|
<property>
|
||||||
|
<name>env.TRAVIS</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.eluder.coveralls</groupId>
|
||||||
|
<artifactId>coveralls-maven-plugin</artifactId>
|
||||||
|
<version>${coveralls-maven-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</project>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,120 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
|
import javafx.scene.Group;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import nz.ac.massey.javaecs.Engine;
|
||||||
|
import nz.ac.massey.javaecs.Entity;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.Control;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.Input;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.Render;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.Sprite;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.Vec2D;
|
||||||
|
import nz.ac.massey.javaecs.examples.Systems.ControlSystem;
|
||||||
|
import nz.ac.massey.javaecs.examples.Systems.PlayerSystem;
|
||||||
|
import nz.ac.massey.javaecs.examples.Systems.RenderSystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hello world!
|
||||||
|
*/
|
||||||
|
public class App {
|
||||||
|
static App thisApp;
|
||||||
|
public App() {
|
||||||
|
thisApp = this;
|
||||||
|
}
|
||||||
|
static Engine gameEngine;
|
||||||
|
public static Stage worldStage;
|
||||||
|
public static Group worldGroup;
|
||||||
|
static Integer syncManager = 0;
|
||||||
|
static Semaphore rendererFinished = new Semaphore(0);
|
||||||
|
/**
|
||||||
|
* Says hello to the world.
|
||||||
|
* @param args The arguments of the program.
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws Exception{
|
||||||
|
/************************************
|
||||||
|
** Initialise engine **
|
||||||
|
*************************************/
|
||||||
|
gameEngine = new Engine(16384);
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
** Register game components **
|
||||||
|
*************************************/
|
||||||
|
gameEngine.registerComponent(Control.class);
|
||||||
|
gameEngine.registerComponent(Render.class);
|
||||||
|
gameEngine.registerComponent(Sprite.class);
|
||||||
|
gameEngine.registerComponent(Vec2D.class);
|
||||||
|
gameEngine.registerComponent(Input.class);
|
||||||
|
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
** Register and initialise systems **
|
||||||
|
*************************************/
|
||||||
|
ControlSystem controlSystem = new ControlSystem(gameEngine);
|
||||||
|
gameEngine.registerSystem(ControlSystem.class, controlSystem);
|
||||||
|
|
||||||
|
RenderSystem renderSystem = new RenderSystem(gameEngine, 5.);
|
||||||
|
gameEngine.registerSystem(RenderSystem.class, renderSystem);
|
||||||
|
|
||||||
|
PlayerSystem playerSystem = new PlayerSystem(gameEngine);
|
||||||
|
gameEngine.registerSystem(PlayerSystem.class, playerSystem);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
** Create known entities **
|
||||||
|
*************************************/
|
||||||
|
// Input controller - gets player input
|
||||||
|
Entity inputEntity = gameEngine.createEntity();
|
||||||
|
gameEngine.addComponent(inputEntity, Input.class, new Input());
|
||||||
|
|
||||||
|
Entity playerEntity = gameEngine.createEntity();
|
||||||
|
gameEngine.addComponent(playerEntity, Vec2D.class, new Vec2D(25,25));
|
||||||
|
gameEngine.addComponent(playerEntity, Render.class, new Render(Sprite.class));
|
||||||
|
gameEngine.addComponent(playerEntity, Control.class, new Render(Control.class));
|
||||||
|
// Load the sprite
|
||||||
|
System.err.println(System.getProperty("user.dir"));
|
||||||
|
Image image = new Image(new FileInputStream("sprite.png"));
|
||||||
|
gameEngine.addComponent(playerEntity, Sprite.class, new Sprite(image, 50, 50));
|
||||||
|
// Push rendering into its own thread (to meet the design principle of a JavaFX program)
|
||||||
|
Thread renderThread = new Thread(new RenderStarter());
|
||||||
|
renderThread.start();
|
||||||
|
|
||||||
|
|
||||||
|
// Use a semaphore to block until the renderer is set-up
|
||||||
|
rendererFinished.acquire();
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
** Run init() on the systems **
|
||||||
|
*************************************/
|
||||||
|
|
||||||
|
controlSystem.init(worldStage);
|
||||||
|
playerSystem.init(inputEntity);
|
||||||
|
renderSystem.init(worldGroup);
|
||||||
|
|
||||||
|
double dt = 0.001;
|
||||||
|
double frameRate = 1.0 / 144; // 1 second divided by target number of frames
|
||||||
|
|
||||||
|
boolean exit = false;
|
||||||
|
long startTime = System.nanoTime();
|
||||||
|
|
||||||
|
while (!exit){
|
||||||
|
// Run system updates
|
||||||
|
controlSystem.update(dt);
|
||||||
|
playerSystem.update(dt);
|
||||||
|
renderSystem.update(dt);
|
||||||
|
|
||||||
|
dt = (System.nanoTime() - startTime) / 1e9; // convert nanoseconds to seconds
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
if (dt < frameRate){
|
||||||
|
Thread.sleep((int)((frameRate-dt)*1000));
|
||||||
|
dt = (System.nanoTime() - startTime) / 1e9;
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
renderThread.join(); // Wait for any render task to exit
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples.Components;
|
||||||
|
|
||||||
|
public class Control {
|
||||||
|
public int input = -1;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples.Components;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class Input {
|
||||||
|
// As this is a user-input- (i.e. timeframe in 10's or 100's of milliseconds) -derived value, the performance impact of
|
||||||
|
// AtomicInteger is irrelevant compared to its synchronisation ability.
|
||||||
|
public AtomicInteger input = new AtomicInteger(-1);
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples.Components;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class Render {
|
||||||
|
public Type renderType;
|
||||||
|
|
||||||
|
public Render(Type t){
|
||||||
|
renderType = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples.Components;
|
||||||
|
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
|
||||||
|
public class Sprite {
|
||||||
|
public Image sprite;
|
||||||
|
public Integer height;
|
||||||
|
public Integer width;
|
||||||
|
|
||||||
|
public Sprite(Image sprite, int height, int width){
|
||||||
|
this.sprite = sprite;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples.Components;
|
||||||
|
|
||||||
|
public class Vec2D {
|
||||||
|
public double x;
|
||||||
|
public double y;
|
||||||
|
|
||||||
|
public Vec2D(double x, double y){
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples;
|
||||||
|
|
||||||
|
|
||||||
|
import javafx.application.Application;
|
||||||
|
import javafx.scene.Group;
|
||||||
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
public class JFXView extends Application {
|
||||||
|
public static Group root;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(Stage primaryStage) throws Exception {
|
||||||
|
primaryStage.setTitle("JavaECS Demo 2");
|
||||||
|
App.worldGroup = new Group();
|
||||||
|
App.worldStage = primaryStage;
|
||||||
|
Scene scene = new Scene(App.worldGroup, 512, 512, Color.BLACK);
|
||||||
|
primaryStage.setScene(scene);
|
||||||
|
primaryStage.show();
|
||||||
|
// Notifiy that the renderer is ready
|
||||||
|
App.rendererFinished.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void run(){
|
||||||
|
launch(new String[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples;
|
||||||
|
|
||||||
|
import javafx.scene.Group;
|
||||||
|
|
||||||
|
// Add a renderer
|
||||||
|
public class RenderStarter implements Runnable{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
JFXView.run();
|
||||||
|
}
|
||||||
|
void updateScene(Group newGroup){
|
||||||
|
JFXView.root.getChildren().clear();
|
||||||
|
JFXView.root.getChildren().add(newGroup);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples.Systems;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.scene.input.KeyCode;
|
||||||
|
import javafx.scene.input.KeyEvent;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import nz.ac.massey.javaecs.ECSSystem;
|
||||||
|
import nz.ac.massey.javaecs.Engine;
|
||||||
|
import nz.ac.massey.javaecs.Entity;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.Input;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The control system creates a handler for input in the world stage.
|
||||||
|
* It then passes input events as they occur to the Input component
|
||||||
|
* The ControlSystem reads this input every frame update and enacts
|
||||||
|
* on the player controller
|
||||||
|
*/
|
||||||
|
public class ControlSystem extends ECSSystem {
|
||||||
|
Engine gameEngine;
|
||||||
|
Entity inputEntity;
|
||||||
|
|
||||||
|
public ControlSystem(Engine gamEngine){
|
||||||
|
this.gameEngine = gamEngine;
|
||||||
|
registrationSet = new BitSet();
|
||||||
|
registrationSet.set(gameEngine.getComponentIndex(Input.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(Stage world) {
|
||||||
|
// use a single entity to control inputs, it is present in the world stage
|
||||||
|
// and is responsible for collecting & passing data
|
||||||
|
inputEntity = entities.iterator().next();
|
||||||
|
|
||||||
|
// Add an event handler to the stage. This
|
||||||
|
Platform.runLater(new Runnable(){
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
world.addEventHandler(KeyEvent.KEY_PRESSED, (key) -> {
|
||||||
|
if(key.getCode()==KeyCode.W) {
|
||||||
|
updateKeyPress(0);
|
||||||
|
System.err.println("W pressed");
|
||||||
|
}
|
||||||
|
else if(key.getCode()==KeyCode.S) {
|
||||||
|
updateKeyPress(1);
|
||||||
|
System.err.println("S pressed");
|
||||||
|
}
|
||||||
|
else if(key.getCode()==KeyCode.A) {
|
||||||
|
updateKeyPress(2);
|
||||||
|
System.err.println("A pressed");
|
||||||
|
}
|
||||||
|
else if(key.getCode()==KeyCode.D) {
|
||||||
|
updateKeyPress(3);
|
||||||
|
System.err.println("D pressed");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(double dt) {
|
||||||
|
//Input inputUpdate = (Input)gameEngine.getComponentData(inputEntity, Input.class);
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the input's keypressed state
|
||||||
|
protected void updateKeyPress(int dir){
|
||||||
|
Input inputUpdate = (Input)gameEngine.getComponentData(inputEntity, Input.class);
|
||||||
|
inputUpdate.input.set(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() throws Exception {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples.Systems;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
import nz.ac.massey.javaecs.ECSSystem;
|
||||||
|
import nz.ac.massey.javaecs.Engine;
|
||||||
|
import nz.ac.massey.javaecs.Entity;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.Control;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.Input;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.Sprite;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.Vec2D;
|
||||||
|
|
||||||
|
public class PlayerSystem extends ECSSystem{
|
||||||
|
Engine gameEngine;
|
||||||
|
Entity inputEntity; // Entity which recieves event data
|
||||||
|
|
||||||
|
|
||||||
|
public PlayerSystem(Engine gameEngine){
|
||||||
|
this.gameEngine = gameEngine;
|
||||||
|
registrationSet = new BitSet();
|
||||||
|
registrationSet.set(gameEngine.getComponentIndex(Control.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(Entity inputEntity){
|
||||||
|
this.inputEntity = inputEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() throws Exception {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(double dt) {
|
||||||
|
int state = ((Input)gameEngine.getComponentData(inputEntity, Input.class)).input.get();
|
||||||
|
// The value of the input may change before control leaves here; sychronisation isn't
|
||||||
|
// hugely important through this section. So we can just ignore the change
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class);
|
||||||
|
Sprite sprite = (Sprite)gameEngine.getComponentData(entity, Sprite.class);
|
||||||
|
if (state == 0){ // W
|
||||||
|
pos.y -= sprite.height/2;
|
||||||
|
}
|
||||||
|
else if (state == 1){ // S
|
||||||
|
pos.y += sprite.height/2;
|
||||||
|
}
|
||||||
|
else if (state == 2){ // A
|
||||||
|
pos.x -= sprite.width/2;
|
||||||
|
}
|
||||||
|
else if (state == 3){ // D
|
||||||
|
pos.x += sprite.width/2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Finally, unset the state
|
||||||
|
((Input)gameEngine.getComponentData(inputEntity, Input.class)).input.set(-1); // Unset the state, it has been handled
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples.Systems;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
import javafx.application.Platform;
|
||||||
|
import javafx.scene.Group;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import nz.ac.massey.javaecs.ECSSystem;
|
||||||
|
import nz.ac.massey.javaecs.Engine;
|
||||||
|
import nz.ac.massey.javaecs.Entity;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.Render;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.Sprite;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.Vec2D;
|
||||||
|
/*
|
||||||
|
* This render system is different from demo 1, as its main functionality is provided directly by the program, not as an entity.
|
||||||
|
*/
|
||||||
|
public class RenderSystem extends ECSSystem {
|
||||||
|
Engine gameEngine;
|
||||||
|
Group renderGroup;
|
||||||
|
Thread renderThread;
|
||||||
|
double renderScale;
|
||||||
|
int screenX = 512;
|
||||||
|
int screenY = 512;
|
||||||
|
|
||||||
|
public RenderSystem(Engine gameEngine, double renderScale){
|
||||||
|
this.gameEngine = gameEngine;
|
||||||
|
// Set registrations
|
||||||
|
registrationSet = new BitSet();
|
||||||
|
registrationSet.set(gameEngine.getComponentIndex(Render.class));
|
||||||
|
this.renderScale = renderScale;
|
||||||
|
}
|
||||||
|
public void init(Group renderGroup) throws Exception {
|
||||||
|
this.renderGroup = renderGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() throws Exception {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(double dt) {
|
||||||
|
Group frame = new Group();
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class);
|
||||||
|
if (((Render)gameEngine.getComponentData(entity, Render.class)).renderType == Sprite.class){
|
||||||
|
// Render the sprite
|
||||||
|
Sprite sprite = (Sprite)gameEngine.getComponentData(entity, Sprite.class);
|
||||||
|
ImageView spriteRender = new ImageView(sprite.sprite);
|
||||||
|
spriteRender.setX(pos.x);
|
||||||
|
spriteRender.setY(pos.y);
|
||||||
|
spriteRender.setFitWidth(sprite.width);
|
||||||
|
spriteRender.setFitHeight(sprite.height);
|
||||||
|
frame.getChildren().add(spriteRender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must be run by the UI thread, not the main thread.
|
||||||
|
// This dispatches the operation run() to the UI.
|
||||||
|
Platform.runLater(new Runnable(){
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
renderGroup.getChildren().clear();
|
||||||
|
renderGroup.getChildren().add(frame);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,18 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for simple App.
|
||||||
|
*/
|
||||||
|
class AppTest {
|
||||||
|
/**
|
||||||
|
* Rigorous Test.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
void testApp() {
|
||||||
|
assertEquals(1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Editor configuration, see http://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
max_line_length = 80
|
||||||
|
|
||||||
|
[*.sh]
|
||||||
|
end_of_line = lf
|
||||||
|
|
||||||
|
[*.java]
|
||||||
|
indent_size = 4
|
||||||
|
max_line_length = 120
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
# When shell scripts end in CRLF, bash gives a cryptic error message
|
||||||
|
*.sh text eol=lf
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#
|
||||||
|
# Standard Maven .gitignore
|
||||||
|
#
|
||||||
|
target/
|
||||||
|
pom.xml.tag
|
||||||
|
pom.xml.releaseBackup
|
||||||
|
pom.xml.versionsBackup
|
||||||
|
pom.xml.next
|
||||||
|
release.properties
|
||||||
|
dependency-reduced-pom.xml
|
||||||
|
buildNumber.properties
|
||||||
|
.mvn/timing.properties
|
||||||
|
|
||||||
|
#
|
||||||
|
# IntelliJ
|
||||||
|
#
|
||||||
|
*.iml
|
||||||
|
.idea/*
|
||||||
|
!.idea/runConfigurations/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Visual Studio Code
|
||||||
|
#
|
||||||
|
.settings/
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
# Ignore logs, these came from an error in the VM
|
||||||
|
*.log
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
language: java
|
||||||
|
jdk: openjdk8
|
||||||
|
after_success:
|
||||||
|
- mvn coveralls:report
|
||||||
@@ -0,0 +1,200 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>nz.ac.massey.javaecs.examples</groupId>
|
||||||
|
<artifactId>perftest</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<junit.version>5.6.0</junit.version>
|
||||||
|
<maven-enforcer-plugin.version>3.0.0-M3</maven-enforcer-plugin.version>
|
||||||
|
<maven-checkstyle-plugin.version>3.1.0</maven-checkstyle-plugin.version>
|
||||||
|
<checkstyle.version>8.29</checkstyle.version>
|
||||||
|
<checkstyle-rules.version>4.0.1</checkstyle-rules.version>
|
||||||
|
<maven-surefire-plugin.version>3.0.0-M4</maven-surefire-plugin.version>
|
||||||
|
<jacoco-maven-plugin.version>0.8.4</jacoco-maven-plugin.version>
|
||||||
|
<maven-javadoc-plugin.version>3.0.0</maven-javadoc-plugin.version>
|
||||||
|
<coveralls-maven-plugin.version>4.3.0</coveralls-maven-plugin.version>
|
||||||
|
<!-- JaCoCo thresholds. Increase gradually as you add tests. -->
|
||||||
|
<jacoco.unit-tests.limit.instruction-ratio>0%</jacoco.unit-tests.limit.instruction-ratio>
|
||||||
|
<jacoco.unit-tests.limit.branch-ratio>0%</jacoco.unit-tests.limit.branch-ratio>
|
||||||
|
<jacoco.unit-tests.limit.class-complexity>20</jacoco.unit-tests.limit.class-complexity>
|
||||||
|
<jacoco.unit-tests.limit.method-complexity>5</jacoco.unit-tests.limit.method-complexity>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.junit.jupiter</groupId>
|
||||||
|
<artifactId>junit-jupiter-engine</artifactId>
|
||||||
|
<version>${junit.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>nz.ac.massey.javaecs</groupId>
|
||||||
|
<artifactId>javaecs</artifactId>
|
||||||
|
<version>1.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-enforcer-plugin</artifactId>
|
||||||
|
<version>${maven-enforcer-plugin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>enforce</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<rules>
|
||||||
|
<requireMavenVersion>
|
||||||
|
<version>3.6.3</version>
|
||||||
|
</requireMavenVersion>
|
||||||
|
</rules>
|
||||||
|
<fail>true</fail>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
|
<version>${maven-checkstyle-plugin.version}</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.puppycrawl.tools</groupId>
|
||||||
|
<artifactId>checkstyle</artifactId>
|
||||||
|
<version>${checkstyle.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.ngeor</groupId>
|
||||||
|
<artifactId>checkstyle-rules</artifactId>
|
||||||
|
<version>${checkstyle-rules.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<configuration>
|
||||||
|
<configLocation>com/github/ngeor/checkstyle.xml</configLocation>
|
||||||
|
<includeTestSourceDirectory>true</includeTestSourceDirectory>
|
||||||
|
<skip>${skipTests}</skip>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>checkstyle</id>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>${maven-surefire-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jacoco</groupId>
|
||||||
|
<artifactId>jacoco-maven-plugin</artifactId>
|
||||||
|
<version>${jacoco-maven-plugin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>pre-unit-test</id>
|
||||||
|
<goals>
|
||||||
|
<goal>prepare-agent</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>post-unit-test</id>
|
||||||
|
<phase>test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>report</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>check-unit-test</id>
|
||||||
|
<phase>test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>check</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<dataFile>${project.build.directory}/jacoco.exec</dataFile>
|
||||||
|
<rules>
|
||||||
|
<rule>
|
||||||
|
<element>BUNDLE</element>
|
||||||
|
<limits>
|
||||||
|
<limit>
|
||||||
|
<counter>INSTRUCTION</counter>
|
||||||
|
<value>COVEREDRATIO</value>
|
||||||
|
<minimum>${jacoco.unit-tests.limit.instruction-ratio}</minimum>
|
||||||
|
</limit>
|
||||||
|
<limit>
|
||||||
|
<counter>BRANCH</counter>
|
||||||
|
<value>COVEREDRATIO</value>
|
||||||
|
<minimum>${jacoco.unit-tests.limit.branch-ratio}</minimum>
|
||||||
|
</limit>
|
||||||
|
</limits>
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<element>CLASS</element>
|
||||||
|
<limits>
|
||||||
|
<limit>
|
||||||
|
<counter>COMPLEXITY</counter>
|
||||||
|
<value>TOTALCOUNT</value>
|
||||||
|
<maximum>${jacoco.unit-tests.limit.class-complexity}</maximum>
|
||||||
|
</limit>
|
||||||
|
</limits>
|
||||||
|
</rule>
|
||||||
|
<rule>
|
||||||
|
<element>METHOD</element>
|
||||||
|
<limits>
|
||||||
|
<limit>
|
||||||
|
<counter>COMPLEXITY</counter>
|
||||||
|
<value>TOTALCOUNT</value>
|
||||||
|
<maximum>${jacoco.unit-tests.limit.method-complexity}</maximum>
|
||||||
|
</limit>
|
||||||
|
</limits>
|
||||||
|
</rule>
|
||||||
|
</rules>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<reporting>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>${maven-javadoc-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</reporting>
|
||||||
|
<profiles>
|
||||||
|
<!-- Publish coverage report to Coveralls, only when running in Travis. -->
|
||||||
|
<profile>
|
||||||
|
<id>travis</id>
|
||||||
|
<activation>
|
||||||
|
<property>
|
||||||
|
<name>env.TRAVIS</name>
|
||||||
|
</property>
|
||||||
|
</activation>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.eluder.coveralls</groupId>
|
||||||
|
<artifactId>coveralls-maven-plugin</artifactId>
|
||||||
|
<version>${coveralls-maven-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples;
|
||||||
|
|
||||||
|
import nz.ac.massey.javaecs.*;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.*;
|
||||||
|
import nz.ac.massey.javaecs.examples.Systems.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Benchmark,
|
||||||
|
* A port of https://github.com/abeimler/ecs_benchmark
|
||||||
|
*/
|
||||||
|
public final class App {
|
||||||
|
private App() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Says hello to the world.
|
||||||
|
* @param args The arguments of the program.
|
||||||
|
* @throws InterruptedException
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
int nEntities = 1_000_000;
|
||||||
|
double startTime = System.nanoTime();
|
||||||
|
Engine engine = new Engine(nEntities);
|
||||||
|
double endTime = System.nanoTime();
|
||||||
|
|
||||||
|
System.out.println("Constructor Time taken: " + (endTime - startTime) / 1e6+ " ms " + "("+ (endTime - startTime) / 1e9 + " seconds )");
|
||||||
|
|
||||||
|
|
||||||
|
engine.registerComponent(ComflabulationComponent.class);
|
||||||
|
engine.registerComponent(DirectionComponent.class);
|
||||||
|
engine.registerComponent(PositionComponent.class);
|
||||||
|
|
||||||
|
ComflabSystem comflabSystem = new ComflabSystem(engine);
|
||||||
|
engine.registerSystem(ComflabSystem.class, comflabSystem);
|
||||||
|
|
||||||
|
MovementSystem movementSystem = new MovementSystem(engine);
|
||||||
|
engine.registerSystem(MovementSystem.class, movementSystem);
|
||||||
|
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
|
||||||
|
for (int i = 0; i < nEntities; i++) {
|
||||||
|
Entity entity = engine.createEntity();
|
||||||
|
engine.addComponent(entity, PositionComponent.class, new PositionComponent());
|
||||||
|
engine.addComponent(entity, DirectionComponent.class, new DirectionComponent());
|
||||||
|
if (i % 2 != 0){
|
||||||
|
engine.addComponent(entity, ComflabulationComponent.class, new ComflabulationComponent());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
endTime = System.nanoTime();
|
||||||
|
|
||||||
|
System.out.println("Entity creation Time taken: " + (endTime - startTime) / 1e6+ " ms " + "("+ (endTime - startTime) / 1e9 + " seconds )");
|
||||||
|
// Delay as object creation is multithreaded in at least OpenJDK 1.8 - lets use see the single core performance
|
||||||
|
Thread.sleep(5000);
|
||||||
|
double dt = 1.0f/60.0f;
|
||||||
|
startTime = System.nanoTime();
|
||||||
|
movementSystem.update(dt);
|
||||||
|
comflabSystem.update(dt);
|
||||||
|
endTime = System.nanoTime();
|
||||||
|
|
||||||
|
System.out.println("Single Loop Time taken: " + (endTime - startTime) / 1e6+ " ms " + "("+ (endTime - startTime) / 1e9 + " seconds )");
|
||||||
|
|
||||||
|
System.out.println("Hello World!");
|
||||||
|
}
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples.Components;
|
||||||
|
|
||||||
|
public class ComflabulationComponent {
|
||||||
|
public double thingy;
|
||||||
|
public int dingy;
|
||||||
|
public boolean mingy;
|
||||||
|
public String stringy;
|
||||||
|
|
||||||
|
public ComflabulationComponent(double thingy, int dingy, boolean mingy, String stringy){
|
||||||
|
this.thingy = thingy;
|
||||||
|
this.dingy = dingy;
|
||||||
|
this.mingy = mingy;
|
||||||
|
this.stringy = stringy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComflabulationComponent(){
|
||||||
|
thingy = 0.0f;
|
||||||
|
dingy = 0;
|
||||||
|
mingy = false;
|
||||||
|
stringy = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples.Components;
|
||||||
|
|
||||||
|
public class DirectionComponent {
|
||||||
|
public double x;
|
||||||
|
public double y;
|
||||||
|
|
||||||
|
public DirectionComponent(double x, double y){
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DirectionComponent(){
|
||||||
|
x = 0.0f;
|
||||||
|
y = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples.Components;
|
||||||
|
|
||||||
|
public class PositionComponent {
|
||||||
|
public double x;
|
||||||
|
public double y;
|
||||||
|
|
||||||
|
public PositionComponent(double x, double y){
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PositionComponent(){
|
||||||
|
x = 0.0f;
|
||||||
|
y = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples.Systems;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
import nz.ac.massey.javaecs.ECSSystem;
|
||||||
|
import nz.ac.massey.javaecs.Engine;
|
||||||
|
import nz.ac.massey.javaecs.Entity;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.ComflabulationComponent;
|
||||||
|
|
||||||
|
public class ComflabSystem extends ECSSystem {
|
||||||
|
Engine ecs;
|
||||||
|
|
||||||
|
public ComflabSystem(Engine ecs){
|
||||||
|
this.ecs = ecs;
|
||||||
|
registrationSet = new BitSet();
|
||||||
|
registrationSet.set(ecs.getComponentIndex(ComflabulationComponent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(double dt) {
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
ComflabulationComponent comflab = (ComflabulationComponent)ecs.getComponentData(entity, ComflabulationComponent.class);
|
||||||
|
comflab.thingy *= 1.000001;
|
||||||
|
comflab.mingy = !comflab.mingy;
|
||||||
|
comflab.dingy++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples.Systems;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
import nz.ac.massey.javaecs.ECSSystem;
|
||||||
|
import nz.ac.massey.javaecs.Engine;
|
||||||
|
import nz.ac.massey.javaecs.Entity;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.DirectionComponent;
|
||||||
|
import nz.ac.massey.javaecs.examples.Components.PositionComponent;
|
||||||
|
|
||||||
|
public class MovementSystem extends ECSSystem {
|
||||||
|
Engine ecs;
|
||||||
|
|
||||||
|
public MovementSystem(Engine ecs){
|
||||||
|
this.ecs = ecs;
|
||||||
|
registrationSet = new BitSet();
|
||||||
|
registrationSet.set(ecs.getComponentIndex(PositionComponent.class));
|
||||||
|
registrationSet.set(ecs.getComponentIndex(DirectionComponent.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(double dt) {
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
PositionComponent position = (PositionComponent)ecs.getComponentData(entity, PositionComponent.class);
|
||||||
|
DirectionComponent direction = (DirectionComponent)ecs.getComponentData(entity, DirectionComponent.class);
|
||||||
|
position.x += direction.x * dt;
|
||||||
|
position.y += direction.y * dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package nz.ac.massey.javaecs.examples;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for simple App.
|
||||||
|
*/
|
||||||
|
class AppTest {
|
||||||
|
/**
|
||||||
|
* Rigorous Test.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
void testApp() {
|
||||||
|
assertEquals(1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user