diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/content/Example1.mp4 b/content/Example1.mp4 new file mode 100644 index 0000000..2b3df93 Binary files /dev/null and b/content/Example1.mp4 differ diff --git a/demo1/src/main/java/nz/ac/massey/javaecs/examples/App.java b/demo1/src/main/java/nz/ac/massey/javaecs/examples/App.java index dbf57a9..5b83d13 100644 --- a/demo1/src/main/java/nz/ac/massey/javaecs/examples/App.java +++ b/demo1/src/main/java/nz/ac/massey/javaecs/examples/App.java @@ -1,7 +1,10 @@ package nz.ac.massey.javaecs.examples; +import java.sql.Time; import java.util.Random; +import javafx.scene.paint.Color; +import javafx.scene.text.Text; import nz.ac.massey.javaecs.*; import nz.ac.massey.javaecs.examples.Components.*; import nz.ac.massey.javaecs.examples.Systems.*; @@ -28,6 +31,9 @@ public final class App { gameEngine.registerComponent(LogUpdate.class); gameEngine.registerComponent(Render.class); gameEngine.registerComponent(BoxRender.class); + gameEngine.registerComponent(TimedExistence.class); + gameEngine.registerComponent(Reporter.class); + gameEngine.registerComponent(TextRender.class); PhysicsSystem physicsSystem = new PhysicsSystem(gameEngine); gameEngine.registerSystem(PhysicsSystem.class, physicsSystem); @@ -42,6 +48,12 @@ public final class App { RenderSystem renderSystem = new RenderSystem(gameEngine, 10.); gameEngine.registerSystem(RenderSystem.class, renderSystem); + ExistenceSystem existenceSystem = new ExistenceSystem(gameEngine); + gameEngine.registerSystem(ExistenceSystem.class, existenceSystem); + + ReportSystem reportSystem = new ReportSystem(gameEngine); + gameEngine.registerSystem(ReportSystem.class, reportSystem); + // Define a play area 100 * 100, make sure to use worldspace not screenspace (top left is 0, 100, not 0,0) // Bottom boundary Entity newEnt = gameEngine.createEntity(); @@ -79,9 +91,15 @@ public final class App { gameEngine.addComponent(newEnt, Gravity.class, new Gravity(0, -9.80665, 45., 45.)); // Terminal velocity is 45 m/s gameEngine.addComponent(newEnt, Render.class, new Render(BoxRender.class)); gameEngine.addComponent(newEnt, BoxRender.class, new BoxRender(10, 10, 255, 64, 64)); + + newEnt = gameEngine.createEntity(); + gameEngine.addComponent(newEnt, TextRender.class, new TextRender("", 24, Color.WHITE)); + gameEngine.addComponent(newEnt, Render.class, new Render(TextRender.class)); + gameEngine.addComponent(newEnt, Reporter.class, new Reporter()); + gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(5,5,0)); // Other objects Random rand = new Random(); - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 20; i++) { newEnt = gameEngine.createEntity(); gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(10 + rand.nextDouble()* 80, 10+ rand.nextDouble()* 80,0)); gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(-2.5 + rand.nextDouble()* 5., 0., 0., 0., 0.f, 0., rand.nextDouble() * 20.)); @@ -91,6 +109,7 @@ public final class App { gameEngine.addComponent(newEnt, LogUpdate.class, null); // Add to object to print pos of 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, TimedExistence.class, new TimedExistence(5 + rand.nextDouble() * 90)); } //gameEngine.addComponent(newEnt, LogUpdate.class, null); @@ -100,8 +119,10 @@ public final class App { collisionSystem.init(); logUpdateSystem.init(); renderSystem.init(); + existenceSystem.init(); + reportSystem.init(); - double dt = 0.; + double dt = 0.001; double frameRate = 1.0 / 144; // 1 second divided by target number of frames double idleTime = 0.0; // the amount of time spent sleeping @@ -112,6 +133,8 @@ public final class App { collisionSystem.update(); physicsSystem.update(dt); + existenceSystem.update(dt); + reportSystem.update(); //logUpdateSystem.update(); // The render system should be uncoupled from the physics and collision renderSystem.update(); @@ -124,6 +147,7 @@ public final class App { dt = (System.nanoTime() - startTime) / 1e9; startTime = System.nanoTime(); } + dt = 0.001; } } } diff --git a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Components/BoxRender.java b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Components/BoxRender.java index a68e999..3ffae5f 100644 --- a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Components/BoxRender.java +++ b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Components/BoxRender.java @@ -2,9 +2,10 @@ package nz.ac.massey.javaecs.examples.Components; public class BoxRender { - public double r = 255; - public double g = 255; - public double b = 255; + public double r = 1.; + public double g = 1.; + public double b = 1.; + public double a = 1.; public double xSize = 0.0; public double ySize = 0.0; diff --git a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Components/Reporter.java b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Components/Reporter.java new file mode 100644 index 0000000..a45e961 --- /dev/null +++ b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Components/Reporter.java @@ -0,0 +1,5 @@ +package nz.ac.massey.javaecs.examples.Components; + +public class Reporter { + +} diff --git a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Components/TextRender.java b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Components/TextRender.java new file mode 100644 index 0000000..bfc7a5d --- /dev/null +++ b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Components/TextRender.java @@ -0,0 +1,15 @@ +package nz.ac.massey.javaecs.examples.Components; + +import javafx.scene.paint.Color; + +public class TextRender { + public String content = ""; + public double size = 10.; + public Color color = Color.WHITE; + + public TextRender(String content, double size, Color color){ + this.content = content; + this.size = size; + this.color = color; + } +} diff --git a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Components/TimedExistence.java b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Components/TimedExistence.java new file mode 100644 index 0000000..2519708 --- /dev/null +++ b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Components/TimedExistence.java @@ -0,0 +1,9 @@ +package nz.ac.massey.javaecs.examples.Components; + +public class TimedExistence { + public double lifeTime = 0.0; + + public TimedExistence(double lifeTime){ + this.lifeTime = lifeTime; + } +} diff --git a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/ExistenceSystem.java b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/ExistenceSystem.java new file mode 100644 index 0000000..e6a3577 --- /dev/null +++ b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/ExistenceSystem.java @@ -0,0 +1,80 @@ +package nz.ac.massey.javaecs.examples.Systems; + +import java.util.BitSet; +import java.util.LinkedList; +import java.util.Queue; +import java.util.Random; + +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.BoxRender; +import nz.ac.massey.javaecs.examples.Components.Collider; +import nz.ac.massey.javaecs.examples.Components.Gravity; +import nz.ac.massey.javaecs.examples.Components.LogUpdate; +import nz.ac.massey.javaecs.examples.Components.Render; +import nz.ac.massey.javaecs.examples.Components.RidgidBody; +import nz.ac.massey.javaecs.examples.Components.TimedExistence; +import nz.ac.massey.javaecs.examples.Components.Vec2D; + +public class ExistenceSystem extends ECSSystem{ + Engine gameEngine; + Random rand; + + public ExistenceSystem(Engine gameEngine){ + this.gameEngine = gameEngine; + // Set registrations + registrationSet = new BitSet(); + registrationSet.set(gameEngine.getComponentIndex(TimedExistence.class)); + registrationSet.set(gameEngine.getComponentIndex(BoxRender.class)); + } + + @Override + public void init() { + rand = new Random(); + + } + + @Override + public void update() { + // TODO Auto-generated method stub + + } + + public void update(double dt){ + Queue deletions = new LinkedList<>(); + for (Entity entity : entities) { + BoxRender shape = (BoxRender)gameEngine.getComponentData(entity, BoxRender.class); + TimedExistence timedExistence = (TimedExistence)gameEngine.getComponentData(entity, TimedExistence.class); + // Get the rate the fade should occur at our current frame rate. + double fadeRate = timedExistence.lifeTime / dt; // I.e. might say 200 frames left + // Fade the opacity + shape.a -= shape.a / fadeRate; + // Clauses to keep things safe + if (shape.a < 0) shape.a = 0.; + else if (shape.a > 1) shape.a = 1.; + // Reduce the time the shape may continue living for + timedExistence.lifeTime -= dt; + + if (timedExistence.lifeTime <= 0){ + deletions.add(entity); + } + } + while (deletions.size() > 0){ + gameEngine.destroyEntity(deletions.remove()); + } + // Finally, randomly add an entity as required + if (rand.nextInt(16384) < 8){ + Entity newEnt = gameEngine.createEntity(); + gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(10 + rand.nextDouble()* 80, 10+ rand.nextDouble()* 80,0)); + gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(-2.5 + rand.nextDouble()* 5., 0., 0., 0., 0.f, 0., rand.nextDouble() * 20.)); + double size = 3 + rand.nextDouble() * 7; + gameEngine.addComponent(newEnt, Collider.class, new Collider(size, size)); + gameEngine.addComponent(newEnt, Gravity.class, new Gravity(0, -9.80665, 45., 45.)); // Terminal velocity is 45 m/s + 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, TimedExistence.class, new TimedExistence(5 + rand.nextDouble() * 90)); + } + } + +} diff --git a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/RenderSystem.java b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/RenderSystem.java index 33edacb..2894361 100644 --- a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/RenderSystem.java +++ b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/RenderSystem.java @@ -10,12 +10,15 @@ import javafx.scene.Scene; import javafx.scene.paint.Color; import javafx.scene.paint.Paint; import javafx.scene.shape.Rectangle; +import javafx.scene.text.Font; +import javafx.scene.text.Text; 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.BoxRender; import nz.ac.massey.javaecs.examples.Components.Render; +import nz.ac.massey.javaecs.examples.Components.TextRender; import nz.ac.massey.javaecs.examples.Components.Vec2D; public class RenderSystem extends ECSSystem{ @@ -31,6 +34,7 @@ public class RenderSystem extends ECSSystem{ // Set registrations registrationSet = new BitSet(); registrationSet.set(gameEngine.getComponentIndex(Render.class)); + registrationSet.set(gameEngine.getComponentIndex(Vec2D.class)); this.renderScale = renderScale; } @@ -58,11 +62,20 @@ public class RenderSystem extends ECSSystem{ Vec2D vec2d = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class); Rectangle rect = new Rectangle(box.xSize* renderScale, box.ySize * renderScale); - rect.setFill(new Color(box.r, box.g, box.b, 0.9)); + rect.setFill(new Color(box.r, box.g, box.b, box.a)); rect.setX(12 + (vec2d.x * renderScale)); rect.setY(1012 - (vec2d.y * renderScale) - rect.getHeight()); renderScene.getChildren().add(rect); } + else if (((Render)gameEngine.getComponentData(entity, Render.class)).renderType == TextRender.class){ + Vec2D vec2d = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class); + TextRender text = (TextRender)gameEngine.getComponentData(entity, TextRender.class); + Text t = new Text(vec2d.x * renderScale, vec2d.y * renderScale, text.content); + t.setFont(new Font(text.size)); + t.setFill(text.color); + t.setStroke(text.color); + renderScene.getChildren().add(t); + } } Platform.runLater(new Runnable(){ @Override diff --git a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/ReportSystem.java b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/ReportSystem.java new file mode 100644 index 0000000..61b0229 --- /dev/null +++ b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/ReportSystem.java @@ -0,0 +1,36 @@ +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.Reporter; +import nz.ac.massey.javaecs.examples.Components.TextRender; + +public class ReportSystem extends ECSSystem{ + Engine gameEngine; + + public ReportSystem(Engine gameEngine){ + this.gameEngine = gameEngine; + // Set registrations + registrationSet = new BitSet(); + registrationSet.set(gameEngine.getComponentIndex(Reporter.class)); + registrationSet.set(gameEngine.getComponentIndex(TextRender.class)); + } + @Override + public void init() { + // TODO Auto-generated method stub + + } + + @Override + public void update() { + for (Entity entity : entities) { + TextRender text = (TextRender)gameEngine.getComponentData(entity, TextRender.class); + text.content = "Num Entities: " + gameEngine.getNumEntities(); + } + + } + +}