0

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.

2
  • If it's always going to be just 2 enemies, stop one enemy and let the other move until they are no longer colliding. Commented Jan 14 at 17:44
  • As I said, it's a vampire survivor style game, so there will be... a lot of enemies on screen at the same time. Commented Jan 14 at 19:41

2 Answers 2

0

You could implement something like:

public void move( object, direction, others ) {
   if( direction == LEFT ) {

        // empty object
      virtualObject.setLocation( object.getLocation() );
      virtualObject.incrementX();

        // method that verifies that in the current position 
        // there is no collision with other objects
      if( no collisions( virtualObject ) ) {
         object.incrementX();
      }
   }
   ...
   ...
   ...
}


enum Direction { LEFT, RIGHT, UP, DOWN }
Sign up to request clarification or add additional context in comments.

2 Comments

Shouldn't it be direction == LEFT? And why just LEFT?
Thanks, I correct this, ... I didn't think it was necessary to show all the options, it's just an example.
0

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).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.