Changed circleQuadCollisionEdge function -> Now works perfectly also with moving obstacles
Note: Just works for ball-obstacle-collision, when circle diameter is bigger than quad width or height, won't work anymore
This commit is contained in:
parent
77b927cb1a
commit
4629419d3e
@ -89,5 +89,50 @@
|
||||
</stars>
|
||||
<energy x="17.053387" y="-0.8066667"/>
|
||||
</level>
|
||||
<level packId="2" id="2" goalX="3.0" startSpeed="0.5" endSpeed="0.5" terrainEdge="-0.6" ceilingEdge="1.0">
|
||||
<terrainTiles class="java.util.ArrayList">
|
||||
<tileData x="-2.75" width="0.5"/>
|
||||
<tileData x="2.75" width="0.5"/>
|
||||
</terrainTiles>
|
||||
<ceilingTiles class="java.util.ArrayList">
|
||||
<tileData x="0.0" width="6.0"/>
|
||||
</ceilingTiles>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData floating="true" moving="true" deadly="false" leftEdge="-1.1566665" rightEdge="-0.6566666" height="0.5" y="-0.99333346">
|
||||
<moveComponent length="3.687" rotation="55.602" startOffset="0.0" direction="1.0" speed="0.0" hasPlayerXSpeed="true" triggerDistance="0.0"/>
|
||||
</obstacleData>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList"/>
|
||||
</level>
|
||||
<level packId="2" id="3" goalX="3.0" startSpeed="0.5" endSpeed="0.5" terrainEdge="-0.6" ceilingEdge="1.0">
|
||||
<terrainTiles class="java.util.ArrayList">
|
||||
<tileData x="-2.75" width="0.5"/>
|
||||
<tileData x="2.75" width="0.5"/>
|
||||
</terrainTiles>
|
||||
<ceilingTiles class="java.util.ArrayList">
|
||||
<tileData x="0.0" width="6.0"/>
|
||||
</ceilingTiles>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData floating="true" moving="true" deadly="false" leftEdge="-1.1233333" rightEdge="-0.62333333" height="0.5" y="-0.96000004">
|
||||
<moveComponent length="5.0" rotation="22.618" startOffset="0.0" direction="1.0" speed="0.0" hasPlayerXSpeed="true" triggerDistance="0.0"/>
|
||||
</obstacleData>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList"/>
|
||||
</level>
|
||||
<level packId="2" id="4" goalX="3.0" startSpeed="0.5" endSpeed="0.5" terrainEdge="-0.6" ceilingEdge="1.0">
|
||||
<terrainTiles class="java.util.ArrayList">
|
||||
<tileData x="-2.75" width="0.5"/>
|
||||
<tileData x="2.75" width="0.5"/>
|
||||
</terrainTiles>
|
||||
<ceilingTiles class="java.util.ArrayList">
|
||||
<tileData x="0.0" width="6.0"/>
|
||||
</ceilingTiles>
|
||||
<obstacles class="java.util.ArrayList">
|
||||
<obstacleData floating="true" moving="true" deadly="false" leftEdge="-1.1566666" rightEdge="-0.65666664" height="0.5" y="-0.92666656">
|
||||
<moveComponent length="2.929" rotation="84.817" startOffset="0.0" direction="1.0" speed="0.0" hasPlayerXSpeed="true" triggerDistance="0.0"/>
|
||||
</obstacleData>
|
||||
</obstacles>
|
||||
<stars class="java.util.ArrayList"/>
|
||||
</level>
|
||||
</levels>
|
||||
</levelPack>
|
@ -53,6 +53,12 @@ public class Vector {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector abs(){
|
||||
this.x = Math.abs(x);
|
||||
this.y = Math.abs(y);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Vector mul(float z) {
|
||||
x *= z;
|
||||
y *= z;
|
||||
|
@ -67,12 +67,10 @@ public class Obstacle extends Entity {
|
||||
moveProgress = 2 - moveProgress;
|
||||
moveDirection *= -1;
|
||||
}
|
||||
Vector oldPosition = new Vector(super.getPosition());
|
||||
|
||||
super.setPosition(moveComponent.getPositionForProgress(moveProgress));
|
||||
Vector newPosition = new Vector(super.getPosition());
|
||||
Vector move = newPosition.translate(oldPosition.negate());
|
||||
move.mul(1 / frameTime);
|
||||
super.setMovement(move);
|
||||
super.setMovement(moveComponent.getMovementVector(moveDirection));
|
||||
GameLog.i(super.getMovement().getX() + "; " + player.getMovement().getX());
|
||||
}
|
||||
|
||||
public boolean isMoving() {
|
||||
|
@ -7,7 +7,6 @@ import de.frajul.endlessroll.entities.collision.collisionData.EntityCollisionDat
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Circle;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Quad;
|
||||
import de.frajul.endlessroll.entities.collision.geometry.Triangle;
|
||||
import de.frajul.endlessroll.main.GameLog;
|
||||
|
||||
/**
|
||||
* Created by Julian on 01.12.2015.
|
||||
@ -140,69 +139,153 @@ public class CollisionDetector {
|
||||
if (isCircleQuadCollision(circle, quad)) {
|
||||
Edge edge = circleQuadCollisionEdge(circle, player.getMovement(), quad,
|
||||
entity.getMovement());
|
||||
//Obstacles with MoveComponent do not have entity.getMovement() --> if player not moving, relativeMovement.x = 0
|
||||
return new EntityCollisionData(entity, edge);
|
||||
}
|
||||
return new EntityCollisionData(null, null);
|
||||
}
|
||||
|
||||
|
||||
private Edge circleQuadCollisionEdge(Circle circle, Vector circleMovement, Quad quad, Vector quadMovement) {
|
||||
boolean circleFullyInsideQuad = false;
|
||||
if (circle.getCenter().getX() + circle.getRadius() <= quad.getRightEdge() && circle
|
||||
.getCenter().getX() - circle.getRadius() >= quad.getLeftEdge()) {
|
||||
if (circle.getCenter().getY() + circle.getRadius() <= quad.getTopEdge() && circle
|
||||
.getCenter().getY() - circle.getRadius() >= quad.getBottomEdge()) {
|
||||
circleFullyInsideQuad = true;
|
||||
}
|
||||
}
|
||||
if (circleFullyInsideQuad)
|
||||
return circleCenterInQuadCollisionEdge(circle, circleMovement, quad, quadMovement);
|
||||
return circlePartlyOutsideQuadCollisionEdge(circle, quad);
|
||||
}
|
||||
|
||||
private Edge circlePartlyOutsideQuadCollisionEdge(Circle circle, Quad quad) {
|
||||
Edge edge = Edge.NONE;
|
||||
if (circle.getCenter().getY() + circle.getRadius() >= quad.getTopEdge())
|
||||
edge = Edge.TOP;
|
||||
else if (circle.getCenter().getY() - circle.getRadius() <= quad.getBottomEdge())
|
||||
edge = Edge.BOTTOM;
|
||||
if (circle.getCenter().getX() - circle.getRadius() <= quad.getLeftEdge()) {
|
||||
if (edge != Edge.NONE) {
|
||||
if (edge == Edge.TOP) {
|
||||
float m = -1;
|
||||
float t = quad.getTopEdge() - m * quad.getLeftEdge();
|
||||
if (circle.getCenter().getY() >= m * circle.getCenter().getX() + t)
|
||||
edge = Edge.TOP;
|
||||
else
|
||||
edge = Edge.LEFT;
|
||||
} else if (edge == Edge.BOTTOM) {
|
||||
float m = 1;
|
||||
float t = quad.getBottomEdge() - m * quad.getLeftEdge();
|
||||
if (circle.getCenter().getY() <= m * circle.getCenter().getX() + t)
|
||||
edge = Edge.BOTTOM;
|
||||
else
|
||||
edge = Edge.LEFT;
|
||||
}
|
||||
} else
|
||||
edge = Edge.LEFT;
|
||||
} else if (circle.getCenter().getX() + circle.getRadius() >= quad.getRightEdge()) {
|
||||
if (edge != Edge.NONE) {
|
||||
if (edge == Edge.TOP) {
|
||||
float m = 1;
|
||||
float t = quad.getTopEdge() - m * quad.getRightEdge();
|
||||
if (circle.getCenter().getY() >= m * circle.getCenter().getX() + t)
|
||||
edge = Edge.TOP;
|
||||
else
|
||||
edge = Edge.RIGHT;
|
||||
} else if (edge == Edge.BOTTOM) {
|
||||
float m = -1;
|
||||
float t = quad.getBottomEdge() - m * quad.getRightEdge();
|
||||
if (circle.getCenter().getY() <= m * circle.getCenter().getX() + t)
|
||||
edge = Edge.BOTTOM;
|
||||
else
|
||||
edge = Edge.RIGHT;
|
||||
}
|
||||
} else
|
||||
edge = Edge.RIGHT;
|
||||
}
|
||||
return edge;
|
||||
}
|
||||
|
||||
private Edge circleCenterInQuadCollisionEdge(Circle circle, Vector circleMovement, Quad quad, Vector quadMovement) {
|
||||
Vector relativeMovement = circleMovement.translate(quadMovement.negate());
|
||||
|
||||
//LEFT || TOP || BOTTOM
|
||||
if (relativeMovement.x > 0) {
|
||||
//LEFT || BOTTOM
|
||||
if (relativeMovement.y > 0) {
|
||||
float toLeftDistance = quad.getLeftEdge() - circle.getCenter().x - circle.getRadius();
|
||||
float actualY = toLeftDistance * (relativeMovement.y / relativeMovement.x) + circle
|
||||
.getCenter().y + circle.getRadius();
|
||||
if (actualY <= quad.getBottomEdge())
|
||||
return Edge.BOTTOM;
|
||||
else
|
||||
return Edge.LEFT;
|
||||
float m = relativeMovement.getY() / relativeMovement.getX();
|
||||
float t = circle.getCenter().getY() - m * circle.getCenter().getX();
|
||||
|
||||
float yAtLeftEdge = m * quad.getLeftEdge() + t;
|
||||
boolean touchingLeftEdge = yAtLeftEdge < quad.getTopEdge() && yAtLeftEdge > quad
|
||||
.getBottomEdge();
|
||||
float yAtRightEdge = m * quad.getRightEdge() + t;
|
||||
boolean touchingRightEdge = yAtRightEdge < quad.getTopEdge() && yAtRightEdge > quad
|
||||
.getBottomEdge();
|
||||
|
||||
float xAtTopEdge = (quad.getTopEdge() - t) / m;
|
||||
boolean touchingTopEdge = xAtTopEdge >= quad.getLeftEdge() && xAtTopEdge <= quad
|
||||
.getRightEdge();
|
||||
float xAtBottomEdge = (quad.getBottomEdge() - t) / m;
|
||||
boolean touchingBottomEdge = xAtBottomEdge >= quad.getLeftEdge() && xAtBottomEdge <= quad
|
||||
.getRightEdge();
|
||||
|
||||
if (relativeMovement.getX() == 0) {
|
||||
if (circle.getCenter().getX() - circle.getRadius() <= quad.getRightEdge() && circle
|
||||
.getCenter().getX() + circle.getRadius() >= quad.getLeftEdge()) {
|
||||
touchingTopEdge = true;
|
||||
touchingBottomEdge = true;
|
||||
}
|
||||
//LEFT || TOP
|
||||
else if (relativeMovement.y < 0) {
|
||||
float toLeftDistance = quad.getLeftEdge() - circle.getCenter().x - circle.getRadius();
|
||||
float actualY = toLeftDistance * (relativeMovement.y / relativeMovement.x) + circle
|
||||
.getCenter().y - circle.getRadius();
|
||||
if (actualY > quad.getTopEdge())
|
||||
return Edge.TOP;
|
||||
else
|
||||
}
|
||||
|
||||
// CORNERS BELONGING TO TOP / BOTTOM EDGES
|
||||
if (touchingLeftEdge) {
|
||||
if (touchingRightEdge) {
|
||||
if (circle.getCenter().getX() <= quad.getPosition().getX())
|
||||
return Edge.LEFT;
|
||||
return Edge.RIGHT;
|
||||
} else if (touchingTopEdge) {
|
||||
// Normale through vertex
|
||||
float mn = -1 / m;
|
||||
float tn = quad.getTopEdge() - mn * quad.getLeftEdge();
|
||||
if (circle.getCenter().getY() < mn * circle.getCenter().getX() + tn)
|
||||
return Edge.LEFT;
|
||||
return Edge.TOP;
|
||||
} else if (touchingBottomEdge) {
|
||||
// Normale through vertex
|
||||
float mn = -1 / m;
|
||||
float tn = quad.getBottomEdge() - mn * quad.getLeftEdge();
|
||||
if (circle.getCenter().getY() > mn * circle.getCenter().getX() + tn)
|
||||
return Edge.LEFT;
|
||||
return Edge.BOTTOM;
|
||||
} else {
|
||||
return Edge.LEFT;
|
||||
}
|
||||
}
|
||||
//RIGHT || TOP || BOTTOM
|
||||
else if (relativeMovement.x < 0) {
|
||||
//RIGHT || BOTTOM
|
||||
if (relativeMovement.y > 0) {
|
||||
float toRightDistance = quad.getRightEdge() - circle.getCenter().x + circle.getRadius();
|
||||
float actualY = toRightDistance * (relativeMovement.y / relativeMovement.x) + circle
|
||||
.getCenter().y + circle.getRadius();
|
||||
if (actualY <= quad.getBottomEdge())
|
||||
return Edge.BOTTOM;
|
||||
else
|
||||
} else if (touchingRightEdge) {
|
||||
if (touchingTopEdge) {
|
||||
// Normale through vertex
|
||||
float mn = -1 / m;
|
||||
float tn = quad.getTopEdge() - mn * quad.getRightEdge();
|
||||
if (circle.getCenter().getY() < mn * circle.getCenter().getX() + tn)
|
||||
return Edge.RIGHT;
|
||||
}
|
||||
//RIGHT || TOP
|
||||
else if (relativeMovement.y < 0) {
|
||||
float toRightDistance = quad.getRightEdge() - circle.getCenter().x + circle.getRadius();
|
||||
float actualY = toRightDistance * (relativeMovement.y / relativeMovement.x) + circle
|
||||
.getCenter().y - circle.getRadius();
|
||||
if (actualY > quad.getTopEdge())
|
||||
return Edge.TOP;
|
||||
else
|
||||
return Edge.TOP;
|
||||
} else if (touchingBottomEdge) {
|
||||
// Normale through vertex
|
||||
float mn = -1 / m;
|
||||
float tn = quad.getBottomEdge() - mn * quad.getRightEdge();
|
||||
if (circle.getCenter().getY() > mn * circle.getCenter().getX() + tn)
|
||||
return Edge.RIGHT;
|
||||
return Edge.BOTTOM;
|
||||
} else {
|
||||
return Edge.RIGHT;
|
||||
}
|
||||
} else {
|
||||
if (relativeMovement.y > 0)
|
||||
} else if (touchingTopEdge) {
|
||||
if (touchingBottomEdge) {
|
||||
if (circle.getCenter().getY() >= quad.getPosition().getY())
|
||||
return Edge.TOP;
|
||||
return Edge.BOTTOM;
|
||||
else if (relativeMovement.y < 0)
|
||||
} else {
|
||||
return Edge.TOP;
|
||||
}
|
||||
} else if (touchingBottomEdge) {
|
||||
return Edge.BOTTOM;
|
||||
}
|
||||
return Edge.NONE;
|
||||
}
|
||||
|
@ -71,9 +71,7 @@ public class MoveComponent {
|
||||
|
||||
public void calcSpeedForPlayerSpeed(Player player) {
|
||||
float xSpeed = player.getSpeed();
|
||||
double invertRotationRadians = Math.toRadians(90 - getRotation());
|
||||
float ySpeed = (float) (xSpeed * Math.sin(invertRotationRadians));
|
||||
speed = (float) Math.sqrt(xSpeed * xSpeed + ySpeed * ySpeed);
|
||||
speed = xSpeed / new Vector(triangleWidth, triangleHeight).normalize().getX();
|
||||
speed /= TRANSITION_VALUE;
|
||||
}
|
||||
|
||||
@ -81,6 +79,11 @@ public class MoveComponent {
|
||||
return triangleWidth >= 0 ? position.x : position.x + triangleWidth;
|
||||
}
|
||||
|
||||
public Vector getMovementVector(float moveDirection) {
|
||||
return new Vector(triangleWidth, triangleHeight).normalize()
|
||||
.mul(moveDirection * getSpeed() * TRANSITION_VALUE);
|
||||
}
|
||||
|
||||
public Vector getPositionForProgress(float progress) {
|
||||
return new Vector(position.x + triangleWidth * progress,
|
||||
position.y + triangleHeight * progress);
|
||||
|
Loading…
x
Reference in New Issue
Block a user