package de.samdev.colorrunner.game.world.entities; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.math.Vector2; import de.samdev.colorrunner.game.world.CRGameWorld; public abstract class MovingEntity extends CRGameEntity { protected Vector2 velocity = new Vector2(); private boolean face_TOP_isTouching = false; private boolean face_LEFT_isTouching = false; private boolean face_BOTTOM_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); } protected boolean moveByX(float bx) { if (bx == 0) return false; boolean collided = false; bounds.x += bx; for (CRGameEntity ent : world.entities) { if (ent == this) continue; if (ent.bounds.overlaps(bounds)) { if (bx < 0) { // LEFT float correction = (ent.bounds.x + ent.bounds.width) - bounds.x; bounds.x += correction; bx += correction; collided = true; } else { // RIGHT float correction = ent.bounds.x - (bounds.x + bounds.width); bounds.x += correction; bx += correction; collided = true; } } } return collided; } protected boolean moveByY(float by) { if (by == 0) return false; boolean collided = false; bounds.y += by; for (CRGameEntity ent : world.entities) { if (ent == this) continue; if (ent.bounds.overlaps(bounds)) { if (by < 0) { // DOWN float correction = (ent.bounds.y + ent.bounds.height) - bounds.y; bounds.y += correction; by += correction; collided = true; } else { // UP float correction = ent.bounds.y - (bounds.y + bounds.height); bounds.y += correction; by += correction; collided = true; } } } return collided; } 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) < F_EPSILON && ent.bounds.x < (bounds.x + bounds.width) && (ent.bounds.x + ent.bounds.width) > bounds.x) { face_BOTTOM_isTouching = true; } if (Math.abs((bounds.y + bounds.height) - ent.bounds.y) < F_EPSILON && ent.bounds.x < (bounds.x + bounds.width) && (ent.bounds.x + ent.bounds.width) > bounds.x) { face_TOP_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; } } if (velocity.y != 0) { if (moveByY(velocity.y * delta)) { velocity.y = 0; } } updateTouchCollisions(); } public boolean isTouching_TOP() { return face_TOP_isTouching; } public boolean isTouching_LEFT() { return face_LEFT_isTouching; } public boolean isTouching_BOTTOM() { return face_BOTTOM_isTouching; } public boolean isTouching_RIGHT() { return face_RIGHT_isTouching; } }