2015-05-08 20:18:12 +02:00
|
|
|
package com.saltosion.gladiator.systems;
|
|
|
|
|
|
|
|
import com.badlogic.ashley.core.ComponentMapper;
|
|
|
|
import com.badlogic.ashley.core.Engine;
|
|
|
|
import com.badlogic.ashley.core.Entity;
|
|
|
|
import com.badlogic.ashley.core.EntitySystem;
|
|
|
|
import com.badlogic.ashley.core.Family;
|
|
|
|
import com.badlogic.ashley.utils.ImmutableArray;
|
2015-05-10 22:33:41 +02:00
|
|
|
import com.saltosion.gladiator.components.CCombat;
|
2015-05-08 20:18:12 +02:00
|
|
|
import com.saltosion.gladiator.components.CPhysics;
|
2015-05-10 17:35:38 +02:00
|
|
|
import com.saltosion.gladiator.util.Direction;
|
2015-05-08 20:18:12 +02:00
|
|
|
|
|
|
|
public class PhysicsSystem extends EntitySystem {
|
|
|
|
|
2015-05-16 21:50:47 +02:00
|
|
|
private static final float MAX_VEL = 1.75f, COLLISION_PRECISION = 12f, UPDATES_PER_SECOND = 240f;
|
2015-05-11 22:18:38 +02:00
|
|
|
|
|
|
|
private static final ComponentMapper<CPhysics> pm = ComponentMapper.getFor(CPhysics.class);
|
|
|
|
private static final ComponentMapper<CCombat> cm = ComponentMapper.getFor(CCombat.class);
|
2015-05-10 00:09:54 +02:00
|
|
|
private ImmutableArray<Entity> entities;
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void addedToEngine(Engine engine) {
|
|
|
|
updateEntities(engine);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void update(float deltaTime) {
|
2015-05-13 22:40:57 +02:00
|
|
|
float freq = 1f / UPDATES_PER_SECOND;
|
|
|
|
int times = (int) Math.ceil(deltaTime / freq);
|
|
|
|
deltaTime /= (float) times;
|
|
|
|
for (int t = 0; t < times; t++) {
|
|
|
|
for (int i = 0; i < entities.size(); i++) {
|
|
|
|
CPhysics obj = pm.get(entities.get(i));
|
|
|
|
CCombat combat = cm.get(entities.get(i));
|
|
|
|
|
|
|
|
// Apply movement
|
|
|
|
obj.getPosition().add(Math.max(Math.min(obj.getVelocity().x * deltaTime, MAX_VEL), -MAX_VEL),
|
|
|
|
Math.max(Math.min(obj.getVelocity().y * deltaTime, MAX_VEL), -MAX_VEL));
|
|
|
|
|
|
|
|
// Movement
|
|
|
|
if (obj.isMovable()) {
|
|
|
|
float move = 0;
|
|
|
|
if (obj.movingLeft) {
|
|
|
|
move--;
|
2015-05-16 20:28:45 +02:00
|
|
|
obj.movedLeftLast = true;
|
2015-05-13 22:40:57 +02:00
|
|
|
}
|
|
|
|
if (obj.movingRight) {
|
|
|
|
move++;
|
2015-05-16 20:28:45 +02:00
|
|
|
obj.movedLeftLast = false;
|
2015-05-13 22:40:57 +02:00
|
|
|
}
|
|
|
|
obj.getVelocity().x = move * obj.getMovespeed();
|
|
|
|
if (combat != null) {
|
|
|
|
if (combat.swingCdCounter > 0) {
|
|
|
|
obj.getVelocity().x /= 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (obj.jumping && obj.isGrounded()) {
|
|
|
|
obj.setGrounded(false);
|
|
|
|
obj.getVelocity().y = obj.getJumpForce();
|
2015-05-10 22:33:41 +02:00
|
|
|
}
|
|
|
|
}
|
2015-05-10 00:09:54 +02:00
|
|
|
|
2015-05-13 22:40:57 +02:00
|
|
|
// Gravity
|
|
|
|
if (obj.isGravityApplied()) {
|
|
|
|
obj.getVelocity().y -= obj.getGravity() * deltaTime;
|
|
|
|
}
|
2015-05-10 00:09:54 +02:00
|
|
|
|
2015-05-13 22:40:57 +02:00
|
|
|
// Collisions
|
|
|
|
if (obj.isProcessCollisions()) {
|
|
|
|
for (int j = 0; j < entities.size(); j++) {
|
|
|
|
if (i == j) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
collision(entities.get(i), entities.get(j));
|
2015-05-10 00:09:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void collision(Entity entity0, Entity entity1) {
|
|
|
|
CPhysics cp0 = pm.get(entity0);
|
|
|
|
CPhysics cp1 = pm.get(entity1);
|
|
|
|
|
2015-05-10 17:30:57 +02:00
|
|
|
float x00 = cp0.getPosition().x - cp0.getSize().x / 2;
|
|
|
|
float x01 = cp0.getPosition().x + cp0.getSize().x / 2;
|
|
|
|
float x10 = cp1.getPosition().x - cp1.getSize().x / 2;
|
|
|
|
float x11 = cp1.getPosition().x + cp1.getSize().x / 2;
|
|
|
|
float y00 = cp0.getPosition().y - cp0.getSize().y / 2;
|
|
|
|
float y01 = cp0.getPosition().y + cp0.getSize().y / 2;
|
|
|
|
float y10 = cp1.getPosition().y - cp1.getSize().y / 2;
|
|
|
|
float y11 = cp1.getPosition().y + cp1.getSize().y / 2;
|
2015-05-10 00:09:54 +02:00
|
|
|
|
|
|
|
boolean colliding = (x00 < x11) && (x01 > x10) && (y00 < y11) && (y01 > y10);
|
|
|
|
|
|
|
|
if (!colliding) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-05-10 20:34:57 +02:00
|
|
|
boolean collidedAlready = false;
|
2015-05-16 21:28:56 +02:00
|
|
|
float precisionX = COLLISION_PRECISION * (float) Math.sqrt(cp0.getSize().x > cp1.getSize().x ? cp0.getSize().x : cp1.getSize().x);
|
|
|
|
float precisionY = COLLISION_PRECISION * (float) Math.sqrt(cp0.getSize().y > cp1.getSize().y ? cp0.getSize().y : cp1.getSize().y);
|
2015-05-10 20:34:57 +02:00
|
|
|
|
2015-05-16 20:50:19 +02:00
|
|
|
if (x00 <= x11 && Math.abs(x00 - x11) < (cp0.getSize().x + cp1.getSize().x) / precisionX) {
|
2015-05-10 00:09:54 +02:00
|
|
|
// cp0's left side is colliding with cp1's right side
|
2015-05-10 17:30:57 +02:00
|
|
|
if (!cp0.isGhost() && !cp1.isGhost()) {
|
|
|
|
if (cp0.getVelocity().x < 0) {
|
2015-05-10 16:30:31 +02:00
|
|
|
// cp0 is going left, stop
|
2015-05-10 17:30:57 +02:00
|
|
|
cp0.getVelocity().x = 0;
|
2015-05-10 16:30:31 +02:00
|
|
|
}
|
2015-05-13 22:40:57 +02:00
|
|
|
cp0.getPosition().x += x11 - x00;
|
2015-05-10 00:09:54 +02:00
|
|
|
}
|
|
|
|
|
2015-05-10 17:30:57 +02:00
|
|
|
if (cp0.getCollisionListener() != null) {
|
2015-05-10 17:35:38 +02:00
|
|
|
cp0.getCollisionListener().collision(Direction.LEFT, entity0, entity1);
|
2015-05-10 00:09:54 +02:00
|
|
|
}
|
2015-05-10 20:34:57 +02:00
|
|
|
collidedAlready = true;
|
2015-05-10 00:09:54 +02:00
|
|
|
}
|
2015-05-16 20:50:19 +02:00
|
|
|
if (x01 > x10 && Math.abs(x01 - x10) < (cp0.getSize().x + cp1.getSize().x) / precisionX) {
|
2015-05-10 00:09:54 +02:00
|
|
|
// cp0's right side is colliding with cp1's left side
|
2015-05-10 17:30:57 +02:00
|
|
|
if (!cp0.isGhost() && !cp1.isGhost()) {
|
|
|
|
if (cp0.getVelocity().x > 0) {
|
2015-05-10 16:30:31 +02:00
|
|
|
// cp0 is going right, stop
|
2015-05-10 17:30:57 +02:00
|
|
|
cp0.getVelocity().x = 0;
|
2015-05-10 16:30:31 +02:00
|
|
|
}
|
2015-05-13 22:40:57 +02:00
|
|
|
cp0.getPosition().x += x10 - x01;
|
2015-05-10 00:09:54 +02:00
|
|
|
}
|
|
|
|
|
2015-05-10 17:30:57 +02:00
|
|
|
if (cp0.getCollisionListener() != null) {
|
2015-05-10 17:35:38 +02:00
|
|
|
cp0.getCollisionListener().collision(Direction.RIGHT, entity0, entity1);
|
2015-05-10 00:09:54 +02:00
|
|
|
}
|
2015-05-10 20:34:57 +02:00
|
|
|
collidedAlready = true;
|
2015-05-10 00:09:54 +02:00
|
|
|
}
|
2015-05-16 20:50:19 +02:00
|
|
|
if (y00 <= y11 && Math.abs(y00 - y11) < (cp0.getSize().y + cp1.getSize().y) / precisionY) {
|
2015-05-10 00:09:54 +02:00
|
|
|
// cp0's bottom side is colliding with cp1's top side
|
2015-05-10 17:30:57 +02:00
|
|
|
if (!cp0.isGhost() && !cp1.isGhost()) {
|
|
|
|
if (cp0.getVelocity().y < 0) {
|
2015-05-10 16:30:31 +02:00
|
|
|
// cp0 is going down, stop
|
2015-05-10 17:30:57 +02:00
|
|
|
cp0.getVelocity().y = 0;
|
2015-05-10 16:30:31 +02:00
|
|
|
}
|
2015-05-10 17:30:57 +02:00
|
|
|
cp0.setGrounded(true);
|
|
|
|
cp0.getPosition().y += y11 - y00;
|
2015-05-10 00:09:54 +02:00
|
|
|
}
|
|
|
|
|
2015-05-10 17:30:57 +02:00
|
|
|
if (cp0.getCollisionListener() != null) {
|
2015-05-10 17:35:38 +02:00
|
|
|
cp0.getCollisionListener().collision(Direction.DOWN, entity0, entity1);
|
2015-05-10 00:09:54 +02:00
|
|
|
}
|
2015-05-10 20:34:57 +02:00
|
|
|
collidedAlready = true;
|
2015-05-10 00:09:54 +02:00
|
|
|
}
|
2015-05-16 20:50:19 +02:00
|
|
|
if (y01 > y10 && Math.abs(y01 - y10) < (cp0.getSize().y + cp1.getSize().y) / precisionY) {
|
2015-05-10 00:09:54 +02:00
|
|
|
// cp0's top side is colliding with cp1's bottom side
|
2015-05-10 17:30:57 +02:00
|
|
|
if (!cp0.isGhost() && !cp1.isGhost()) {
|
|
|
|
if (cp0.getVelocity().y > 0) {
|
2015-05-10 16:30:31 +02:00
|
|
|
// cp0 is going up, stop
|
2015-05-10 17:30:57 +02:00
|
|
|
cp0.getVelocity().y = 0;
|
2015-05-10 16:30:31 +02:00
|
|
|
}
|
2015-05-13 22:48:40 +02:00
|
|
|
cp0.getPosition().y += y10 - y01;
|
2015-05-10 00:09:54 +02:00
|
|
|
}
|
|
|
|
|
2015-05-10 17:30:57 +02:00
|
|
|
if (cp0.getCollisionListener() != null) {
|
2015-05-10 17:35:38 +02:00
|
|
|
cp0.getCollisionListener().collision(Direction.UP, entity0, entity1);
|
2015-05-10 00:09:54 +02:00
|
|
|
}
|
2015-05-10 20:34:57 +02:00
|
|
|
collidedAlready = true;
|
|
|
|
}
|
|
|
|
if (!collidedAlready && cp0.getCollisionListener() != null) {
|
|
|
|
cp0.getCollisionListener().collision(Direction.CENTRE, entity0, entity1);
|
2015-05-10 00:09:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void updateEntities(Engine engine) {
|
|
|
|
entities = engine.getEntitiesFor(Family.getFor(CPhysics.class));
|
|
|
|
}
|
2015-05-08 20:18:12 +02:00
|
|
|
|
|
|
|
}
|