1
\$\begingroup\$

Please point me to the duplicate if this has been asked before. I couldn't find it.

Basically, I am creating a 2d top-down game where the player is represented by a circle, and the tiles are represented by 16x16 squares. I have gotten collision detection working, such that the player cannot collide with tiles, by using the following algorithm:

let curPosition = player.position;
let newPosition = player.position + player.velocity;

if (canTouchPosition(newPosition.x, curPosition.y)) { 
  player.position.x = newPos.x;
}

if (canTouchPosition(curPosition.x, newPosition.y)) { 
  player.position.y = newPos.y;
}

if (canTouchPosition(newPosition.x, newPosition.y)) { 
  player.position.x = newPos.x;
  player.position.y = newPos.y;
}

This works, except there's a problem. If the player is on the edge of a tile and moving to the right, I want them to slide past it, instead of getting stuck. Like so:

enter image description here

See how currently the circle is stuck on the corner when trying to move right? Instead I want it to slide along the corner until it is able to move freely, and then continue moving to the right. I can't quite figure this out. I figure a circle would make this easier, but if a square is instead easier to perform this operation on, maybe I'll use one of those instead? I mostly just want to get it working.

\$\endgroup\$
6

1 Answer 1

0
\$\begingroup\$

An easy way would be to think of the circle as a rectangle still, so just have a circle displayed, but still be rectangle colliding. And then instead of preventing movement, move first, holding the updated x,y somewhere that is not the final x,y, and then apply that movement if there is not collision, if there is adjust, which you're doing. But let the collision method return the point of collision, for example:

        this._pos.x += this._veloc.x*this._deltaTime;
        this._pos.y += this._veloc.y*this._deltaTime;
        
        var pgy, pgx;
        pgx = this.isLeftPushingOnMap(this._lastPos,this._pos,this._veloc,this._map,this._tw,this._th);
        if(pgx > 0) {
            this._pLeft = 1;//pushing left
            this._pos.x = pgx +1;
            this._veloc.x = 0;
        } else {
            
            this._pLeft = 0;
        }

        ...
        this.setX( this._pos.x );
        this.setY( this._pos.y );
\$\endgroup\$
2
  • 1
    \$\begingroup\$ This is a nice solution in general, especially for someone learning how collisions work, but I'm not sure if it's the answer OP was looking for. They mentioned the Circle getting stuck in a corner, if the collision shape of the Circle was a Square instead, it would still get stuck in the corner unable to move to the right. \$\endgroup\$ Commented Mar 23, 2023 at 11:56
  • \$\begingroup\$ @TomTsagk The collision is resolved by the square being placed at the point just outside of collision, so it would skip up over that edge point if the velocity is fast enough. \$\endgroup\$
    – mrall
    Commented Mar 24, 2023 at 0:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .