From bca92faa88aa61903718d7b36d185049036a6f2d Mon Sep 17 00:00:00 2001 From: Brychan Dempsey Date: Sat, 12 Jun 2021 12:54:54 +1200 Subject: [PATCH] Upgraded to 0.9.9, minor physics improvements --- demo1/pom.xml | 2 +- .../nz/ac/massey/javaecs/examples/App.java | 6 +- .../examples/Systems/CollisionSystem.java | 69 +++++++++++-------- .../examples/Systems/ExistenceSystem.java | 3 - .../examples/Systems/LogUpdateSystem.java | 2 +- .../examples/Systems/PhysicsSystem.java | 5 -- .../examples/Systems/RenderSystem.java | 2 +- .../examples/Systems/ReportSystem.java | 2 +- 8 files changed, 48 insertions(+), 43 deletions(-) diff --git a/demo1/pom.xml b/demo1/pom.xml index a460062..f51d7cb 100644 --- a/demo1/pom.xml +++ b/demo1/pom.xml @@ -38,7 +38,7 @@ nz.ac.massey.javaecs javaecs - 0.9.2-PRERELEASE + 0.9.9-RELEASE_CANDIDATE 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 49bbc09..9cb547d 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 @@ -145,11 +145,11 @@ public final class App { long startTime = System.nanoTime(); while (!exit){ // Run system updates - collisionSystem.update(); + collisionSystem.update(dt); physicsSystem.update(dt); existenceSystem.update(dt); - reportSystem.update(); - renderSystem.update(); + reportSystem.update(dt); + renderSystem.update(dt); dt = (System.nanoTime() - startTime) / 1e9; // convert nanoseconds to seconds startTime = System.nanoTime(); diff --git a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/CollisionSystem.java b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/CollisionSystem.java index 9530306..a79c80c 100644 --- a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/CollisionSystem.java +++ b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/CollisionSystem.java @@ -28,12 +28,12 @@ public class CollisionSystem extends ECSSystem { public void init() { } - // This is a quick & naive physics implementation. Not all collision states are accurately calculated - // I also expect it is highly inefficient, though I was able to run it with 500 subscribed entities + // This is a quick & naive physics implementation. Not all collision states are accurately calculated | I'm pretty sure one of the states is set wrong, and sends things flying in the wrong direction + // I also expect it is highly inefficient, though it is able to run it with 500 subscribed entities // 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 - public void update() { + public void update(double dt) { Set processed = new HashSet<>(); // Gets all items we have collided with for (Entity entity : entities) { @@ -52,20 +52,21 @@ public class CollisionSystem extends ECSSystem { if (ridgidBody.mass >= 0 || otherRidgidBody.mass >= 0) { // Evaluate a collision in the top-left - boolean tlCollide = pos.x > otherPos.x && pos.x < otherPos.x + otherCollider.x - && pos.y > otherPos.y && pos.y < otherPos.y + otherCollider.y; + boolean tlCollide = pos.x > otherPos.x && pos.x < otherPos.x + otherCollider.x + && pos.y > otherPos.y && pos.y < otherPos.y + otherCollider.y; // 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 + otherCollider.y; // 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.y + collider.y > otherPos.y + && pos.y + collider.y > otherPos.y && pos.y + collider.y < otherPos.y + otherCollider.y; // Evaluate a collision in the top-right boolean trCollide = pos.x + collider.x > otherPos.x - && pos.x + collider.x < otherPos.x + otherCollider.x && pos.y > otherPos.y + && pos.x + collider.x < otherPos.x + otherCollider.x + && pos.y > otherPos.y && pos.y < otherPos.y + otherCollider.y; if (tlCollide || blCollide || brCollide || trCollide) { // Get the vels @@ -79,31 +80,31 @@ public class CollisionSystem extends ECSSystem { // left-hand collision if (tlCollide && blCollide) { fullEdge = true; - pos.x = otherPos.x + otherCollider.x; + pos.x = otherPos.x + otherCollider.x - .00001; xMult = multTot; } // right-hand collision else if (brCollide && trCollide) { fullEdge = true; - pos.x = otherPos.x - collider.x; + pos.x = otherPos.x - collider.x + .00001; xMult = -multTot; } // Bottom collision else if (blCollide && brCollide) { fullEdge = true; //pos.y = otherPos.y + otherCollider.y; - pos.y = otherPos.y - collider.y; + pos.y = otherPos.y - collider.y + .00001; yMult = -multTot; } // top collision else if (trCollide && tlCollide) { fullEdge = true; //pos.y = otherPos.y - collider.y; - pos.y = otherPos.y + otherCollider.y; + pos.y = otherPos.y + otherCollider.y -.00001; yMult = multTot; } if(!fullEdge){ - // Not a full edge collision, must evaluate which edge it is + // Not a full edge collision, must evaluate which edge it is (it then gets treated as a full edge) double deltaXVel = Math.abs(ridgidBody.xVel - otherRidgidBody.xVel); double deltaYVel = Math.abs(ridgidBody.yVel - otherRidgidBody.yVel); double deltaMin = 50.; @@ -206,24 +207,36 @@ public class CollisionSystem extends ECSSystem { // entity 2 is immovable; full acceleration applied to the current entity if (otherRidgidBody.mass >= 0){ - ridgidBody.xVel += totalXVel * ((totalMass - ridgidBody.mass) / totalMass) * (xMult + (Math.abs(xMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness))); - ridgidBody.yVel += totalYVel * ((totalMass - ridgidBody.mass) / totalMass) * (yMult + (Math.abs(yMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness))); - otherRidgidBody.xVel -= totalXVel * ((totalMass - otherRidgidBody.mass) / totalMass) * (xMult + (Math.abs(xMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness))); - otherRidgidBody.yVel -= totalYVel * ((totalMass - otherRidgidBody.mass) / totalMass) * (yMult + (Math.abs(yMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness))); + // For collisions between dynamic objects, the restoring velocity [rv] is shared between both objects. + // Each object experiences a restoring velocity proportionate to its percentage of the total mass. + // They each recieve an additional force of 'bounce', + // which is the total velocity * total bounciness + // This force is then shared by the mass + double rvX1 = totalXVel * ((totalMass - ridgidBody.mass) / totalMass) * xMult; + double rvY1 = totalYVel * ((totalMass - ridgidBody.mass) / totalMass) * yMult; + double totalBounce = ridgidBody.bounciness * otherRidgidBody.bounciness; + // Restoring forces + ridgidBody.xVel += rvX1; + ridgidBody.yVel += rvY1; + // Additional forces; 'bounce' + double xBounce = rvX1 * ((totalBounce - ridgidBody.bounciness) / totalBounce); + double yBounce = rvY1 * ((totalBounce - ridgidBody.bounciness) / totalBounce); + rvX1 = xBounce * ((totalMass - ridgidBody.mass) / totalMass);// * xMult; + rvY1 = yBounce * ((totalMass - ridgidBody.mass) / totalMass);// * yMult; + // bounce forces + ridgidBody.xVel += rvX1; + ridgidBody.yVel += rvY1; } else{ - double newXVel = totalXVel * (xMult * (Math.abs(xMult) + ridgidBody.bounciness)); - double newYVel = totalYVel * (yMult * (Math.abs(yMult) + ridgidBody.bounciness)); + // For collisions against a fixed object, the restoring velocity (velocity in the direction against the collision vector) [name it 'rv'] + // is at least -1x. This would affix the cardinal velocity to zero, both objects would have a 'bounciness' of zero. + // The bounciness is combined (b = object1 * object2), which gives us the total percent of retained velocity, + // i.e. a factor >= 0 & <= 1. Multiply this factor by rv to get the total restoring velocity + double newXVel = totalXVel * (xMult * (Math.abs(xMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness))); + double newYVel = totalYVel * (yMult * (Math.abs(yMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness))); ridgidBody.xVel += newXVel; ridgidBody.yVel += newYVel; } - Object grav = gameEngine.getComponentData(entity, Gravity.class); - if (grav != null && otherRidgidBody.mass < 0) { - // negate gravity while collided - Gravity gravity = (Gravity) grav; - ridgidBody.xAcc += gravity.x * -1.; - ridgidBody.yAcc += gravity.y * -1.; - } } } } 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 index a05126e..9fd7309 100644 --- 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 @@ -34,9 +34,6 @@ public class ExistenceSystem extends ECSSystem{ } @Override - public void update() { - } - public void update(double dt){ Queue deletions = new LinkedList<>(); for (Entity entity : entities) { diff --git a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/LogUpdateSystem.java b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/LogUpdateSystem.java index 4329609..228de5f 100644 --- a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/LogUpdateSystem.java +++ b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/LogUpdateSystem.java @@ -24,7 +24,7 @@ public class LogUpdateSystem extends ECSSystem{ } @Override - public void update() { + public void update(double dt) { for (Entity entity : entities) { Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class); System.out.println(String.format("X: %.6g, Y: %.6g", pos.x, pos.y)); diff --git a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/PhysicsSystem.java b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/PhysicsSystem.java index 77d6506..f214274 100644 --- a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/PhysicsSystem.java +++ b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/PhysicsSystem.java @@ -30,11 +30,6 @@ public class PhysicsSystem extends ECSSystem { } @Override - public void update() { - // TODO Auto-generated method stub - - } - public void update(double dt){ for (Entity entity : entities) { Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class); 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 84bac2a..5467827 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 @@ -44,7 +44,7 @@ public class RenderSystem extends ECSSystem{ } @Override - public void update() { + public void update(double dt) { Group renderScene = new Group(); for (Entity entity : entities) { if (((Render)gameEngine.getComponentData(entity, Render.class)).renderType == BoxRender.class){ 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 index ee2fb51..88de5ab 100644 --- 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 @@ -23,7 +23,7 @@ public class ReportSystem extends ECSSystem{ } @Override - public void update() { + public void update(double dt) { for (Entity entity : entities) { TextRender text = (TextRender)gameEngine.getComponentData(entity, TextRender.class); text.content = "Num Entities: " + gameEngine.getNumEntities();