I am trying to create a Vampire survivor type game, and I am currently creating the logic of the enemies, but I have found a problem, and that is that they are able to overlap each other, to a point where you don't even notice that there are 2, which is uncomfortable because I need them to be able to collide and maybe be one on top of the other slightly, but not to that extreme.
I have tried to use a code to solve the collisions, but when I try to do it these two just move one after the other pushing each other, even so I feel that my code is not done in the best way.
Enemy Movement:
public void move(double playerX, double playerY, double fps, List<Enemies> enemiesList){
double angle = Math.atan2(playerY - y, playerX - x);
x += Math.cos(angle) * speed / fps;
y += Math.sin(angle) * speed / fps;
hitbox.setFrame(x, y, 40, 40);
for (int i = 0; i < enemiesList.size(); i++) {
if (this == enemiesList.get(i)) {
continue;
}
if (hitbox.intersects(enemiesList.get(i).getHitbox())) {
resolveCollition(enemiesList.get(i).getHitbox());
}
}
}
the attempt to solve it
private void resolveCollition(Rectangle2D.Double otherHitbox) {
double overX;
double overY;
if (this.hitbox.getCenterX() < hitbox.getCenterX()) {
overX = hitbox.getMaxX() - this.hitbox.getMinX();
} else {
overX = hitbox.getMinX() - this.hitbox.getMaxX();
}
if (this.hitbox.getCenterY() < hitbox.getCenterY()) {
overY = hitbox.getMaxY() - this.hitbox.getMinY();
} else {
overY = hitbox.getMinY() - this.hitbox.getMaxY();
}
x -= overX;
y -= overY;
}
I would like to know if there is a better way to solve the overlap issue without the enemies continuously pushing each other.
Welp, I ended up with this:
double angle = Math.atan2(playerY - y, playerX - x);
double deltaX = Math.cos(angle) * speed/fps;
double deltaY = Math.sin(angle) * speed/fps;
Rectangle2D deltaHitbox = new Rectangle2D.Double(x+deltaX, y+deltaY, 40, 40);
Iterator<Enemies> iterator = enemiesList.iterator();
while (iterator.hasNext()) {
Enemies enemy = iterator.next();
if (enemy == this)continue;
if (enemy.hitbox.intersects(deltaHitbox)) {
double deltaXCenter = -deltaHitbox.getCenterX() + enemy.hitbox.getCenterX();
double deltaYCenter = -deltaHitbox.getCenterY() + enemy.hitbox.getCenterY();
int separation = 40;
if (Math.abs(deltaXCenter) > Math.abs(deltaYCenter)) {
if (deltaXCenter > 0) {
x += (deltaXCenter - separation);
} else {
x -= (Math.abs(deltaXCenter) - separation);
}
} else {
if (deltaYCenter > 0) {
y += (deltaYCenter - separation);
} else {
y -= (Math.abs(deltaYCenter) - separation);
}
}
}
}
x += deltaX;
y += deltaY;
hitbox.setFrame(x, y, 40, 40);
so I simply calculate the difference between the centers when moving it hypothetically, and subtract the difference between them, so when it is added, it will always be at a distance which when adding the normal movement, it will not reach the other, and that works even when there is more than one (I do not know if I could explain the idea well).