Search code examples
javascriptcollision-detectiongame-physics

Collision detection/player movement physics


I have an issue understanding and fixing an issue I am having. I have a collision map and if an element is a 1 it should trigger my collision detection function, which it does. I am pretty sure my problem exist with how I am controlling my characters movement but I can't figure out what to do to fix it. If I hit a wall I can still move through it even though I set player.vx to 0. So then I added player.x = cell.x - cell.w but doing that for all sides causes the character to be flung around depending on which side gets called first in my routing table.

I have also tried many many variations of adding velocity to my player to prevent the unwanted penetration.

Here's my players code

let friction = 0.9;
let gravity = 2;
let size = 32;
//player
class Player {
    constructor() {
        this.x = 256;
        this.y = 96;
        this.w = 32;
        this.h = 32;
        this.vx = 0;
        this.vy = 0;
        this.oldX = this.x;
        this.oldY = this.y;
        this.jumping = false;
    }
    draw() {
        ctx.fillStyle = 'green';
        ctx.fillRect(this.x, this.y, this.w, this.h)
    }
    update() {
      this.oldX = this.x;
      this.oldY = this.y;
      if (controller.right) {this.vx += 1}
      if (controller.left) {this.vx -= 1}
      if (controller.up && !this.jumping) {this.vy -= 10; this.player = true}
      if (controller.down) {this.vy += 1}
        this.x += this.vx;
        this.y += this.vy;
        this.vx *= friction;
        this.vy *= friction;
        this.vy += gravity;
        this.draw();
    }
}
let player = new Player();

and a Codepen to make it easier to help https://codepen.io/jfirestorm44/pen/GRrjXGE?editors=0010

thanks in advance

EDIT: If anyone finds this I left a new CodePen in the comments below with a working example completely re-written.


Solution

  • Alright I think I got it

    enter image description here

    First off, it looks like leftCollision() and rightCollision() functions have the names mixed up.

    The if conditional statements in both functions look correct to me, so I decided to rejected the new x value by assigning the oldX value to it:

    function rightCollision(obj, cell) {
        if (obj.x + obj.w >= cell.x && obj.oldX < obj.x) {
            obj.vx = 0;
            obj.x = obj.oldX;    // <-- like this
        } 
    };
    

    How I approached debugging this

    1. Focused on a single direction. I chose moving right
    2. Noticed that it's detecting the left collision only after hitting the left arrow key
    3. Printed the player and cell coordinates inside RightCollision() and noticed that the x and oldX 'seemed' correct to me
    4. Rejected the new x value by assigning the oldX value to it.