|
@@ -1,5 +1,6 @@
|
|
|
package me.hammerle.supersnuvi.entity;
|
|
|
|
|
|
+import java.util.Collections;
|
|
|
import java.util.LinkedList;
|
|
|
import javafx.scene.image.Image;
|
|
|
import javafx.scene.image.PixelWriter;
|
|
@@ -8,8 +9,9 @@ import javafx.scene.paint.Color;
|
|
|
import me.hammerle.supersnuvi.input.IKeyHandler;
|
|
|
import me.hammerle.supersnuvi.rendering.GameRenderer;
|
|
|
import me.hammerle.supersnuvi.rendering.WorldRenderer;
|
|
|
-import me.hammerle.supersnuvi.tiles.Tile;
|
|
|
+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 class Entity
|
|
@@ -21,14 +23,16 @@ public class Entity
|
|
|
// added correction factor, real life gravity seems to strong
|
|
|
public static double GRAVITY = GameRenderer.TILE_SIZE * 9.81 / 60 * 0.1;
|
|
|
|
|
|
- private double prevX;
|
|
|
- private double prevY;
|
|
|
+ private double prevPosX;
|
|
|
+ private double prevPrevY;
|
|
|
private double posX;
|
|
|
private double posY;
|
|
|
|
|
|
- protected double motionX;
|
|
|
- protected double motionY;
|
|
|
- public boolean onGround;
|
|
|
+ private double prevMotionX;
|
|
|
+ private double prevMotionY;
|
|
|
+ private double motionX;
|
|
|
+ private double motionY;
|
|
|
+ private boolean onGround;
|
|
|
|
|
|
private CollisionBox collisionBox;
|
|
|
private double width;
|
|
@@ -36,15 +40,15 @@ public class Entity
|
|
|
|
|
|
private Image image;
|
|
|
|
|
|
- private WorldRenderer map;
|
|
|
+ private WorldRenderer world;
|
|
|
|
|
|
public Entity(WorldRenderer map, double x, double y, double width, double height)
|
|
|
{
|
|
|
- this.map = map;
|
|
|
+ this.world = map;
|
|
|
this.posX = x;
|
|
|
this.posY = y;
|
|
|
- this.prevX = x;
|
|
|
- this.prevY = y;
|
|
|
+ this.prevPosX = x;
|
|
|
+ this.prevPrevY = y;
|
|
|
this.motionX = 0;
|
|
|
this.motionY = 0;
|
|
|
this.onGround = false;
|
|
@@ -68,6 +72,10 @@ public class Entity
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ //--------------------------------------------------------------------------
|
|
|
+ // ticking
|
|
|
+ //--------------------------------------------------------------------------
|
|
|
+
|
|
|
public void controlTick(IKeyHandler keyHandler)
|
|
|
{
|
|
|
}
|
|
@@ -79,11 +87,14 @@ public class Entity
|
|
|
motionY -= GRAVITY;
|
|
|
}
|
|
|
|
|
|
- prevX = posX;
|
|
|
- prevY = posY;
|
|
|
+ prevMotionX = motionX;
|
|
|
+ prevMotionY = motionY;
|
|
|
+
|
|
|
+ prevPosX = posX;
|
|
|
+ prevPrevY = posY;
|
|
|
setAllowedMotion();
|
|
|
posX += motionX;
|
|
|
- posY += motionY;
|
|
|
+ posY += motionY;
|
|
|
|
|
|
motionX = Utils.round(motionX);
|
|
|
motionY = Utils.round(motionY);
|
|
@@ -95,8 +106,29 @@ public class Entity
|
|
|
|
|
|
posX = Utils.round(posX);
|
|
|
posY = Utils.round(posY);
|
|
|
+
|
|
|
+ if(!onGround)
|
|
|
+ {
|
|
|
+ motionX *= 0.7;
|
|
|
+ }
|
|
|
+
|
|
|
+ LinkedList<CollisionBox> list = world.getCollisionBoxesAt(this, getBox());
|
|
|
+ if(!list.isEmpty())
|
|
|
+ {
|
|
|
+ System.out.println(getBox());
|
|
|
+ list.forEach(s -> System.out.println(s));
|
|
|
+ System.out.println("WELL");
|
|
|
+ posX = prevPosX;
|
|
|
+ posY = prevPrevY;
|
|
|
+ }
|
|
|
+
|
|
|
+ doCollision();
|
|
|
}
|
|
|
|
|
|
+ //--------------------------------------------------------------------------
|
|
|
+ // gravity
|
|
|
+ //--------------------------------------------------------------------------
|
|
|
+
|
|
|
public final void jump()
|
|
|
{
|
|
|
if(onGround)
|
|
@@ -106,11 +138,25 @@ public class Entity
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public boolean isAffectedByGravity()
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
public double getJumpPower()
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+ public boolean isOnGround()
|
|
|
+ {
|
|
|
+ return onGround;
|
|
|
+ }
|
|
|
+
|
|
|
+ //--------------------------------------------------------------------------
|
|
|
+ // collision stuff
|
|
|
+ //--------------------------------------------------------------------------
|
|
|
+
|
|
|
public final CollisionBox getBox()
|
|
|
{
|
|
|
return collisionBox.reset().offset(posX, posY);
|
|
@@ -143,7 +189,7 @@ public class Entity
|
|
|
// expanding area by the size of the entity
|
|
|
CollisionBox expandedBox = eBox.copy().expand(motionX, motionY);
|
|
|
|
|
|
- LinkedList<CollisionBox> allBoxes = map.getCollisionBoxesAt(this, expandedBox);
|
|
|
+ LinkedList<CollisionBox> allBoxes = world.getCollisionBoxesAt(this, expandedBox);
|
|
|
if(allBoxes.isEmpty())
|
|
|
{
|
|
|
return;
|
|
@@ -151,6 +197,7 @@ public class Entity
|
|
|
|
|
|
double x;
|
|
|
double y;
|
|
|
+ char lastWall = 0;
|
|
|
|
|
|
if(dirX >= 0)
|
|
|
{
|
|
@@ -166,15 +213,51 @@ public class Entity
|
|
|
}
|
|
|
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())
|
|
|
+ if(y > box.getMinY() && y < box.getMaxY())
|
|
|
{
|
|
|
endX = box.getMinX();
|
|
|
+ endY = y;
|
|
|
+ lastWall = 'x';
|
|
|
}
|
|
|
- else if(x >= box.getMinX() && x <= box.getMaxX())
|
|
|
+ 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)
|
|
|
+ {
|
|
|
+ if(endX <= box.getMinX() || lineEndY >= box.getMaxY() ||
|
|
|
+ endX >= box.getMaxX() || endY <= box.getMinY())
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ 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())
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ lineEndX = box.getMinX();
|
|
|
+ }
|
|
|
+ endX = lineEndX;
|
|
|
+ }
|
|
|
}
|
|
|
else // Right - Up
|
|
|
{
|
|
@@ -188,15 +271,51 @@ public class Entity
|
|
|
}
|
|
|
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())
|
|
|
+ if(y > box.getMinY() && y < box.getMaxY())
|
|
|
{
|
|
|
endX = box.getMinX();
|
|
|
+ endY = y;
|
|
|
+ lastWall = 'x';
|
|
|
}
|
|
|
- else if(x >= box.getMinX() && x <= box.getMaxX())
|
|
|
+ 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)
|
|
|
+ {
|
|
|
+ if(endX <= box.getMinX() || lineEndY <= box.getMinY() ||
|
|
|
+ endX >= box.getMaxX() || endY >= box.getMaxY())
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ 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())
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ lineEndX = box.getMinX();
|
|
|
+ }
|
|
|
+ endX = lineEndX;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
else
|
|
@@ -213,14 +332,50 @@ public class Entity
|
|
|
}
|
|
|
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())
|
|
|
+ if(y > box.getMinY() && y < box.getMaxY())
|
|
|
{
|
|
|
endX = box.getMaxX();
|
|
|
+ endY = y;
|
|
|
+ lastWall = 'x';
|
|
|
}
|
|
|
- else if(x >= box.getMinX() && x <= box.getMaxX())
|
|
|
+ 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)
|
|
|
+ {
|
|
|
+ if(endX <= box.getMinX() || lineEndY >= box.getMaxY() ||
|
|
|
+ endX >= box.getMaxX() || endY <= box.getMinY())
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ lineEndY = box.getMaxY();
|
|
|
+ }
|
|
|
+ endY = lineEndY;
|
|
|
+ }
|
|
|
+ else if(lastWall == 'y')
|
|
|
+ {
|
|
|
+ double lineEndX = startX + dirX;
|
|
|
+ for(CollisionBox box : allBoxes)
|
|
|
+ {
|
|
|
+ if(lineEndX >= box.getMaxX() || endY >= box.getMaxY() ||
|
|
|
+ endX <= box.getMinX() || endY <= box.getMinY())
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ lineEndX = box.getMaxX();
|
|
|
}
|
|
|
+ endX = lineEndX;
|
|
|
}
|
|
|
}
|
|
|
else // Left - Up
|
|
@@ -235,14 +390,50 @@ public class Entity
|
|
|
}
|
|
|
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())
|
|
|
+ if(y > box.getMinY() && y < box.getMaxY())
|
|
|
{
|
|
|
endX = box.getMaxX();
|
|
|
+ endY = y;
|
|
|
+ lastWall = 'x';
|
|
|
}
|
|
|
- else if(x >= box.getMinX() && x <= box.getMaxX())
|
|
|
+ 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)
|
|
|
+ {
|
|
|
+ if(endX <= box.getMinX() || lineEndY <= box.getMinY() ||
|
|
|
+ endX >= box.getMaxX() || endY >= box.getMaxY())
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ lineEndY = box.getMinY();
|
|
|
}
|
|
|
+ endY = lineEndY;
|
|
|
+ }
|
|
|
+ else if(lastWall == 'y')
|
|
|
+ {
|
|
|
+ double lineEndX = startX + dirX;
|
|
|
+ for(CollisionBox box : allBoxes)
|
|
|
+ {
|
|
|
+ if(lineEndX >= box.getMaxX() || endY >= box.getMaxY() ||
|
|
|
+ endX <= box.getMinX() || endY <= box.getMinY())
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ lineEndX = box.getMaxX();
|
|
|
+ }
|
|
|
+ endX = lineEndX;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -261,21 +452,44 @@ public class Entity
|
|
|
System.exit(0);
|
|
|
}
|
|
|
|
|
|
- System.out.println("VORHER " + dirX + " " + dirY);
|
|
|
- System.out.println("NACHHER " + motionX + " " + motionY);
|
|
|
+ /*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);
|
|
|
}
|
|
|
|
|
|
- public final Image getImage()
|
|
|
+ private void doCollision()
|
|
|
{
|
|
|
- return image;
|
|
|
+ CollisionBox box = getBox().copy();
|
|
|
+ for(Face f : Face.values())
|
|
|
+ {
|
|
|
+ box.reset();
|
|
|
+ box.expand(f.getCollisionOffsetX(), f.getCollisionOffsetY());
|
|
|
+ world.getEntitiesCollidingWith(this, box).forEach(ent -> this.onCollideWithEntity(ent, f));
|
|
|
+ world.getTilesCollidingWith(box).forEach(loc ->
|
|
|
+ {
|
|
|
+ this.onCollideWithTile(loc, f);
|
|
|
+ loc.getTile().onEntityCollide(this, loc.getX(), loc.getY(), f);
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- public boolean isAffectedByGravity()
|
|
|
+ public void onCollideWithTile(Location loc, Face face)
|
|
|
{
|
|
|
- return true;
|
|
|
}
|
|
|
|
|
|
+ public void onCollideWithEntity(Entity ent, Face face)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ //--------------------------------------------------------------------------
|
|
|
+ // basic coord and motion stuff
|
|
|
+ //--------------------------------------------------------------------------
|
|
|
+
|
|
|
public final double getX()
|
|
|
{
|
|
|
return posX;
|
|
@@ -286,6 +500,52 @@ public class Entity
|
|
|
return posY;
|
|
|
}
|
|
|
|
|
|
+ public final double getPreviousX()
|
|
|
+ {
|
|
|
+ return prevPosX;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final double getPreviousY()
|
|
|
+ {
|
|
|
+ return prevPrevY;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final double getMotionX()
|
|
|
+ {
|
|
|
+ return motionX;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final void setMotionX(double motionX)
|
|
|
+ {
|
|
|
+ prevMotionX = this.motionX;
|
|
|
+ this.motionX = motionX;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final double getMotionY()
|
|
|
+ {
|
|
|
+ return motionY;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final void setMotionY(double motionY)
|
|
|
+ {
|
|
|
+ prevMotionY = this.motionY;
|
|
|
+ this.motionY = motionY;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final double getPreviousMotionX()
|
|
|
+ {
|
|
|
+ return prevMotionX;
|
|
|
+ }
|
|
|
+
|
|
|
+ public final double getPreviousMotionY()
|
|
|
+ {
|
|
|
+ return prevMotionY;
|
|
|
+ }
|
|
|
+
|
|
|
+ //--------------------------------------------------------------------------
|
|
|
+ // rendering stuff
|
|
|
+ //--------------------------------------------------------------------------
|
|
|
+
|
|
|
public final double getRenderX()
|
|
|
{
|
|
|
return posX;
|
|
@@ -295,4 +555,9 @@ public class Entity
|
|
|
{
|
|
|
return posY + height;
|
|
|
}
|
|
|
+
|
|
|
+ public final Image getImage()
|
|
|
+ {
|
|
|
+ return image;
|
|
|
+ }
|
|
|
}
|