0
\$\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\$

You must log in to answer this question.

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