Compare commits
2 Commits
4d76428553
...
294c0fc52f
Author | SHA1 | Date | |
---|---|---|---|
294c0fc52f | |||
0db1abcbdf |
@ -1,10 +1,8 @@
|
|||||||
package nz.ac.massey.javaecs.examples;
|
package nz.ac.massey.javaecs.examples;
|
||||||
|
|
||||||
import java.sql.Time;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.scene.text.Text;
|
|
||||||
import nz.ac.massey.javaecs.*;
|
import nz.ac.massey.javaecs.*;
|
||||||
import nz.ac.massey.javaecs.examples.Components.*;
|
import nz.ac.massey.javaecs.examples.Components.*;
|
||||||
import nz.ac.massey.javaecs.examples.Systems.*;
|
import nz.ac.massey.javaecs.examples.Systems.*;
|
||||||
@ -22,8 +20,14 @@ public final class App {
|
|||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) throws InterruptedException {
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
/************************************
|
||||||
|
** Initialise engine **
|
||||||
|
*************************************/
|
||||||
Engine gameEngine = new Engine(16384);
|
Engine gameEngine = new Engine(16384);
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
** Register game components **
|
||||||
|
*************************************/
|
||||||
gameEngine.registerComponent(Gravity.class);
|
gameEngine.registerComponent(Gravity.class);
|
||||||
gameEngine.registerComponent(RidgidBody.class);
|
gameEngine.registerComponent(RidgidBody.class);
|
||||||
gameEngine.registerComponent(Vec2D.class);
|
gameEngine.registerComponent(Vec2D.class);
|
||||||
@ -35,6 +39,9 @@ public final class App {
|
|||||||
gameEngine.registerComponent(Reporter.class);
|
gameEngine.registerComponent(Reporter.class);
|
||||||
gameEngine.registerComponent(TextRender.class);
|
gameEngine.registerComponent(TextRender.class);
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
** Register and initialise systems **
|
||||||
|
*************************************/
|
||||||
PhysicsSystem physicsSystem = new PhysicsSystem(gameEngine);
|
PhysicsSystem physicsSystem = new PhysicsSystem(gameEngine);
|
||||||
gameEngine.registerSystem(PhysicsSystem.class, physicsSystem);
|
gameEngine.registerSystem(PhysicsSystem.class, physicsSystem);
|
||||||
|
|
||||||
@ -54,6 +61,11 @@ public final class App {
|
|||||||
ReportSystem reportSystem = new ReportSystem(gameEngine);
|
ReportSystem reportSystem = new ReportSystem(gameEngine);
|
||||||
gameEngine.registerSystem(ReportSystem.class, reportSystem);
|
gameEngine.registerSystem(ReportSystem.class, reportSystem);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
** Create known entities **
|
||||||
|
*************************************/
|
||||||
// Define a play area 100 * 100, make sure to use worldspace not screenspace (top left is 0, 100, not 0,0)
|
// Define a play area 100 * 100, make sure to use worldspace not screenspace (top left is 0, 100, not 0,0)
|
||||||
// Bottom boundary
|
// Bottom boundary
|
||||||
Entity newEnt = gameEngine.createEntity();
|
Entity newEnt = gameEngine.createEntity();
|
||||||
@ -86,35 +98,35 @@ public final class App {
|
|||||||
// One object
|
// One object
|
||||||
newEnt = gameEngine.createEntity();
|
newEnt = gameEngine.createEntity();
|
||||||
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(62., 90.,0));
|
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(62., 90.,0));
|
||||||
gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(1., 0., 0., 0., 0.f, 0., 1.));
|
gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(1., 0., 0., 0., 0.f, 0.66, 120.));
|
||||||
gameEngine.addComponent(newEnt, Collider.class, new Collider(10., 10.));
|
gameEngine.addComponent(newEnt, Collider.class, new Collider(10., 10.));
|
||||||
gameEngine.addComponent(newEnt, Gravity.class, new Gravity(0, -9.80665, 45., 45.)); // Terminal velocity is 45 m/s
|
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, Render.class, new Render(BoxRender.class));
|
||||||
gameEngine.addComponent(newEnt, BoxRender.class, new BoxRender(10, 10, 255, 64, 64));
|
gameEngine.addComponent(newEnt, BoxRender.class, new BoxRender(10, 10, 255, 64, 64));
|
||||||
|
// The textobject that prints the current number of entities
|
||||||
newEnt = gameEngine.createEntity();
|
newEnt = gameEngine.createEntity();
|
||||||
gameEngine.addComponent(newEnt, TextRender.class, new TextRender("", 24, Color.WHITE));
|
gameEngine.addComponent(newEnt, TextRender.class, new TextRender("", 24, Color.WHITE));
|
||||||
gameEngine.addComponent(newEnt, Render.class, new Render(TextRender.class));
|
gameEngine.addComponent(newEnt, Render.class, new Render(TextRender.class));
|
||||||
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));
|
||||||
// Other objects
|
|
||||||
|
/* // 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 < 20; i++) {
|
for (int i = 0; i < 500; i++) {
|
||||||
newEnt = gameEngine.createEntity();
|
newEnt = gameEngine.createEntity();
|
||||||
|
double size = 1 + rand.nextDouble();
|
||||||
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(10 + rand.nextDouble()* 80, 10+ rand.nextDouble()* 80,0));
|
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.));
|
gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(-2.5 + rand.nextDouble()* 5., 0., 0., 0., 0.f, 0.3, 2. * size));
|
||||||
double size = 3 + rand.nextDouble() * 7;
|
|
||||||
gameEngine.addComponent(newEnt, Collider.class, new Collider(size, size));
|
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, Gravity.class, new Gravity(0, -9.80665, 45., 45.)); // Terminal velocity is 45 m/s
|
||||||
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, 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(5 + rand.nextDouble() * 90));
|
gameEngine.addComponent(newEnt, TimedExistence.class, new TimedExistence(25 + rand.nextDouble() * 90));
|
||||||
}
|
} */
|
||||||
|
|
||||||
//gameEngine.addComponent(newEnt, LogUpdate.class, null);
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
** Run init() on the systems **
|
||||||
|
*************************************/
|
||||||
physicsSystem.init();
|
physicsSystem.init();
|
||||||
collisionSystem.init();
|
collisionSystem.init();
|
||||||
logUpdateSystem.init();
|
logUpdateSystem.init();
|
||||||
@ -122,32 +134,33 @@ public final class App {
|
|||||||
existenceSystem.init();
|
existenceSystem.init();
|
||||||
reportSystem.init();
|
reportSystem.init();
|
||||||
|
|
||||||
|
|
||||||
|
/************************************
|
||||||
|
** Prepare and enter the game loop **
|
||||||
|
*************************************/
|
||||||
double dt = 0.001;
|
double dt = 0.001;
|
||||||
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
|
||||||
double idleTime = 0.0; // the amount of time spent sleeping
|
|
||||||
|
|
||||||
boolean exit = false;
|
boolean exit = false;
|
||||||
long loopStart = System.currentTimeMillis();
|
|
||||||
long startTime = System.nanoTime();
|
long startTime = System.nanoTime();
|
||||||
while (!exit){
|
while (!exit){
|
||||||
|
// Run system updates
|
||||||
collisionSystem.update();
|
collisionSystem.update();
|
||||||
physicsSystem.update(dt);
|
physicsSystem.update(dt);
|
||||||
existenceSystem.update(dt);
|
existenceSystem.update(dt);
|
||||||
reportSystem.update();
|
reportSystem.update();
|
||||||
//logUpdateSystem.update();
|
|
||||||
// The render system should be uncoupled from the physics and collision
|
|
||||||
renderSystem.update();
|
renderSystem.update();
|
||||||
|
|
||||||
dt = (System.nanoTime() - startTime) / 1e9; // convert nanoseconds to seconds
|
dt = (System.nanoTime() - startTime) / 1e9; // convert nanoseconds to seconds
|
||||||
startTime = System.nanoTime();
|
startTime = System.nanoTime();
|
||||||
if (dt < frameRate){
|
if (dt < frameRate){
|
||||||
idleTime = frameRate-dt;
|
|
||||||
Thread.sleep((int)((frameRate-dt)*1000));
|
Thread.sleep((int)((frameRate-dt)*1000));
|
||||||
dt = (System.nanoTime() - startTime) / 1e9;
|
dt = (System.nanoTime() - startTime) / 1e9;
|
||||||
startTime = System.nanoTime();
|
startTime = System.nanoTime();
|
||||||
}
|
}
|
||||||
dt = 0.001;
|
// Setting dt here to a fixed time-step will lock the rate of the physics. The above code ensures that it is
|
||||||
|
// executed no more than once 1/framerate seconds.
|
||||||
|
// dt = 0.001;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,4 @@ public class Collider {
|
|||||||
// bottom-right, top-right is specified by position
|
// bottom-right, top-right is specified by position
|
||||||
public double x = 0.0;
|
public double x = 0.0;
|
||||||
public double y = 0.0;
|
public double y = 0.0;
|
||||||
public boolean collided = false;
|
|
||||||
|
|
||||||
public double travelDirection = 0.0;
|
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,4 @@ package nz.ac.massey.javaecs.examples.Components;
|
|||||||
|
|
||||||
public class Reporter {
|
public class Reporter {
|
||||||
|
|
||||||
}
|
}
|
@ -1,11 +1,8 @@
|
|||||||
package nz.ac.massey.javaecs.examples.Systems;
|
package nz.ac.massey.javaecs.examples.Systems;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import nz.ac.massey.javaecs.ECSSystem;
|
import nz.ac.massey.javaecs.ECSSystem;
|
||||||
import nz.ac.massey.javaecs.Engine;
|
import nz.ac.massey.javaecs.Engine;
|
||||||
@ -29,170 +26,98 @@ public class CollisionSystem extends ECSSystem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
public void updateNew() {
|
|
||||||
Set<Entity> processed = new HashSet<>();
|
|
||||||
// Gets all items we have collided with
|
|
||||||
for (Entity entity : entities) {
|
|
||||||
RidgidBody ridgidBody = (RidgidBody) gameEngine.getComponentData(entity, RidgidBody.class);
|
|
||||||
// Only considering elements with mass just now
|
|
||||||
if (ridgidBody.mass > 0){
|
|
||||||
Vec2D pos = (Vec2D) gameEngine.getComponentData(entity, Vec2D.class);
|
|
||||||
Collider collider = (Collider) gameEngine.getComponentData(entity, Collider.class);
|
|
||||||
|
|
||||||
// The pos of each bounding line of the entity
|
|
||||||
// i.e.
|
|
||||||
//
|
|
||||||
// -------------
|
|
||||||
// |###########|
|
|
||||||
// |###########|
|
|
||||||
// |###########|
|
|
||||||
// |###########|
|
|
||||||
// -------------
|
|
||||||
//
|
|
||||||
double eleft = pos.x;
|
|
||||||
double ebottom = pos.y;
|
|
||||||
double eright = pos.x + collider.x;
|
|
||||||
double etop = pos.y + collider.y;
|
|
||||||
|
|
||||||
double evectorAngle = calcAngle(ridgidBody.xVel, ridgidBody.yVel);
|
|
||||||
|
|
||||||
|
|
||||||
if (ridgidBody.mass > 0){
|
|
||||||
// Dont't recalc for entities that aren't static
|
|
||||||
processed.add(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Entity entity2 : entities) {
|
|
||||||
if (!processed.contains(entity2)) {
|
|
||||||
// skip entities that have already been processed
|
|
||||||
Vec2D oPos = (Vec2D) gameEngine.getComponentData(entity2, Vec2D.class);
|
|
||||||
RidgidBody oRidgidBody = (RidgidBody) gameEngine.getComponentData(entity2, RidgidBody.class);
|
|
||||||
Collider oCollider = (Collider) gameEngine.getComponentData(entity2, Collider.class);
|
|
||||||
|
|
||||||
double oleft = oPos.x;
|
|
||||||
double obottom = oPos.y;
|
|
||||||
double oright = oPos.x + oCollider.x;
|
|
||||||
double otop = oPos.y + oCollider.y;
|
|
||||||
|
|
||||||
// Check if a collision occured
|
|
||||||
// Few conditions required, that is,
|
|
||||||
// - oS2 must be greater than eS0, else they aren't close
|
|
||||||
// - eS2 must be greater than oS0, for the same reason
|
|
||||||
// - either
|
|
||||||
if (!(eleft > oright || oleft > eright || etop < obottom || otop < ebottom)){
|
|
||||||
// Collided
|
|
||||||
// Grab the angle the other is moving, to figure the quadrant to move to
|
|
||||||
double ovectorAngle = calcAngle(oRidgidBody.xVel, oRidgidBody.yVel);
|
|
||||||
// Grab the vector sums
|
|
||||||
double xVelSum = ridgidBody.xVel + oRidgidBody.xVel;
|
|
||||||
double yVelSum = ridgidBody.yVel + oRidgidBody.yVel;
|
|
||||||
// Collision occurred
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// with no major performance issues
|
||||||
|
// Replace this with a proper system as required
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
// Parallelising this loop ()
|
|
||||||
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) {
|
||||||
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);
|
//processed.add(entity);
|
||||||
}
|
for (Entity entity2 : entities) {
|
||||||
for (Entity entity2 : entities) {
|
if (!processed.contains(entity2)) {
|
||||||
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 (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 + otherCollider.y;
|
&& pos.y + collider.y > otherPos.y
|
||||||
// Evaluate a collision in the bottom-right
|
&& pos.y + collider.y < otherPos.y + otherCollider.y;
|
||||||
boolean brCollide = pos.x + collider.x > otherPos.x
|
// Evaluate a collision in the bottom-right
|
||||||
&& pos.x + collider.x < otherPos.x + otherCollider.x && pos.y + collider.y > otherPos.y
|
boolean brCollide = pos.x + collider.x > otherPos.x
|
||||||
&& pos.y + collider.y < otherPos.y + otherCollider.y;
|
&& pos.x + collider.x < otherPos.x + otherCollider.x
|
||||||
// Evaluate a collision in the top-right
|
&& pos.y + collider.y > otherPos.y
|
||||||
boolean trCollide = pos.x + collider.x > otherPos.x
|
&& pos.y + collider.y < otherPos.y + otherCollider.y;
|
||||||
&& pos.x + collider.x < otherPos.x + otherCollider.x && pos.y > otherPos.y
|
// Evaluate a collision in the top-right
|
||||||
&& pos.y < otherPos.y + otherCollider.y;
|
boolean trCollide = pos.x + collider.x > otherPos.x
|
||||||
if (tlCollide || blCollide || brCollide || trCollide) {
|
&& pos.x + collider.x < otherPos.x + otherCollider.x && pos.y > otherPos.y
|
||||||
// Determine collision nature
|
&& pos.y < otherPos.y + otherCollider.y;
|
||||||
if (tlCollide) {
|
if (tlCollide || blCollide || brCollide || trCollide) {
|
||||||
int k = 0;
|
// Get the vels
|
||||||
}
|
double totalXVel = Math.abs(ridgidBody.xVel) + Math.abs(otherRidgidBody.xVel);
|
||||||
if (trCollide) {
|
double totalYVel = Math.abs(ridgidBody.yVel) + Math.abs(otherRidgidBody.yVel);
|
||||||
int k = 0;
|
double xMult = 0;
|
||||||
}
|
double yMult = 0;
|
||||||
if (blCollide) {
|
double multTot = (1 + ridgidBody.bounciness);
|
||||||
int k = 0;
|
double totalMass = ridgidBody.mass + otherRidgidBody.mass;
|
||||||
}
|
boolean fullEdge = false;
|
||||||
if (brCollide) {
|
// left-hand collision
|
||||||
int k = 0;
|
if (tlCollide && blCollide) {
|
||||||
}
|
fullEdge = true;
|
||||||
// Get the vels
|
pos.x = otherPos.x + otherCollider.x;
|
||||||
double totalXVel = Math.abs(ridgidBody.xVel) + Math.abs(otherRidgidBody.xVel);
|
xMult = multTot;
|
||||||
double totalYVel = Math.abs(ridgidBody.yVel) + Math.abs(otherRidgidBody.yVel);
|
}
|
||||||
double totalMass = ridgidBody.mass + otherRidgidBody.mass;
|
// right-hand collision
|
||||||
int xMult = 0;
|
else if (brCollide && trCollide) {
|
||||||
int yMult = 0;
|
fullEdge = true;
|
||||||
boolean fullEdge = false;
|
pos.x = otherPos.x - collider.x;
|
||||||
// left-hand collision
|
xMult = -multTot;
|
||||||
if (tlCollide && blCollide) {
|
}
|
||||||
fullEdge = true;
|
// Bottom collision
|
||||||
xMult = 2;
|
if (blCollide && brCollide) {
|
||||||
}
|
fullEdge = true;
|
||||||
// Bottom collision
|
//pos.y = otherPos.y + otherCollider.y;
|
||||||
if (blCollide && brCollide) {
|
pos.y = otherPos.y - collider.y;
|
||||||
fullEdge = true;
|
yMult = -multTot;
|
||||||
yMult = -2;
|
}
|
||||||
}
|
// top collision
|
||||||
// right-hand collision
|
else if (trCollide && tlCollide) {
|
||||||
if (brCollide && trCollide) {
|
fullEdge = true;
|
||||||
fullEdge = true;
|
//pos.y = otherPos.y - collider.y;
|
||||||
xMult = -2;
|
pos.y = otherPos.y + otherCollider.y;
|
||||||
}
|
yMult = multTot;
|
||||||
// top collision
|
}
|
||||||
if (trCollide && tlCollide) {
|
if (fullEdge) {
|
||||||
fullEdge = true;
|
// Finally, actuate the calculation
|
||||||
yMult = 2;
|
|
||||||
}
|
|
||||||
if (fullEdge) {
|
|
||||||
// Finally, actuate the calculation
|
|
||||||
if (ridgidBody.mass < 0) {
|
|
||||||
// entity 1 is immovable
|
|
||||||
otherRidgidBody.xVel += totalXVel * (-1 * xMult);
|
|
||||||
otherRidgidBody.yVel += totalYVel * (-1 * yMult);
|
|
||||||
|
|
||||||
Object grav = gameEngine.getComponentData(entity, Gravity.class);
|
|
||||||
if (grav != null) {
|
|
||||||
Gravity gravity = (Gravity) grav;
|
|
||||||
otherRidgidBody.xAcc += gravity.x * -1.;
|
|
||||||
otherRidgidBody.yAcc += gravity.y * -1.;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (otherRidgidBody.mass < 0) {
|
|
||||||
// entity 2 is immovable; full acceleration applied to the current entity
|
// entity 2 is immovable; full acceleration applied to the current entity
|
||||||
ridgidBody.xVel += totalXVel * xMult;
|
|
||||||
ridgidBody.yVel += totalYVel * yMult;
|
if (otherRidgidBody.mass > 0){
|
||||||
|
ridgidBody.xVel += totalXVel * xMult * ((totalMass - ridgidBody.mass) / totalMass);
|
||||||
|
ridgidBody.yVel += totalYVel * yMult * ((totalMass - ridgidBody.mass) / totalMass);
|
||||||
|
|
||||||
|
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);
|
Object grav = gameEngine.getComponentData(entity, Gravity.class);
|
||||||
if (grav != null) {
|
if (grav != null) {
|
||||||
// negate gravity while collided
|
// negate gravity while collided
|
||||||
@ -200,53 +125,36 @@ public class CollisionSystem extends ECSSystem {
|
|||||||
ridgidBody.xAcc += gravity.x * -1.;
|
ridgidBody.xAcc += gravity.x * -1.;
|
||||||
ridgidBody.yAcc += gravity.y * -1.;
|
ridgidBody.yAcc += gravity.y * -1.;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// collision is elastic; add the forces x & y and the masses, and share between
|
|
||||||
// objects
|
|
||||||
/*ridgidBody.xVel += (ridgidBody.mass / totalMass) * totalXVel * xMult;
|
|
||||||
otherRidgidBody.xVel += (otherRidgidBody.mass / totalMass) * totalXVel
|
|
||||||
* (-1 * xMult);
|
|
||||||
|
|
||||||
ridgidBody.yVel += (ridgidBody.mass / totalMass) * totalYVel * yMult;
|
|
||||||
otherRidgidBody.yVel += (otherRidgidBody.mass / totalMass) * totalYVel
|
|
||||||
* (-1 * yMult);*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zero degrees is straight up,
|
* Zero degrees is straight up, 90 east -90 (270) = west 180 south
|
||||||
* 90 east
|
*
|
||||||
* -90 (270) = west
|
|
||||||
* 180 south
|
|
||||||
* @param xVel
|
* @param xVel
|
||||||
* @param yVel
|
* @param yVel
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static double calcAngle(double xVel, double yVel){
|
public static double calcAngle(double xVel, double yVel) {
|
||||||
if (xVel == 0){ // Div zero; = +- 90
|
if (xVel == 0) { // Div zero; = +- 90
|
||||||
return yVel < 0 ? 270 : 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);
|
||||||
}
|
}
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ import nz.ac.massey.javaecs.Entity;
|
|||||||
import nz.ac.massey.javaecs.examples.Components.BoxRender;
|
import nz.ac.massey.javaecs.examples.Components.BoxRender;
|
||||||
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.Gravity;
|
||||||
import nz.ac.massey.javaecs.examples.Components.LogUpdate;
|
|
||||||
import nz.ac.massey.javaecs.examples.Components.Render;
|
import nz.ac.massey.javaecs.examples.Components.Render;
|
||||||
import nz.ac.massey.javaecs.examples.Components.RidgidBody;
|
import nz.ac.massey.javaecs.examples.Components.RidgidBody;
|
||||||
import nz.ac.massey.javaecs.examples.Components.TimedExistence;
|
import nz.ac.massey.javaecs.examples.Components.TimedExistence;
|
||||||
@ -32,13 +31,10 @@ public class ExistenceSystem extends ECSSystem{
|
|||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
rand = new Random();
|
rand = new Random();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(double dt){
|
public void update(double dt){
|
||||||
@ -47,10 +43,10 @@ public class ExistenceSystem extends ECSSystem{
|
|||||||
BoxRender shape = (BoxRender)gameEngine.getComponentData(entity, BoxRender.class);
|
BoxRender shape = (BoxRender)gameEngine.getComponentData(entity, BoxRender.class);
|
||||||
TimedExistence timedExistence = (TimedExistence)gameEngine.getComponentData(entity, TimedExistence.class);
|
TimedExistence timedExistence = (TimedExistence)gameEngine.getComponentData(entity, TimedExistence.class);
|
||||||
// Get the rate the fade should occur at our current frame rate.
|
// Get the rate the fade should occur at our current frame rate.
|
||||||
double fadeRate = timedExistence.lifeTime / dt; // I.e. might say 200 frames left
|
double fadeRate = timedExistence.lifeTime / dt;
|
||||||
// Fade the opacity
|
// Fade the opacity
|
||||||
shape.a -= shape.a / fadeRate;
|
shape.a -= shape.a / fadeRate;
|
||||||
// Clauses to keep things safe
|
// Keep the alpha between 0-1
|
||||||
if (shape.a < 0) shape.a = 0.;
|
if (shape.a < 0) shape.a = 0.;
|
||||||
else if (shape.a > 1) shape.a = 1.;
|
else if (shape.a > 1) shape.a = 1.;
|
||||||
// Reduce the time the shape may continue living for
|
// Reduce the time the shape may continue living for
|
||||||
@ -60,15 +56,18 @@ public class ExistenceSystem extends ECSSystem{
|
|||||||
deletions.add(entity);
|
deletions.add(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// As we were using the iterator to traverse entities, we could not delete them as we read them.
|
||||||
while (deletions.size() > 0){
|
while (deletions.size() > 0){
|
||||||
gameEngine.destroyEntity(deletions.remove());
|
gameEngine.destroyEntity(deletions.remove());
|
||||||
}
|
}
|
||||||
// Finally, randomly add an entity as required
|
// Finally, randomly add an entity as required
|
||||||
if (rand.nextInt(16384) < 8){
|
int newRate = gameEngine.getNumEntities();
|
||||||
|
newRate = newRate < 13 ? 7 - newRate / 2 : 1;
|
||||||
|
if (rand.nextInt(2048) <= 1*newRate){
|
||||||
Entity newEnt = gameEngine.createEntity();
|
Entity newEnt = gameEngine.createEntity();
|
||||||
|
double size = 1 + rand.nextDouble() * 10;
|
||||||
gameEngine.addComponent(newEnt, Vec2D.class, new Vec2D(10 + rand.nextDouble()* 80, 10+ rand.nextDouble()* 80,0));
|
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.));
|
gameEngine.addComponent(newEnt, RidgidBody.class, new RidgidBody(-2.5 + rand.nextDouble()* 5., 0., 0., 0., 0.f, 0.75, 2. * size));
|
||||||
double size = 3 + rand.nextDouble() * 7;
|
|
||||||
gameEngine.addComponent(newEnt, Collider.class, new Collider(size, size));
|
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, 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, Render.class, new Render(BoxRender.class));
|
||||||
|
@ -40,7 +40,6 @@ public class PhysicsSystem extends ECSSystem {
|
|||||||
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);
|
||||||
Gravity gravity = (Gravity)gameEngine.getComponentData(entity, Gravity.class);
|
Gravity gravity = (Gravity)gameEngine.getComponentData(entity, Gravity.class);
|
||||||
Collider collider = (Collider)gameEngine.getComponentData(entity, Collider.class);
|
|
||||||
// Firstly, add the result of the accelerative forces to the ridgidbody
|
// Firstly, add the result of the accelerative forces to the ridgidbody
|
||||||
ridgidBody.xVel += ridgidBody.xAcc * dt;
|
ridgidBody.xVel += ridgidBody.xAcc * dt;
|
||||||
ridgidBody.yVel += ridgidBody.yAcc * dt;
|
ridgidBody.yVel += ridgidBody.yAcc * dt;
|
||||||
@ -49,14 +48,12 @@ public class PhysicsSystem extends ECSSystem {
|
|||||||
ridgidBody.xAcc = 0.;
|
ridgidBody.xAcc = 0.;
|
||||||
ridgidBody.yAcc = 0.;
|
ridgidBody.yAcc = 0.;
|
||||||
|
|
||||||
if (!collider.collided){
|
// Special case of gravity
|
||||||
// Special case of gravity
|
if (gravity.terminalX < 0 || Math.abs(ridgidBody.xVel) < gravity.terminalX){
|
||||||
if (gravity.terminalX < 0 || Math.abs(ridgidBody.xVel) < gravity.terminalX){
|
ridgidBody.xAcc += gravity.x;
|
||||||
ridgidBody.xAcc += gravity.x;
|
}
|
||||||
}
|
if (gravity.terminalY < 0 || Math.abs(ridgidBody.yVel) < gravity.terminalY){
|
||||||
if (gravity.terminalY < 0 || Math.abs(ridgidBody.yVel) < gravity.terminalY){
|
ridgidBody.yAcc += gravity.y;
|
||||||
ridgidBody.yAcc += gravity.y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,11 +4,9 @@ import java.util.BitSet;
|
|||||||
|
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.concurrent.Task;
|
|
||||||
import javafx.scene.Group;
|
import javafx.scene.Group;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.paint.Color;
|
import javafx.scene.paint.Color;
|
||||||
import javafx.scene.paint.Paint;
|
|
||||||
import javafx.scene.shape.Rectangle;
|
import javafx.scene.shape.Rectangle;
|
||||||
import javafx.scene.text.Font;
|
import javafx.scene.text.Font;
|
||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
@ -40,23 +38,15 @@ public class RenderSystem extends ECSSystem{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
// Spawn a new thread
|
// Spawn a new asynchronous thread (won't rejoin the main program flow)
|
||||||
renderThread = new Thread(new RenderStarter());
|
renderThread = new Thread(new RenderStarter());
|
||||||
renderThread.start(); // this thread is asynchronous, it isn't expected to rejoin
|
renderThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
/* while (JFXView.root == null){
|
|
||||||
try {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
Group renderScene = new Group();
|
Group renderScene = new Group();
|
||||||
for (Entity entity : entities) {
|
for (Entity entity : entities) {
|
||||||
//Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class);
|
|
||||||
if (((Render)gameEngine.getComponentData(entity, Render.class)).renderType == BoxRender.class){
|
if (((Render)gameEngine.getComponentData(entity, Render.class)).renderType == BoxRender.class){
|
||||||
BoxRender box = (BoxRender)gameEngine.getComponentData(entity, BoxRender.class);
|
BoxRender box = (BoxRender)gameEngine.getComponentData(entity, BoxRender.class);
|
||||||
Vec2D vec2d = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class);
|
Vec2D vec2d = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class);
|
||||||
@ -77,6 +67,9 @@ public class RenderSystem extends ECSSystem{
|
|||||||
renderScene.getChildren().add(t);
|
renderScene.getChildren().add(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Must be run by the UI thread, not the main thread.
|
||||||
|
// This dispatches the operation run() to the UI.
|
||||||
Platform.runLater(new Runnable(){
|
Platform.runLater(new Runnable(){
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -87,7 +80,6 @@ public class RenderSystem extends ECSSystem{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add a renderer
|
// Add a renderer
|
||||||
|
|
||||||
public class RenderStarter implements Runnable{
|
public class RenderStarter implements Runnable{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -109,7 +101,6 @@ public class RenderSystem extends ECSSystem{
|
|||||||
root = new Group();
|
root = new Group();
|
||||||
Scene scene = new Scene(root, 1024, 1024, Color.BLACK);
|
Scene scene = new Scene(root, 1024, 1024, Color.BLACK);
|
||||||
primaryStage.setScene(scene);
|
primaryStage.setScene(scene);
|
||||||
|
|
||||||
primaryStage.show();
|
primaryStage.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,6 @@ public class ReportSystem extends ECSSystem{
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user