|
@@ -1,89 +1,79 @@
|
|
|
package me.hammerle.supersnuvi.entity;
|
|
|
|
|
|
-import me.hammerle.supersnuvi.entity.components.animator.EntityAnimator;
|
|
|
-import me.hammerle.supersnuvi.entity.components.ai.EntityController;
|
|
|
-import java.util.LinkedList;
|
|
|
+import java.util.List;
|
|
|
+import me.hammerle.supersnuvi.entity.components.animator.Renderer;
|
|
|
+import me.hammerle.supersnuvi.entity.components.ai.Controller;
|
|
|
import me.hammerle.supersnuvi.entity.components.Energy;
|
|
|
import me.hammerle.supersnuvi.entity.components.Health;
|
|
|
import me.hammerle.supersnuvi.entity.components.ItemCollector;
|
|
|
import me.hammerle.supersnuvi.entity.components.Movement;
|
|
|
-import me.hammerle.supersnuvi.entity.components.MovementPenalty;
|
|
|
import me.hammerle.supersnuvi.gamelogic.Level;
|
|
|
-import me.hammerle.supersnuvi.rendering.OldGame;
|
|
|
-import me.hammerle.supersnuvi.tiles.Location;
|
|
|
import me.hammerle.supersnuvi.util.CollisionBox;
|
|
|
import me.hammerle.supersnuvi.util.Face;
|
|
|
import me.hammerle.supersnuvi.util.Utils;
|
|
|
|
|
|
public final class Entity
|
|
|
{
|
|
|
- // 1 Tile = 1 m
|
|
|
- // Pixel m s Pixel
|
|
|
- // ----- * --- * ------ = -------
|
|
|
- // m s Tick Tick
|
|
|
- // added correction factor, real life gravity seems to strong
|
|
|
- public static double GRAVITY = OldGame.TILE_SIZE * 9.81 / 60 * 0.1;
|
|
|
-
|
|
|
- private double posX;
|
|
|
- private double posY;
|
|
|
- private final double width;
|
|
|
- private final double height;
|
|
|
- private final double cWidth;
|
|
|
- private final double cHeight;
|
|
|
-
|
|
|
- private double prevPosX;
|
|
|
- private double prevPrevY;
|
|
|
-
|
|
|
- private double prevMotionX;
|
|
|
- private double prevMotionY;
|
|
|
- private double motionX;
|
|
|
- private double motionY;
|
|
|
- private boolean onGround;
|
|
|
-
|
|
|
- private final CollisionBox collisionBox;
|
|
|
-
|
|
|
+ public static float GRAVITY = 8.0f;
|
|
|
+ public static float STEP = 0.0625f;
|
|
|
+
|
|
|
+ // the last position is used for interpolation during rendering
|
|
|
+ private float lastPosX;
|
|
|
+ private float lastPosY;
|
|
|
+ // the current position of the entity
|
|
|
+ private float posX;
|
|
|
+ private float posY;
|
|
|
+
|
|
|
+ // the collision box of the entity
|
|
|
+ private final CollisionBox box;
|
|
|
+
|
|
|
+ // the motion before the movement collision check
|
|
|
+ private float preMotionX;
|
|
|
+ private float preMotionY;
|
|
|
+ // the motion after the movement collision check
|
|
|
+ private float motionX;
|
|
|
+ private float motionY;
|
|
|
+
|
|
|
+ // a flag indicating that the entity is on the ground
|
|
|
+ private boolean onGround = false;
|
|
|
+
|
|
|
+ // the level of the entity
|
|
|
private final Level level;
|
|
|
|
|
|
- // components
|
|
|
- protected EntityAnimator animator;
|
|
|
- protected EntityController controller;
|
|
|
+ // entity components
|
|
|
+ protected Renderer renderer;
|
|
|
+ protected Controller controller;
|
|
|
protected Health health;
|
|
|
protected Energy energy;
|
|
|
protected Movement move;
|
|
|
protected ItemCollector itemCollector;
|
|
|
- protected MovementPenalty movePenalty;
|
|
|
|
|
|
- protected Entity(Level level, double x, double y, double width, double height, double cWidth, double cHeight)
|
|
|
+ protected Entity(Level level, float x, float y, CollisionBox box)
|
|
|
{
|
|
|
+ lastPosX = x;
|
|
|
+ lastPosY = y;
|
|
|
+ posX = x;
|
|
|
+ posY = y;
|
|
|
+
|
|
|
+ // ensure the box cannot be modified from the outside
|
|
|
+ this.box = box.copy().offset(x, y);
|
|
|
+
|
|
|
+ preMotionX = 0.0f;
|
|
|
+ preMotionY = 0.0f;
|
|
|
+ motionX = 0.0f;
|
|
|
+ motionY = 0.0f;
|
|
|
+
|
|
|
this.level = level;
|
|
|
- this.posX = x;
|
|
|
- this.posY = y;
|
|
|
- this.prevPosX = x;
|
|
|
- this.prevPrevY = y;
|
|
|
- this.motionX = 0;
|
|
|
- this.motionY = 0;
|
|
|
- this.onGround = false;
|
|
|
- this.collisionBox = new CollisionBox(0, 0, cWidth, cHeight);
|
|
|
- this.width = width;
|
|
|
- this.height = height;
|
|
|
- this.cWidth = cWidth;
|
|
|
- this.cHeight = cHeight;
|
|
|
|
|
|
// components
|
|
|
- this.animator = EntityAnimator.NULL;
|
|
|
- this.controller = EntityController.NULL;
|
|
|
+ this.renderer = Renderer.NULL;
|
|
|
+ this.controller = Controller.NULL;
|
|
|
this.health = Health.NULL;
|
|
|
this.energy = Energy.NULL;
|
|
|
this.move = Movement.NULL;
|
|
|
this.itemCollector = ItemCollector.NULL;
|
|
|
- this.movePenalty = MovementPenalty.NULL;
|
|
|
}
|
|
|
|
|
|
- protected Entity(Level level, double x, double y, double width, double height)
|
|
|
- {
|
|
|
- this(level, x, y, width, height, width, height);
|
|
|
- }
|
|
|
-
|
|
|
public Level getLevel()
|
|
|
{
|
|
|
return level;
|
|
@@ -93,14 +83,9 @@ public final class Entity
|
|
|
// components
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
- public EntityController getController()
|
|
|
- {
|
|
|
- return controller;
|
|
|
- }
|
|
|
-
|
|
|
- public EntityAnimator getAnimator()
|
|
|
+ public boolean isAnimated()
|
|
|
{
|
|
|
- return animator;
|
|
|
+ return renderer.isAnimated();
|
|
|
}
|
|
|
|
|
|
public Health getHealth()
|
|
@@ -123,522 +108,247 @@ public final class Entity
|
|
|
return itemCollector;
|
|
|
}
|
|
|
|
|
|
- public MovementPenalty getMovementPenalty()
|
|
|
- {
|
|
|
- return movePenalty;
|
|
|
- }
|
|
|
-
|
|
|
//--------------------------------------------------------------------------
|
|
|
// basic stuff
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
- public double squaredDistance(Entity other)
|
|
|
+ public float getSquaredDistance(Entity e)
|
|
|
{
|
|
|
- return (posX - other.posX) * (posX - other.posX) + (posY - other.posY) * (posY - other.posY);
|
|
|
+ return Utils.getSquaredDistance(
|
|
|
+ posX + box.getWidth() * 0.5f, posY + box.getHeight() * 0.5f,
|
|
|
+ e.posX + e.box.getWidth() * 0.5f, e.posY + e.box.getHeight() * 0.5f);
|
|
|
}
|
|
|
|
|
|
- public double signedDistanceX(Entity other)
|
|
|
+ public float getX()
|
|
|
{
|
|
|
- if(posX < other.posX)
|
|
|
- {
|
|
|
- return Math.min(0.0, posX + cWidth - other.posX);
|
|
|
- }
|
|
|
- return Math.max(0.0, posX - (other.posX + other.cWidth));
|
|
|
+ return posX;
|
|
|
}
|
|
|
|
|
|
- public double getWidth()
|
|
|
+ public float getY()
|
|
|
{
|
|
|
- return width;
|
|
|
+ return posY;
|
|
|
}
|
|
|
|
|
|
- public double getHeight()
|
|
|
+ public float getLastX()
|
|
|
{
|
|
|
- return height;
|
|
|
+ return lastPosX;
|
|
|
}
|
|
|
|
|
|
- public double getCollisionWidth()
|
|
|
+ public float getLastY()
|
|
|
{
|
|
|
- return cWidth;
|
|
|
+ return lastPosY;
|
|
|
}
|
|
|
|
|
|
- public double getCollisionHeight()
|
|
|
+ public float getCenterX()
|
|
|
{
|
|
|
- return cHeight;
|
|
|
+ return posX + box.getWidth() * 0.5f;
|
|
|
}
|
|
|
|
|
|
- public double getX()
|
|
|
+ public float getCenterY()
|
|
|
{
|
|
|
- return posX;
|
|
|
+ return posY + box.getHeight() * 0.5f;
|
|
|
}
|
|
|
|
|
|
- public double getY()
|
|
|
+ public Face getFace()
|
|
|
{
|
|
|
- return posY;
|
|
|
+ return preMotionX > 0.0f ? Face.RIGHT : Face.LEFT;
|
|
|
}
|
|
|
|
|
|
- public boolean isOutOfMap()
|
|
|
+ public float getMotionX()
|
|
|
{
|
|
|
- return posY < -height;
|
|
|
+ return motionX;
|
|
|
}
|
|
|
|
|
|
- //--------------------------------------------------------------------------
|
|
|
- // ticking
|
|
|
- //--------------------------------------------------------------------------
|
|
|
+ public void setMotionX(float motionX)
|
|
|
+ {
|
|
|
+ this.motionX = motionX;
|
|
|
+ }
|
|
|
|
|
|
- public void tick()
|
|
|
+ public float getMotionY()
|
|
|
{
|
|
|
- controller.tick();
|
|
|
- health.tick();
|
|
|
- movePenalty.reset();
|
|
|
-
|
|
|
- if(move.isAffectedByGravity())
|
|
|
- {
|
|
|
- motionY -= GRAVITY * move.getGravityFactor();
|
|
|
- }
|
|
|
-
|
|
|
- prevMotionX = motionX;
|
|
|
- prevMotionY = motionY;
|
|
|
-
|
|
|
- prevPosX = posX;
|
|
|
- prevPrevY = posY;
|
|
|
-
|
|
|
- boolean check = !move.canMoveEverywhere();
|
|
|
- if(check)
|
|
|
- {
|
|
|
- setAllowedMotion();
|
|
|
- }
|
|
|
-
|
|
|
- if(!move.blockHorizontal())
|
|
|
- {
|
|
|
- posX += motionX;
|
|
|
- }
|
|
|
- posY += motionY;
|
|
|
-
|
|
|
- motionX = Utils.round(motionX);
|
|
|
- motionY = Utils.round(motionY);
|
|
|
-
|
|
|
- if(motionY != 0)
|
|
|
- {
|
|
|
- onGround = false;
|
|
|
- }
|
|
|
-
|
|
|
- posX = Utils.round(posX);
|
|
|
- posY = Utils.round(posY);
|
|
|
-
|
|
|
- if(check)
|
|
|
- {
|
|
|
- LinkedList<CollisionBox> list = level.getMovementBoxesAt(this, getBox());
|
|
|
- if(!list.isEmpty())
|
|
|
- {
|
|
|
- //System.out.println(getBox());
|
|
|
- //list.forEach(s -> System.out.println(s));
|
|
|
- //System.out.println("WELL");
|
|
|
- posX = prevPosX;
|
|
|
- posY = prevPrevY;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- movePenalty.setFriction(0.7);
|
|
|
- doCollision();
|
|
|
- movePenalty.applyFriction();
|
|
|
- energy.tick();
|
|
|
- animator.tick();
|
|
|
+ return motionY;
|
|
|
}
|
|
|
|
|
|
- //--------------------------------------------------------------------------
|
|
|
- // gravity, friction
|
|
|
- //--------------------------------------------------------------------------
|
|
|
+ public void setMotionY(float motionY)
|
|
|
+ {
|
|
|
+ this.motionY = motionY;
|
|
|
+ }
|
|
|
|
|
|
- public boolean isOnGround()
|
|
|
+ public float getPreMotionX()
|
|
|
{
|
|
|
- return onGround;
|
|
|
- }
|
|
|
+ return preMotionX;
|
|
|
+ }
|
|
|
|
|
|
- public void setNoGround()
|
|
|
+ public float getPreMotionY()
|
|
|
{
|
|
|
- onGround = false;
|
|
|
- }
|
|
|
+ return preMotionY;
|
|
|
+ }
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
- // collision stuff
|
|
|
+ // ticking
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
- public CollisionBox getBox()
|
|
|
- {
|
|
|
- return collisionBox.reset().offset(posX, posY);
|
|
|
- }
|
|
|
-
|
|
|
- private void setAllowedMotion()
|
|
|
+ public void tick()
|
|
|
{
|
|
|
- if(motionX == 0 && motionY == 0)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- double dirX = motionX;
|
|
|
- double dirY = motionY;
|
|
|
- double startX = posX;
|
|
|
- double startY = posY;
|
|
|
- double endX = startX + dirX;
|
|
|
- double endY = startY + dirY;
|
|
|
+ lastPosX = posX;
|
|
|
+ lastPosY = posY;
|
|
|
|
|
|
- CollisionBox eBox = getBox();
|
|
|
- double halfWidth = eBox.getWidth() / 2;
|
|
|
- double halfHeight = eBox.getHeight() / 2;
|
|
|
- eBox = eBox.copy();
|
|
|
-
|
|
|
- startX += halfWidth;
|
|
|
- startY += halfHeight;
|
|
|
- endX += halfWidth;
|
|
|
- endY += halfHeight;
|
|
|
+ controller.tick();
|
|
|
+ health.tick();
|
|
|
+ energy.tick();
|
|
|
|
|
|
- // expanding area by the size of the entity
|
|
|
- CollisionBox expandedBox = eBox.copy().expand(motionX, motionY);
|
|
|
+ preMotionX = motionX;
|
|
|
+ preMotionY = motionY;
|
|
|
|
|
|
- LinkedList<CollisionBox> allBoxes = level.getMovementBoxesAt(this, expandedBox);
|
|
|
- if(allBoxes.isEmpty())
|
|
|
+ if(move.hasGravity())
|
|
|
{
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- double x;
|
|
|
- double y;
|
|
|
- char lastWall = 0;
|
|
|
-
|
|
|
- if(dirX >= 0)
|
|
|
+ preMotionY += GRAVITY * move.getGravityFactor();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(move.canMoveEverywhere())
|
|
|
{
|
|
|
- if(dirY <= 0) // Right - Down
|
|
|
+ motionX = preMotionX;
|
|
|
+ motionY = preMotionY;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ CollisionBox testBox = box.copy().expand(preMotionX, preMotionY);
|
|
|
+ List<CollisionBox> boxes = level.getMovementBoxesAt(testBox);
|
|
|
+ if(!boxes.isEmpty())
|
|
|
{
|
|
|
- for(CollisionBox box : allBoxes)
|
|
|
- {
|
|
|
- box.grow(halfWidth, halfHeight);
|
|
|
- if(endX <= box.getMinX() || endY >= box.getMaxY() ||
|
|
|
- startX >= box.getMaxX() || startY <= box.getMinY())
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- x = Utils.interpolateX(startX, startY, endX, endY, box.getMaxY());
|
|
|
- y = Utils.interpolateY(startX, startY, endX, endY, box.getMinX());
|
|
|
- if(y > box.getMinY() && y < box.getMaxY())
|
|
|
- {
|
|
|
- endX = box.getMinX();
|
|
|
- endY = y;
|
|
|
- lastWall = 'x';
|
|
|
- }
|
|
|
- else if(x > box.getMinX() && x < box.getMaxX())
|
|
|
- {
|
|
|
- endY = box.getMaxY();
|
|
|
- endX = x;
|
|
|
- lastWall = 'y';
|
|
|
- }
|
|
|
- else if(x >= box.getMinX() && x <= box.getMaxX())
|
|
|
- {
|
|
|
- lastWall = 'y';
|
|
|
- }
|
|
|
- }
|
|
|
- if(lastWall == 'x')
|
|
|
+ float mx = preMotionX;
|
|
|
+ float my = preMotionY;
|
|
|
+
|
|
|
+ testBox.reset();
|
|
|
+
|
|
|
+ float oldX = testBox.getMinX();
|
|
|
+ float oldY = testBox.getMinY();
|
|
|
+
|
|
|
+ while(mx != 0.0 || my != 0.0)
|
|
|
{
|
|
|
- double lineEndY = startY + dirY;
|
|
|
- for(CollisionBox box : allBoxes)
|
|
|
+ testBox.save();
|
|
|
+
|
|
|
+ if(mx < 0.0)
|
|
|
{
|
|
|
- if(endX <= box.getMinX() || lineEndY >= box.getMaxY() ||
|
|
|
- endX >= box.getMaxX() || endY <= box.getMinY())
|
|
|
+ if(mx > -STEP)
|
|
|
{
|
|
|
- continue;
|
|
|
+ testBox.offsetX(mx);
|
|
|
+ mx = 0.0f;
|
|
|
}
|
|
|
- lineEndY = box.getMaxY();
|
|
|
- }
|
|
|
- endY = lineEndY;
|
|
|
- }
|
|
|
- else if(lastWall == 'y')
|
|
|
- {
|
|
|
- double lineEndX = startX + dirX;
|
|
|
- for(CollisionBox box : allBoxes)
|
|
|
- {
|
|
|
- if(lineEndX <= box.getMinX() || endY >= box.getMaxY() ||
|
|
|
- endX >= box.getMaxX() || endY <= box.getMinY())
|
|
|
+ else
|
|
|
{
|
|
|
- continue;
|
|
|
+ testBox.offsetX(-STEP);
|
|
|
+ mx += STEP;
|
|
|
}
|
|
|
- lineEndX = box.getMinX();
|
|
|
- }
|
|
|
- endX = lineEndX;
|
|
|
- }
|
|
|
- }
|
|
|
- else // Right - Up
|
|
|
- {
|
|
|
- for(CollisionBox box : allBoxes)
|
|
|
- {
|
|
|
- box.grow(halfWidth, halfHeight);
|
|
|
- if(endX <= box.getMinX() || endY <= box.getMinY() ||
|
|
|
- startX >= box.getMaxX() || startY >= box.getMaxY())
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- x = Utils.interpolateX(startX, startY, endX, endY, box.getMinY());
|
|
|
- y = Utils.interpolateY(startX, startY, endX, endY, box.getMinX());
|
|
|
- if(y > box.getMinY() && y < box.getMaxY())
|
|
|
- {
|
|
|
- endX = box.getMinX();
|
|
|
- endY = y;
|
|
|
- lastWall = 'x';
|
|
|
- }
|
|
|
- else if(x > box.getMinX() && x < box.getMaxX())
|
|
|
- {
|
|
|
- endY = box.getMinY();
|
|
|
- endX = x;
|
|
|
- lastWall = 'y';
|
|
|
}
|
|
|
- else if(x >= box.getMinX() && x <= box.getMaxX())
|
|
|
+ else if(mx > 0.0)
|
|
|
{
|
|
|
- lastWall = 'y';
|
|
|
- }
|
|
|
- }
|
|
|
- if(lastWall == 'x')
|
|
|
- {
|
|
|
- double lineEndY = startY + dirY;
|
|
|
- for(CollisionBox box : allBoxes)
|
|
|
- {
|
|
|
- if(endX <= box.getMinX() || lineEndY <= box.getMinY() ||
|
|
|
- endX >= box.getMaxX() || endY >= box.getMaxY())
|
|
|
+ if(mx < STEP)
|
|
|
{
|
|
|
- continue;
|
|
|
+ testBox.offsetX(mx);
|
|
|
+ mx = 0.0f;
|
|
|
}
|
|
|
- lineEndY = box.getMinY();
|
|
|
- }
|
|
|
- endY = lineEndY;
|
|
|
- }
|
|
|
- else if(lastWall == 'y')
|
|
|
- {
|
|
|
- double lineEndX = startX + dirX;
|
|
|
- for(CollisionBox box : allBoxes)
|
|
|
- {
|
|
|
- if(lineEndX <= box.getMinX() || endY >= box.getMaxY() ||
|
|
|
- endX >= box.getMaxX() || endY <= box.getMinY())
|
|
|
+ else
|
|
|
{
|
|
|
- continue;
|
|
|
+ testBox.offsetX(STEP);
|
|
|
+ mx -= STEP;
|
|
|
}
|
|
|
- lineEndX = box.getMinX();
|
|
|
}
|
|
|
- endX = lineEndX;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if(dirY <= 0) // Left - Down
|
|
|
- {
|
|
|
- for(CollisionBox box : allBoxes)
|
|
|
- {
|
|
|
- box.grow(halfWidth, halfHeight);
|
|
|
- if(endX >= box.getMaxX() || endY >= box.getMaxY() ||
|
|
|
- startX <= box.getMinX() || startY <= box.getMinY())
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- x = Utils.interpolateX(startX, startY, endX, endY, box.getMaxY());
|
|
|
- y = Utils.interpolateY(startX, startY, endX, endY, box.getMaxX());
|
|
|
- if(y > box.getMinY() && y < box.getMaxY())
|
|
|
- {
|
|
|
- endX = box.getMaxX();
|
|
|
- endY = y;
|
|
|
- lastWall = 'x';
|
|
|
- }
|
|
|
- else if(x > box.getMinX() && x < box.getMaxX())
|
|
|
- {
|
|
|
- endY = box.getMaxY();
|
|
|
- endX = x;
|
|
|
- lastWall = 'y';
|
|
|
- }
|
|
|
- else if(x >= box.getMinX() && x <= box.getMaxX())
|
|
|
- {
|
|
|
- lastWall = 'y';
|
|
|
- }
|
|
|
- }
|
|
|
- if(lastWall == 'x')
|
|
|
- {
|
|
|
- double lineEndY = startY + dirY;
|
|
|
- for(CollisionBox box : allBoxes)
|
|
|
+
|
|
|
+ for(CollisionBox cb : boxes)
|
|
|
{
|
|
|
- if(endX <= box.getMinX() || lineEndY >= box.getMaxY() ||
|
|
|
- endX >= box.getMaxX() || endY <= box.getMinY())
|
|
|
+ if(cb.isColliding(testBox))
|
|
|
{
|
|
|
- continue;
|
|
|
+ mx = 0.0f;
|
|
|
+ testBox.reset();
|
|
|
+ break;
|
|
|
}
|
|
|
- lineEndY = box.getMaxY();
|
|
|
}
|
|
|
- endY = lineEndY;
|
|
|
- }
|
|
|
- else if(lastWall == 'y')
|
|
|
- {
|
|
|
- double lineEndX = startX + dirX;
|
|
|
- for(CollisionBox box : allBoxes)
|
|
|
+
|
|
|
+ testBox.save();
|
|
|
+
|
|
|
+ if(my < 0.0)
|
|
|
{
|
|
|
- if(lineEndX >= box.getMaxX() || endY >= box.getMaxY() ||
|
|
|
- endX <= box.getMinX() || endY <= box.getMinY())
|
|
|
+ if(my > -STEP)
|
|
|
{
|
|
|
- continue;
|
|
|
+ testBox.offsetY(my);
|
|
|
+ my = 0.0f;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ testBox.offsetY(-STEP);
|
|
|
+ my += STEP;
|
|
|
}
|
|
|
- lineEndX = box.getMaxX();
|
|
|
- }
|
|
|
- endX = lineEndX;
|
|
|
- }
|
|
|
- }
|
|
|
- else // Left - Up
|
|
|
- {
|
|
|
- for(CollisionBox box : allBoxes)
|
|
|
- {
|
|
|
- box.grow(halfWidth, halfHeight);
|
|
|
- if(endX >= box.getMaxX() || endY <= box.getMinY() ||
|
|
|
- startX <= box.getMinX() || startY >= box.getMaxY())
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- x = Utils.interpolateX(startX, startY, endX, endY, box.getMinY());
|
|
|
- y = Utils.interpolateY(startX, startY, endX, endY, box.getMaxX());
|
|
|
- if(y > box.getMinY() && y < box.getMaxY())
|
|
|
- {
|
|
|
- endX = box.getMaxX();
|
|
|
- endY = y;
|
|
|
- lastWall = 'x';
|
|
|
- }
|
|
|
- else if(x > box.getMinX() && x < box.getMaxX())
|
|
|
- {
|
|
|
- endY = box.getMinY();
|
|
|
- endX = x;
|
|
|
- lastWall = 'y';
|
|
|
- }
|
|
|
- else if(x >= box.getMinX() && x <= box.getMaxX())
|
|
|
- {
|
|
|
- lastWall = 'y';
|
|
|
}
|
|
|
- }
|
|
|
- if(lastWall == 'x')
|
|
|
- {
|
|
|
- double lineEndY = startY + dirY;
|
|
|
- for(CollisionBox box : allBoxes)
|
|
|
+ else if(my > 0.0)
|
|
|
{
|
|
|
- if(endX <= box.getMinX() || lineEndY <= box.getMinY() ||
|
|
|
- endX >= box.getMaxX() || endY >= box.getMaxY())
|
|
|
+ if(my < STEP)
|
|
|
{
|
|
|
- continue;
|
|
|
+ testBox.offsetY(my);
|
|
|
+ my = 0.0f;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ testBox.offsetY(STEP);
|
|
|
+ my -= STEP;
|
|
|
}
|
|
|
- lineEndY = box.getMinY();
|
|
|
}
|
|
|
- endY = lineEndY;
|
|
|
- }
|
|
|
- else if(lastWall == 'y')
|
|
|
- {
|
|
|
- double lineEndX = startX + dirX;
|
|
|
- for(CollisionBox box : allBoxes)
|
|
|
+
|
|
|
+ for(CollisionBox cb : boxes)
|
|
|
{
|
|
|
- if(lineEndX >= box.getMaxX() || endY >= box.getMaxY() ||
|
|
|
- endX <= box.getMinX() || endY <= box.getMinY())
|
|
|
+ if(cb.isColliding(testBox))
|
|
|
{
|
|
|
- continue;
|
|
|
+ my = 0.0f;
|
|
|
+ testBox.reset();
|
|
|
+ break;
|
|
|
}
|
|
|
- lineEndX = box.getMaxX();
|
|
|
}
|
|
|
- endX = lineEndX;
|
|
|
}
|
|
|
+
|
|
|
+ motionX = testBox.getMinX() - oldX;
|
|
|
+ motionY = testBox.getMinY() - oldY;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ motionX = preMotionX;
|
|
|
+ motionY = preMotionY;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- motionX = endX - startX;
|
|
|
- motionY = endY - startY;
|
|
|
+ posX += motionX;
|
|
|
+ posY += motionY;
|
|
|
+ box.reset().offset(posX, posY);
|
|
|
|
|
|
- if(dirY < 0 && motionY == 0)
|
|
|
- {
|
|
|
- onGround = true;
|
|
|
- }
|
|
|
-
|
|
|
- if(Math.abs(motionY) >= 1000 || Math.abs(motionX) >= 1000)
|
|
|
- {
|
|
|
- System.err.println("illegal movement " + motionX + " " + motionY);
|
|
|
- System.exit(0);
|
|
|
- }
|
|
|
+ onGround = preMotionY > 0.0f && motionY == 0;
|
|
|
|
|
|
- /*if(!onGround && Math.abs(dirY) - Math.abs(motionY) > 1)
|
|
|
- {
|
|
|
- System.out.println("\nVORHER " + dirX + " " + dirY);
|
|
|
- System.out.println("NACHHER " + motionX + " " + motionY);
|
|
|
- System.out.println("\nPOS " + posX + " " + posY);
|
|
|
- System.exit(0);
|
|
|
- }*/
|
|
|
- //System.exit(0);
|
|
|
- }
|
|
|
-
|
|
|
- private void doCollision()
|
|
|
- {
|
|
|
- CollisionBox box = getBox().copy();
|
|
|
+ move.setInWater(false);
|
|
|
+ move.setFrictionFactor(0.7f);
|
|
|
+ // apply collision
|
|
|
+ CollisionBox cb = box.copy();
|
|
|
for(Face f : Face.values())
|
|
|
{
|
|
|
- box.reset();
|
|
|
- box.expand(f.getCollisionOffsetX(), f.getCollisionOffsetY());
|
|
|
- level.getEntitiesCollidingWith(this, box).forEach(ent -> this.onCollideWithEntity(ent, f));
|
|
|
- level.getTilesCollidingWith(box).forEach(loc ->
|
|
|
+ cb.reset();
|
|
|
+ cb.expand(f.getCollisionOffsetX(), f.getCollisionOffsetY());
|
|
|
+ level.getEntitiesCollidingWith(this, box).forEach(ent -> ent.controller.onCollideWithEntity(ent, f));
|
|
|
+ level.getCollisionBoxesAt(cb).forEach(loc ->
|
|
|
{
|
|
|
- this.onCollideWithTile(loc, f);
|
|
|
- loc.getTile().onEntityCollide(this, loc.getX(), loc.getY(), f);
|
|
|
+ controller.onCollideWithTile(loc, f);
|
|
|
+ loc.getTile().onEntityCollide(this, loc.getX(), loc.getY(), f.getOpposite());
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public void onCollideWithTile(Location loc, Face face)
|
|
|
+ public void renderTick(float lag)
|
|
|
{
|
|
|
- controller.onCollideWithTile(loc, face);
|
|
|
- }
|
|
|
-
|
|
|
- public void onCollideWithEntity(Entity ent, Face face)
|
|
|
- {
|
|
|
- controller.onCollideWithEntity(ent, face);
|
|
|
+ renderer.renderTick(lag);
|
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
- // basic coord and motion stuff
|
|
|
+ // gravity, friction
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
- public double getPreviousX()
|
|
|
- {
|
|
|
- return prevPosX;
|
|
|
- }
|
|
|
-
|
|
|
- public double getPreviousY()
|
|
|
- {
|
|
|
- return prevPrevY;
|
|
|
- }
|
|
|
-
|
|
|
- public boolean isMoving()
|
|
|
- {
|
|
|
- return motionX != 0.0 || motionY != 0.0;
|
|
|
- }
|
|
|
-
|
|
|
- public final double getMotionX()
|
|
|
- {
|
|
|
- return motionX;
|
|
|
- }
|
|
|
-
|
|
|
- public final void setMotionX(double motionX)
|
|
|
- {
|
|
|
- this.motionX = motionX;
|
|
|
- }
|
|
|
-
|
|
|
- public final double getMotionY()
|
|
|
- {
|
|
|
- return motionY;
|
|
|
- }
|
|
|
-
|
|
|
- public final void setMotionY(double motionY)
|
|
|
- {
|
|
|
- this.motionY = motionY;
|
|
|
- }
|
|
|
-
|
|
|
- public final double getPreviousMotionX()
|
|
|
- {
|
|
|
- return prevMotionX;
|
|
|
- }
|
|
|
-
|
|
|
- public final double getPreviousMotionY()
|
|
|
+ public boolean isOnGround()
|
|
|
{
|
|
|
- return prevMotionY;
|
|
|
- }
|
|
|
+ return onGround;
|
|
|
+ }
|
|
|
}
|