Upgraded to 0.9.9, minor physics improvements

This commit is contained in:
Brychan Dempsey 2021-06-12 12:54:54 +12:00
parent 4febf41721
commit bca92faa88
8 changed files with 48 additions and 43 deletions

View File

@ -38,7 +38,7 @@
<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>0.9.9-RELEASE_CANDIDATE</version>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -145,11 +145,11 @@ public final class App {
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();

View File

@ -28,12 +28,12 @@ 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. 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 I was able to run it with 500 subscribed entities // I also 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<>(); Set<Entity> processed = new HashSet<>();
// Gets all items we have collided with // Gets all items we have collided with
for (Entity entity : entities) { for (Entity entity : entities) {
@ -52,20 +52,21 @@ public class CollisionSystem extends ECSSystem {
if (ridgidBody.mass >= 0 || otherRidgidBody.mass >= 0) { if (ridgidBody.mass >= 0 || 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
&& 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; && pos.y < otherPos.y + otherCollider.y;
if (tlCollide || blCollide || brCollide || trCollide) { if (tlCollide || blCollide || brCollide || trCollide) {
// Get the vels // Get the vels
@ -79,31 +80,31 @@ public class CollisionSystem extends ECSSystem {
// left-hand collision // left-hand collision
if (tlCollide && blCollide) { if (tlCollide && blCollide) {
fullEdge = true; fullEdge = true;
pos.x = otherPos.x + otherCollider.x; pos.x = otherPos.x + otherCollider.x - .00001;
xMult = multTot; xMult = multTot;
} }
// right-hand collision // right-hand collision
else if (brCollide && trCollide) { else if (brCollide && trCollide) {
fullEdge = true; fullEdge = true;
pos.x = otherPos.x - collider.x; pos.x = otherPos.x - collider.x + .00001;
xMult = -multTot; xMult = -multTot;
} }
// Bottom collision // Bottom collision
else 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 + .00001;
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 -.00001;
yMult = multTot; yMult = multTot;
} }
if(!fullEdge){ 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 deltaXVel = Math.abs(ridgidBody.xVel - otherRidgidBody.xVel);
double deltaYVel = Math.abs(ridgidBody.yVel - otherRidgidBody.yVel); double deltaYVel = Math.abs(ridgidBody.yVel - otherRidgidBody.yVel);
double deltaMin = 50.; double deltaMin = 50.;
@ -206,24 +207,36 @@ public class CollisionSystem extends ECSSystem {
// entity 2 is immovable; full acceleration applied to the current entity // entity 2 is immovable; full acceleration applied to the current entity
if (otherRidgidBody.mass >= 0){ if (otherRidgidBody.mass >= 0){
ridgidBody.xVel += totalXVel * ((totalMass - ridgidBody.mass) / totalMass) * (xMult + (Math.abs(xMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness))); // For collisions between dynamic objects, the restoring velocity [rv] is shared between both objects.
ridgidBody.yVel += totalYVel * ((totalMass - ridgidBody.mass) / totalMass) * (yMult + (Math.abs(yMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness))); // Each object experiences a restoring velocity proportionate to its percentage of the total mass.
otherRidgidBody.xVel -= totalXVel * ((totalMass - otherRidgidBody.mass) / totalMass) * (xMult + (Math.abs(xMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness))); // They each recieve an additional force of 'bounce',
otherRidgidBody.yVel -= totalYVel * ((totalMass - otherRidgidBody.mass) / totalMass) * (yMult + (Math.abs(yMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness))); // 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{ else{
double newXVel = totalXVel * (xMult * (Math.abs(xMult) + ridgidBody.bounciness)); // For collisions against a fixed object, the restoring velocity (velocity in the direction against the collision vector) [name it 'rv']
double newYVel = totalYVel * (yMult * (Math.abs(yMult) + ridgidBody.bounciness)); // 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.xVel += newXVel;
ridgidBody.yVel += newYVel; 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.;
}
} }
} }
} }

View File

@ -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) {

View File

@ -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));

View File

@ -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);

View File

@ -44,7 +44,7 @@ public class RenderSystem extends ECSSystem{
} }
@Override @Override
public void update() { public void update(double dt) {
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){

View File

@ -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();