Search code examples
javascriptcanvastypescriptcollision-detectiongame-physics

How to do collision prevention? (Resetting position of player object)


I'm having some serious trouble with preventing my player from ocupying the same positions as my other objects on the canvas.

The following code is my player.update method, which as far as my logic goes, should prevent it, although leaving a possible gab between the player and the obstacle, but that's not my concern right now.

I've tested that the collision is detected, so what am I doing wrong?

update() {
    var oldPosition = this.position;                                                  //Save the old player position.
    this.accelerate();                                                                //Accelerate the player through playerinput.
    this.decelerate();                                                                //Modify velocity to friction and gravity
    this.position.addTo(this.velocity);                                               //Move the player according to velocity.
    for (var i = 0; i < this.cElements.length; i++) {                                 //Run through all the elements on the canvas.
        if (this.cElements[i] != this) {                                              //Exclude the player itself.
            if (this.collisionDetector.cElementsIntersect(this, this.cElements[i])) { //If there is collision
                collision = true;
            }
        }
    }
    if (collision) {
        this.position = oldPosition;                                                  //Reset the position.
    }
}

Solution

  • The problem is you are not copying the position data. You are just creating a new reference to the object position.

    In javascript Objects and Arrays are accessed via their reference.Think of it as a pointer to a memory location.

    If you have an object

    var myObject = {
          str: "aaaa",
          num: 100,
    }
    

    And then copy it

    var myObject2 = myObject;
    

    They both point to the same structure. So if I change the value in one it will show up in both.

    myObject.num = 200;
    console.log(myObject.num); // 200 is displayed
    console.log(myObject2.num); // 200 is displayed
    

    The same is true for arrays

    var myArr = [0,1,2,3,4,5];
    var myArrRef = mayArr;
    myArr[1] = 10;
    console.log(myArrRef[1]); // as they are the same array the output is 10;
    

    Only primitive types have a copy created when you assign them to another variable.

    var str = "Blah blah"
    var str1 = str;   // there are now two copies of "blah blah"
    str1 += " blah";
    console.log(str);  "Blah blah"
    console.log(str1);  "Blah blah blah"
    

    The same is true for numbers, booleans, regexp.

    So if you want to make a copy of an object you have to explicitly copy all the primitive types.

    var position = {
        x: 0,
        y: 0,
    }
    
    var oldPos = {
         x:position.x,
         y:position.y,
        // and any other relevant info
    }
    

    Do the collision test

    if(collision){
         position.x = oldPos.x;
         position.y = oldPos.y;
        // and any other relevant info
    }
    

    Hope this helps.