Now this might be a piece of cake to most of you, but it took me several attempts to create a satisfying result regarding this.
Since I didn’t find much regarding Collision Avoidance on the internet, I thought I post my function here. For two reasons!
Reason number 1, I have a feeling I am overcomplicating this and it could be done with much fewer lines of code. I know … I shouldn’t
even worry about that because my function does work perfectly fine (it seems). But yeah, I’m still very curious. I commented the code
for easier readability, please take a look!
Reason number 2, if my approach to Collision Avoidance does get your seal of approval I thought this might help others that struggle with it, since I
didn’t find much resources on that topic out there.
Thank you!
EDIT: The code is intented for a topdown 2D game in which you can move in all four directions (up, down, left, right).
public void move(float dx, float dy, Array<Entity> obstacles){
setBodyPos(x + dx, y + dy); // Set Body(Rectangle) to where it will be if dx/dy get applied
updateBodyCenter();
SortedIntList<Entity> overlappingObs = new SortedIntList<Entity>();
float distX, distY;
int distDirect;
for(Entity obs : obstacles){ // Loop through all available Obstacles
if(body.overlaps(obs.body)){ // Check if intersection with the Object is true
obs.updateBodyCenter();
distX = (centerX) - (obs.centerX);
distY = (centerY) - (obs.centerY);
distDirect = (int)(Math.pow(distX, 2) + Math.pow(distY, 2)); // Calculate the distance between this
// Entity and the Obstacle
int index = distDirect;
boolean tryIndex = true;
do{ // Do-While loop to avoid double indexes (Took me hours to find that error)
if(overlappingObs.get(index) == null){
overlappingObs.insert(index, obs); // Add the intersecting Obstacles to a List
tryIndex = false; // (Sorted from closest to farthest Obstacle)
}
else{
index++;
}
}while(tryIndex);
}
}
Iterator<SortedIntList.Node<Entity>> iterator = overlappingObs.iterator();
while (iterator.hasNext()) { // Loop through the sorted intersecting Obstacles
SortedIntList.Node<Entity> node = iterator.next();
Entity obs = node.value;
if(body.overlaps(obs.body)){
float xOffset = 0, yOffset = 0; // Calculate how much of the Obstacle's body intersects
if(centerX > obs.centerX) xOffset = body.x - (obs.body.x + obs.body.width);
if(centerX <= obs.centerX) xOffset = (body.x + body.width) - obs.body.x;
if(centerY > obs.centerY) yOffset = body.y - (obs.body.y + obs.body.height);
if(centerY <= obs.centerY) yOffset = (body.y + body.height) - obs.body.y;
if(Math.abs(yOffset) > Math.abs(xOffset)){ // Substract the calculated offsets from the dx, dy values
dx -= xOffset;
}
else if(Math.abs(xOffset) > Math.abs(yOffset)){
dy -= yOffset;
}
setBodyPos(x + dx, y + dy); // Update the Entity's body to be on the newly calculated position
updateBodyCenter();
}
}
x += dx;
y += dy;
overlappingObs.clear();
overlappingObs = null;
iterator = null;
}