From 4629419d3eaa803cba8e25008ef9f6a29038c877 Mon Sep 17 00:00:00 2001
From: = <=>
Date: Sun, 7 Jan 2018 15:39:25 +0100
Subject: [PATCH] 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
---
.../main/assets/levelpacks/Icy Mountains.xml | 45 +++++
.../de/frajul/endlessroll/data/Vector.java | 6 +
.../frajul/endlessroll/entities/Obstacle.java | 8 +-
.../entities/collision/CollisionDetector.java | 171 +++++++++++++-----
.../endlessroll/levels/MoveComponent.java | 9 +-
5 files changed, 187 insertions(+), 52 deletions(-)
diff --git a/app/src/main/assets/levelpacks/Icy Mountains.xml b/app/src/main/assets/levelpacks/Icy Mountains.xml
index 6f9fd15..2a303dc 100644
--- a/app/src/main/assets/levelpacks/Icy Mountains.xml
+++ b/app/src/main/assets/levelpacks/Icy Mountains.xml
@@ -89,5 +89,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/de/frajul/endlessroll/data/Vector.java b/app/src/main/java/de/frajul/endlessroll/data/Vector.java
index 1fbbdb9..316f21d 100644
--- a/app/src/main/java/de/frajul/endlessroll/data/Vector.java
+++ b/app/src/main/java/de/frajul/endlessroll/data/Vector.java
@@ -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;
diff --git a/app/src/main/java/de/frajul/endlessroll/entities/Obstacle.java b/app/src/main/java/de/frajul/endlessroll/entities/Obstacle.java
index af2fd86..fefa1ee 100644
--- a/app/src/main/java/de/frajul/endlessroll/entities/Obstacle.java
+++ b/app/src/main/java/de/frajul/endlessroll/entities/Obstacle.java
@@ -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() {
diff --git a/app/src/main/java/de/frajul/endlessroll/entities/collision/CollisionDetector.java b/app/src/main/java/de/frajul/endlessroll/entities/collision/CollisionDetector.java
index d66102d..a94a01c 100644
--- a/app/src/main/java/de/frajul/endlessroll/entities/collision/CollisionDetector.java
+++ b/app/src/main/java/de/frajul/endlessroll/entities/collision/CollisionDetector.java
@@ -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;
}
diff --git a/app/src/main/java/de/frajul/endlessroll/levels/MoveComponent.java b/app/src/main/java/de/frajul/endlessroll/levels/MoveComponent.java
index 5fce6fd..90d9797 100644
--- a/app/src/main/java/de/frajul/endlessroll/levels/MoveComponent.java
+++ b/app/src/main/java/de/frajul/endlessroll/levels/MoveComponent.java
@@ -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);