|
@@ -1,5 +1,7 @@
|
|
package me.hammerle.supersnuvi.entity;
|
|
package me.hammerle.supersnuvi.entity;
|
|
|
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.List;
|
|
import me.hammerle.supersnuvi.entity.components.ai.Controller;
|
|
import me.hammerle.supersnuvi.entity.components.ai.Controller;
|
|
import me.hammerle.supersnuvi.entity.components.Energy;
|
|
import me.hammerle.supersnuvi.entity.components.Energy;
|
|
import me.hammerle.supersnuvi.entity.components.Health;
|
|
import me.hammerle.supersnuvi.entity.components.Health;
|
|
@@ -30,6 +32,8 @@ public final class Entity
|
|
private final float height;
|
|
private final float height;
|
|
// own force used by the controller component
|
|
// own force used by the controller component
|
|
private final Vector ownForce = new Vector();
|
|
private final Vector ownForce = new Vector();
|
|
|
|
+ // the final motion of the last tick
|
|
|
|
+ private final Vector lastMotion = new Vector();
|
|
// the motion, reduced by the movement collision check
|
|
// the motion, reduced by the movement collision check
|
|
private final Vector motion = new Vector();
|
|
private final Vector motion = new Vector();
|
|
// the friction reducing motion each tick
|
|
// the friction reducing motion each tick
|
|
@@ -203,6 +207,11 @@ public final class Entity
|
|
return maxX > getX() && getX() + width > minX && maxY > getY() && getY() + height > minY;
|
|
return maxX > getX() && getX() + width > minX && maxY > getY() && getY() + height > minY;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public boolean isColliding(Entity ent)
|
|
|
|
+ {
|
|
|
|
+ return isColliding(ent.getX(), ent.getY(), ent.getX() + ent.width, ent.getY() + ent.height);
|
|
|
|
+ }
|
|
|
|
+
|
|
private Face getCollidingFace(Entity o)
|
|
private Face getCollidingFace(Entity o)
|
|
{
|
|
{
|
|
return Utils.getCollidingFace(
|
|
return Utils.getCollidingFace(
|
|
@@ -226,6 +235,10 @@ public final class Entity
|
|
|
|
|
|
public void tick(Level level)
|
|
public void tick(Level level)
|
|
{
|
|
{
|
|
|
|
+ // last motion is current motion, last motion will be set in move
|
|
|
|
+ motion.set(lastMotion);
|
|
|
|
+ lastMotion.set(0.0f, 0.0f);
|
|
|
|
+
|
|
// reset own force
|
|
// reset own force
|
|
ownForce.set(0.0f, 0.0f);
|
|
ownForce.set(0.0f, 0.0f);
|
|
|
|
|
|
@@ -233,8 +246,11 @@ public final class Entity
|
|
lastPos.set(pos);
|
|
lastPos.set(pos);
|
|
|
|
|
|
// update onGround before controller tick
|
|
// update onGround before controller tick
|
|
- // ToDo: does not work for ramps
|
|
|
|
onGround = isOnTileGround(level);
|
|
onGround = isOnTileGround(level);
|
|
|
|
+ if(onGround)
|
|
|
|
+ {
|
|
|
|
+ motion.setY(0.0f);
|
|
|
|
+ }
|
|
|
|
|
|
// tick components
|
|
// tick components
|
|
controller.tick(this, level);
|
|
controller.tick(this, level);
|
|
@@ -262,11 +278,26 @@ public final class Entity
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
- public void move(Level level)
|
|
|
|
|
|
+ public int move(Level level)
|
|
{
|
|
{
|
|
|
|
+ if(motion.getX() == 0.0f && motion.getY() == 0.0f)
|
|
|
|
+ {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ Vector maxMotion = new Vector();
|
|
|
|
+ maxMotion.set(motion);
|
|
|
|
+
|
|
reduceMotionByTiles(level);
|
|
reduceMotionByTiles(level);
|
|
- reduceMotionByEntities(level);
|
|
|
|
|
|
+ reduceMotionByEntities(level);
|
|
pos.add(motion);
|
|
pos.add(motion);
|
|
|
|
+
|
|
|
|
+ int r = (motion.getX() == 0.0f && motion.getY() == 0.0f) ? 0 : 1;
|
|
|
|
+
|
|
|
|
+ lastMotion.add(motion);
|
|
|
|
+ maxMotion.sub(motion);
|
|
|
|
+ motion.set(maxMotion);
|
|
|
|
+
|
|
|
|
+ return r;
|
|
}
|
|
}
|
|
|
|
|
|
private boolean isOnTileGround(Level level)
|
|
private boolean isOnTileGround(Level level)
|
|
@@ -291,6 +322,18 @@ public final class Entity
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ for(Entity ent : level.getEntities())
|
|
|
|
+ {
|
|
|
|
+ if(ent == this)
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if(ent.getMovement().isSolid() && ent.isColliding(minX, minY, maxX, maxY))
|
|
|
|
+ {
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -322,6 +365,106 @@ public final class Entity
|
|
|
|
|
|
private void reduceMotionByEntities(Level level)
|
|
private void reduceMotionByEntities(Level level)
|
|
{
|
|
{
|
|
|
|
+ if(motion.getX() == 0.0f && motion.getY() == 0.0f)
|
|
|
|
+ {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ float mx = motion.getX();
|
|
|
|
+ float my = motion.getY();
|
|
|
|
+
|
|
|
|
+ float oldPosX = pos.getX();
|
|
|
|
+ float oldPosY = pos.getY();
|
|
|
|
+
|
|
|
|
+ while(mx != 0.0 || my != 0.0)
|
|
|
|
+ {
|
|
|
|
+ if(mx != 0.0f)
|
|
|
|
+ {
|
|
|
|
+ float oldX = pos.getX();
|
|
|
|
+ if(mx < 0.0)
|
|
|
|
+ {
|
|
|
|
+ if(mx > -STEP)
|
|
|
|
+ {
|
|
|
|
+ pos.addX(mx);
|
|
|
|
+ mx = 0.0f;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ pos.addX(-STEP);
|
|
|
|
+ mx += STEP;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(mx > 0.0)
|
|
|
|
+ {
|
|
|
|
+ if(mx < STEP)
|
|
|
|
+ {
|
|
|
|
+ pos.addX(mx);
|
|
|
|
+ mx = 0.0f;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ pos.addX(STEP);
|
|
|
|
+ mx -= STEP;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<Entity> list = isCollidingWithEntities(level);
|
|
|
|
+ for(Entity ent : list)
|
|
|
|
+ {
|
|
|
|
+ if(move.isSolid() || ent.move.isSolid())
|
|
|
|
+ {
|
|
|
|
+ //controller.onCollideWithEntity(this, ent, getCollidingFace(ent));
|
|
|
|
+ pos.setX(oldX);
|
|
|
|
+ mx = 0.0f;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(my != 0.0f)
|
|
|
|
+ {
|
|
|
|
+ float oldY = pos.getY();
|
|
|
|
+
|
|
|
|
+ if(my < 0.0)
|
|
|
|
+ {
|
|
|
|
+ if(my > -STEP)
|
|
|
|
+ {
|
|
|
|
+ pos.addY(my);
|
|
|
|
+ my = 0.0f;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ pos.addY(-STEP);
|
|
|
|
+ my += STEP;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(my > 0.0)
|
|
|
|
+ {
|
|
|
|
+ if(my < STEP)
|
|
|
|
+ {
|
|
|
|
+ pos.addY(my);
|
|
|
|
+ my = 0.0f;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ pos.addY(STEP);
|
|
|
|
+ my -= STEP;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<Entity> list = isCollidingWithEntities(level);
|
|
|
|
+ for(Entity ent : list)
|
|
|
|
+ {
|
|
|
|
+ if(move.isSolid() || ent.move.isSolid())
|
|
|
|
+ {
|
|
|
|
+ //controller.onCollideWithEntity(this, ent, getCollidingFace(ent));
|
|
|
|
+ pos.setY(oldY);
|
|
|
|
+ my = 0.0f;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ motion.set(pos.getX() - oldPosX, pos.getY() - oldPosY);
|
|
|
|
+ pos.set(oldPosX, oldPosY);
|
|
}
|
|
}
|
|
|
|
|
|
private boolean isCollidingWithTiles(int startX, int startY, int endX, int endY, Level level)
|
|
private boolean isCollidingWithTiles(int startX, int startY, int endX, int endY, Level level)
|
|
@@ -342,10 +485,42 @@ public final class Entity
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ private List<Entity> isCollidingWithEntities(Level level)
|
|
|
|
+ {
|
|
|
|
+ float minX = pos.getX();
|
|
|
|
+ float minY = pos.getY();
|
|
|
|
+ float maxX = pos.getX() + width;
|
|
|
|
+ float maxY = pos.getY() + height;
|
|
|
|
+ ArrayList<Entity> list = new ArrayList<>();
|
|
|
|
+ for(Entity ent : level.getEntities())
|
|
|
|
+ {
|
|
|
|
+ if(ent == this)
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if(ent.isColliding(minX, minY, maxX, maxY))
|
|
|
|
+ {
|
|
|
|
+ list.add(ent);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ for(Entity ent : level.getEntitiesInQueue())
|
|
|
|
+ {
|
|
|
|
+ if(ent == this)
|
|
|
|
+ {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if(ent.isColliding(minX, minY, maxX, maxY))
|
|
|
|
+ {
|
|
|
|
+ list.add(ent);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return list;
|
|
|
|
+ }
|
|
|
|
|
|
public void reduceMotionByTiles(Level level)
|
|
public void reduceMotionByTiles(Level level)
|
|
{
|
|
{
|
|
- if(move.canMoveEverywhere())
|
|
|
|
|
|
+ if(move.canMoveEverywhere() || (motion.getX() == 0.0f && motion.getY() == 0.0f))
|
|
{
|
|
{
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -353,11 +528,6 @@ public final class Entity
|
|
float mx = motion.getX();
|
|
float mx = motion.getX();
|
|
float my = motion.getY();
|
|
float my = motion.getY();
|
|
|
|
|
|
- if(mx == 0.0f && my == 0.0f)
|
|
|
|
- {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
int startX;
|
|
int startX;
|
|
int endX;
|
|
int endX;
|
|
if(mx < 0.0f)
|
|
if(mx < 0.0f)
|
|
@@ -487,4 +657,10 @@ public final class Entity
|
|
{
|
|
{
|
|
return onGround;
|
|
return onGround;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public String toString()
|
|
|
|
+ {
|
|
|
|
+ return String.format("(%f, %f, %f, %f)", pos.getX(), pos.getY(), pos.getX() + width, pos.getY() + height);
|
|
|
|
+ }
|
|
}
|
|
}
|