diff --git a/android/assets/levels/plevel001.tmx b/android/assets/levels/plevel001.tmx index 1fa10c6..d65c30c 100644 --- a/android/assets/levels/plevel001.tmx +++ b/android/assets/levels/plevel001.tmx @@ -4032,7 +4032,7 @@ - + @@ -4537,6 +4537,8 @@ + + @@ -4658,6 +4660,504 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5037,129 +5537,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -5283,383 +5660,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -9158,7 +9158,7 @@ - + @@ -9653,13 +9653,13 @@ - - - - - - - + + + + + + + @@ -14158,10 +14158,510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -14658,10 +15158,6 @@ - - - - @@ -15023,6 +15519,10 @@ + + + + @@ -15158,10 +15658,6 @@ - - - - @@ -15523,6 +16019,10 @@ + + + + @@ -15658,10 +16158,6 @@ - - - - @@ -16023,6 +16519,10 @@ + + + + @@ -16158,10 +16658,6 @@ - - - - @@ -16523,6 +17019,10 @@ + + + + @@ -16658,10 +17158,6 @@ - - - - @@ -17023,6 +17519,10 @@ + + + + @@ -17158,10 +17658,6 @@ - - - - @@ -17523,6 +18019,10 @@ + + + + @@ -17658,10 +18158,6 @@ - - - - @@ -18023,6 +18519,10 @@ + + + + @@ -18158,10 +18658,6 @@ - - - - @@ -18523,6 +19019,10 @@ + + + + @@ -18658,371 +19158,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -19162,7 +19302,6 @@ - @@ -19662,145 +19801,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/src/de/samdev/colorrunner/game/world/entities/MovingEntity.java b/core/src/de/samdev/colorrunner/game/world/entities/MovingEntity.java index 2dae8b7..d26a79a 100644 --- a/core/src/de/samdev/colorrunner/game/world/entities/MovingEntity.java +++ b/core/src/de/samdev/colorrunner/game/world/entities/MovingEntity.java @@ -4,24 +4,24 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; +import de.samdev.colorrunner.CRGame; import de.samdev.colorrunner.game.world.CRGameWorld; public abstract class MovingEntity extends CRGameEntity { protected Vector2 velocity = new Vector2(); - public final static float EPSILON_TOUCH = 4e-5f; - public final static float EPSILON_MOVE = 2e-5f; - public final static float EPSILON_COLLIDE = 1e-5f; + public final static float EPSILON = 1e-8f; + public final static float EPSILON_TOUCH = 5e-8f; - private boolean face_TOP_isTouching = false; - private boolean face_LEFT_isTouching = false; + private boolean face_TOP_isTouching = false; + private boolean face_LEFT_isTouching = false; private boolean face_BOTTOM_isTouching = false; - private boolean face_RIGHT_isTouching = false; - + private boolean face_RIGHT_isTouching = false; + public MovingEntity(CRGameWorld _owner, float width, float height) { this(_owner, 0, 0, width, height); } - + public MovingEntity(CRGameWorld _owner, float x, float y, float width, float height) { super(_owner, x, y, width, height); } @@ -38,44 +38,42 @@ public abstract class MovingEntity extends CRGameEntity { for (CRGameEntity ent : world.entities) { if (ent == this) continue; - if (overlaps(ent.bounds, next, EPSILON_MOVE) && ent.canCollide(true, this)) { + if (overlaps(next, ent.bounds) && ent.canCollide(true, this)) { - if (overlaps(ent.bounds, bounds, EPSILON_COLLIDE)) { - Gdx.app.log("Collision", "Ignore in bounds collision"); + if (overlaps(ent.bounds, bounds)) { + Gdx.app.log("Collision", "Ignore in bounds collision [X]"); continue; } - if (bx < 0) { // DOWN - float correction = (ent.bounds.x + ent.bounds.height) - next.x + EPSILON_MOVE; + if (bx < 0) { // LEFT + float correction = (ent.bounds.x + ent.bounds.height) - next.x + EPSILON; next.x += correction; - bx += correction; + bx = next.x - bounds.x; - if (bx >= -EPSILON_MOVE) - return false; // collision but no movement + if (bx >= 0) return true; // collision but no movement collided = true; - } else { // UP - float correction = ent.bounds.x - (next.x + next.height) - EPSILON_MOVE; + } else { // RIGHT + float correction = (next.x + next.height) - ent.bounds.x + EPSILON; - next.x += correction; - bx += correction; + next.x -= correction; + bx = next.x - bounds.x; - if (bx <= EPSILON_MOVE) - return false; // collision but no movement + if (bx <= 0) return true; // collision but no movement collided = true; } } } - bounds.x += bx; + bounds.x = next.x; return collided; } - + protected boolean moveByY(float by) { if (by == 0) return false; - + boolean collided = false; Rectangle next = new Rectangle(bounds); @@ -84,49 +82,51 @@ public abstract class MovingEntity extends CRGameEntity { for (CRGameEntity ent : world.entities) { if (ent == this) continue; - - if (overlaps(next, ent.bounds, EPSILON_MOVE) && ent.canCollide(true, this)) { - - if (overlaps(bounds, ent.bounds, EPSILON_COLLIDE)) { - Gdx.app.log("Collision", "Ignore in bounds collision"); + + if (overlaps(next, ent.bounds) && ent.canCollide(true, this)) { + + if (overlaps(bounds, ent.bounds)) { + Gdx.app.log("Collision", "Ignore in bounds collision [Y]"); continue; } - + if (by < 0) { // DOWN - float correction = (ent.bounds.y + ent.bounds.height) - next.y + EPSILON_MOVE; + float correction = (ent.bounds.y + ent.bounds.height) - next.y + EPSILON; next.y += correction; - by += correction; + by = next.y - bounds.y; + + if (by >= 0) return true; // collision but no movement - if (by >= -EPSILON_MOVE) - return true; // collision but no movement - collided = true; } else { // UP - float correction = ent.bounds.y - (next.y + next.height) - EPSILON_MOVE; + float correction = (next.y + next.height) - ent.bounds.y + EPSILON; - next.y += correction; - by += correction; + next.y -= correction; + by = next.y - bounds.y; + + if (by <= 0) return true; // collision but no movement - if (by <= EPSILON_MOVE) - return true; // collision but no movement - collided = true; } } } - bounds.y += by; + bounds.y = next.y; return collided; } - + protected boolean updateHitBox(float width, float height) { boolean succ_x = updateHitBoxWidth(width); + if (CRGame.DEBUG && getFirstCollision() != null) Gdx.app.error("Collision", "Collision after updateHitBox [[Width]] - " + succ_x); + boolean succ_y = updateHitBoxHeight(height); - + if (CRGame.DEBUG && getFirstCollision() != null) Gdx.app.error("Collision", "Collision after updateHitBox [[Height]] - " + succ_y); + + return succ_x && succ_y; } - + private boolean updateHitBoxWidth(float width) { Rectangle next = new Rectangle(bounds); @@ -142,39 +142,48 @@ public abstract class MovingEntity extends CRGameEntity { next.x -= add/2; } - if (add < 0) { bounds.set(next); + + for (CRGameEntity ent2 : world.entities) { //TODO rem me + if (ent2 == this) continue; + + if (overlaps(next, ent2.bounds) && ent2.canCollide(false, this)) { + Gdx.app.log("Entity Hitbox", "Expand failed X- || WTF"); + return false; + } + } + return true; } else { for (CRGameEntity ent : world.entities) { if (ent == this) continue; - if (overlaps(ent.bounds, next, EPSILON_MOVE) && ent.canCollide(false, this)) { + if (overlaps(ent.bounds, next) && ent.canCollide(false, this)) { - if (overlaps(ent.bounds, bounds, EPSILON_COLLIDE)) { + if (overlaps(ent.bounds, bounds)) { Gdx.app.log("Collision", "Ignore in bounds collision on HB Expand [X]"); continue; } if (ent.bounds.x > next.x) { - next.x -= (next.x + next.width) - ent.bounds.x - EPSILON_MOVE; + next.x -= (next.x + next.width) - ent.bounds.x + EPSILON; for (CRGameEntity ent2 : world.entities) { if (ent2 == this) continue; - if (overlaps(next, ent2.bounds, EPSILON_COLLIDE) && ent2.canCollide(false, this)) { + if (overlaps(next, ent2.bounds) && ent2.canCollide(false, this)) { Gdx.app.log("Entity Hitbox", "Expand failed X+"); return false; } } } else if (ent.bounds.x < next.x) { - next.x += (ent.bounds.x + ent.bounds.width) - next.x + EPSILON_MOVE; + next.x += (ent.bounds.x + ent.bounds.width) - next.x + EPSILON; for (CRGameEntity ent2 : world.entities) { if (ent2 == this) continue; - if (overlaps(next, ent2.bounds, EPSILON_COLLIDE) && ent2.canCollide(false, this)) { + if (overlaps(next, ent2.bounds) && ent2.canCollide(false, this)) { Gdx.app.log("Entity Hitbox", "Expand failed X-"); return false; } @@ -187,17 +196,17 @@ public abstract class MovingEntity extends CRGameEntity { return true; } } - + private boolean updateHitBoxHeight(float height) { Rectangle next = new Rectangle(bounds); - + float add = height - bounds.height; - if (isTouching_BOTTOM() && ! isTouching_TOP()) { + if (isTouching_BOTTOM() && !isTouching_TOP()) { next.height += add; } else if (! isTouching_BOTTOM() && isTouching_TOP()) { next.height += add; - next.y -= add; + next.y -= add - EPSILON; } else { next.height += add; next.y -= add/2; @@ -205,36 +214,46 @@ public abstract class MovingEntity extends CRGameEntity { if (add < 0) { bounds.set(next); + + for (CRGameEntity ent2 : world.entities) { //TODO rem me + if (ent2 == this) continue; + + if (overlaps(next, ent2.bounds) && ent2.canCollide(false, this)) { + Gdx.app.log("Entity Hitbox", "Expand failed Y- || WTF"); + return false; + } + } + return true; } else { for (CRGameEntity ent : world.entities) { if (ent == this) continue; - - if (overlaps(ent.bounds, next, EPSILON_MOVE) && ent.canCollide(false, this)) { - if (overlaps(ent.bounds, bounds, EPSILON_COLLIDE)) { + if (overlaps(ent.bounds, next) && ent.canCollide(false, this)) { + + if (overlaps(ent.bounds, bounds)) { Gdx.app.log("Collision", "Ignore in bounds collision on HB Expand [Y]"); continue; } if (ent.bounds.y > next.y) { - next.y -= (next.y + next.height) - ent.bounds.y - EPSILON_MOVE; - + next.y -= (next.y + next.height) - ent.bounds.y + EPSILON; + for (CRGameEntity ent2 : world.entities) { if (ent2 == this) continue; - - if (overlaps(next, ent2.bounds, EPSILON_COLLIDE) && ent2.canCollide(false, this)) { + + if (overlaps(next, ent2.bounds) && ent2.canCollide(false, this)) { Gdx.app.log("Entity Hitbox", "Expand failed Y+"); return false; } } } else if (ent.bounds.y < next.y) { - next.y += (ent.bounds.y + ent.bounds.height) - next.y + EPSILON_MOVE; - + next.y += (ent.bounds.y + ent.bounds.height) - next.y + EPSILON; + for (CRGameEntity ent2 : world.entities) { if (ent2 == this) continue; - - if (overlaps(next, ent2.bounds, EPSILON_COLLIDE) && ent2.canCollide(false, this)) { + + if (overlaps(next, ent2.bounds) && ent2.canCollide(false, this)) { Gdx.app.log("Entity Hitbox", "Expand failed Y-"); return false; } @@ -243,27 +262,28 @@ public abstract class MovingEntity extends CRGameEntity { } } + bounds.set(next); return true; } } - + private void updateTouchCollisions() { face_TOP_isTouching = false; face_LEFT_isTouching = false; face_BOTTOM_isTouching = false; face_RIGHT_isTouching = false; - + for (CRGameEntity ent : world.entities) { if (ent == this) continue; - + if (Math.abs((ent.bounds.y + ent.bounds.height) - bounds.y) < EPSILON_TOUCH && ent.bounds.x < (bounds.x + bounds.width) && (ent.bounds.x + ent.bounds.width) > bounds.x && ent.canCollide(false, this)) { face_BOTTOM_isTouching = true; } - + if (Math.abs((bounds.y + bounds.height) - ent.bounds.y) < EPSILON_TOUCH && ent.bounds.x < (bounds.x + bounds.width) && (ent.bounds.x + ent.bounds.width) > bounds.x && ent.canCollide(false, this)) { face_TOP_isTouching = true; } - + if (Math.abs((bounds.x + bounds.width) - ent.bounds.x) < EPSILON_TOUCH && ent.bounds.y < (bounds.y + bounds.height) && (ent.bounds.y + ent.bounds.height) > bounds.y && ent.canCollide(false, this)) { face_RIGHT_isTouching = true; } @@ -272,49 +292,43 @@ public abstract class MovingEntity extends CRGameEntity { face_LEFT_isTouching = true; } } - + } - + public Vector2 getVelocity() { return velocity; } - + @Override public void update(float delta) { if (velocity.x != 0) { if (moveByX(velocity.x * delta)) { velocity.x = 0; } - for (CRGameEntity ent : world.entities) { - if (ent == this) continue; - if (overlaps(ent.bounds, bounds, EPSILON_COLLIDE) && ent.canCollide(true, this)) - Gdx.app.error("Collision", "Collision after move X"); - } + if (CRGame.DEBUG && getFirstCollision() != null) Gdx.app.error("Collision", "Collision after move [[X]]"); } - + if (velocity.y != 0) { if (moveByY(velocity.y * delta)) { velocity.y = 0; } - for (CRGameEntity ent : world.entities) { - if (ent == this) continue; - if (overlaps(ent.bounds, bounds, EPSILON_COLLIDE) && ent.canCollide(true, this)) - Gdx.app.error("Collision", "Collision after Y"); - } + if (CRGame.DEBUG && getFirstCollision() != null) Gdx.app.error("Collision", "Collision after move [[Y]]"); } - - updateTouchCollisions(); } + private CRGameEntity getFirstCollision() + { + for (CRGameEntity ent : world.entities) { + if (ent == this) continue; + if (overlaps(ent.bounds, bounds) && ent.canCollide(false, this)) return ent; + } + return null; + } - private boolean overlaps (Rectangle r1, Rectangle r2, float delta) { - return - r1.x - 1*delta < r2.x + r2.width && - r1.x + r1.width + 2*delta > r2.x && - r1.y - 1*delta < r2.y + r2.height && - r1.y + r1.height + 2*delta > r2.y; + private boolean overlaps (Rectangle r1, Rectangle r2) { + return r1.overlaps(r2) && r2.overlaps(r1); // make overlaps commutative (?) } public boolean isTouching_ANY() { diff --git a/core/src/de/samdev/colorrunner/game/world/entities/gameentities/PlayerEntity.java b/core/src/de/samdev/colorrunner/game/world/entities/gameentities/PlayerEntity.java index 3bb2ea2..73b7804 100644 --- a/core/src/de/samdev/colorrunner/game/world/entities/gameentities/PlayerEntity.java +++ b/core/src/de/samdev/colorrunner/game/world/entities/gameentities/PlayerEntity.java @@ -73,7 +73,7 @@ public class PlayerEntity extends GravityEntity { } private void updateRotation(float delta) { - boolean touch = isTouching_ANY(); + boolean touch = false; //isTouching_ANY(); //TODO comment me to force bug boolean aligned = (visualRotation % 90 == 0); if (!touch)