简体   繁体   中英

Collision detection in javascript

I am implementing a custom space invader like in HTML/javascript. So far everything works fine but collision detection seems to be a problem. After looking for a couple of solutions online, here is what I have so far.

My enemies are represented in an array like this:

function Logo(I){
    I = I || {};
    I.sprite = new Image();
    I.active = true;

    I.width = 25;
    I.height = 25;

    I.explode = function(){
        this.active = false;
    }

    I.draw = function(){
        context.drawImage(I.sprite,this.x,this.y);
    }

    I.setRes = function(name){
        this.sprite.src = name;
    }

    return I;
}

which is populated like this:

var logoArray = [];
    for(i=0;i<logoData.length;i++){
        logoArray.push(Logo({
            x: logoData[i].x,
            y: logoData[i].y
        }));
        logoArray[i].setRes("./graphics/logo_slices/logo_" + logoData[i].name + ".png");
        console.log(logoArray[i].sprite.src);
    }

The collision are handled like this (enemy.explode do a this.active = false):

function handleCollision(){
    playerBullets.forEach(function(bullet) {
       logoArray.forEach(function(enemy) {
          if (isCollide(bullet, enemy)) {
            enemy.explode();
            bullet.active = false;
          }
        });
    });
}

function isCollide(a, b) {
  return a.x < b.x + b.width &&
         a.x + a.width > b.x &&
         a.y < b.y + b.height &&
         a.y + a.height > b.y;
}

The problem is that it makes inactive everything that is to the left of the impact point. I understand that it is quite hard to depict my problem so happy to clarify.

The draw function filters to draw only the active elements of the array:

logoArray.forEach(function(logo_slice){
    logo_slice.draw();
});

Thanks for any help you can give!

Regarding your collision logic, i would take the opposite approach:

Take the 4 cases that define a not collide and negate them. being above, being below, being besides to left / right. not being either of these 4 makes it necessarily a collision.

Just as i guess this is the reason. The rest of your "engine" looks reasonable and should work.

collide = 

!(a.x + a.width < b.x ||
  a.x > b.x + b.width ||

  a.y + a.height < b.y||
  a.y > b.y + b.height )

Additionally you could define a radius per entity that participates in the collisions and use a intersection via the radius. Of course then you need the center of the entities for this to work.

Edit: For more details and elaborate example of different Collision Detection approaches in JS, see https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM