在javascript帆布坦克游戏中的碰撞检测

时间:2013-12-12 15:01:08

标签: javascript jquery html5-canvas

这是代码,我将如何继续发射子弹(大小为6x6像素)与当前地图上的块相撞?我已经查看了所有类型的碰撞代码,但我似乎无法将其应用于此特定代码,因为我正在猜测地图是如何设置的。 迫切需要一个解决方案!

// inner variables    
var canvas, context; // canvas and context objects
var imgBrick, imgSteel, imgWater, imgForest, imgTank; // images
var aMap; // map array
var oTank; // tank object
var bullets = [];

var iCellSize = 24; // cell wide
var iXCnt = 26; // amount of X cells
var iYCnt = 26; // amount of Y cells

// objects :
function Tank(x, y, w, h, image) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.i = 0;
this.image = image;
}

function Bullet(dir, bullX, bullY, bulltype) {
this.direct = dir;
this.bullX = bullX;
this.bullY = bullY;
this.bulltype = bulltype;
}

// functions
function clear() { // clear canvas function
context.clearRect(0, 0, canvas.width, canvas.height);
}
// Firing bullets and directions
function movebullets()
{
    for (var i = 0; i < bullets.length; i++) {
        if (bullets[i].direct==2)
        {
            bullets[i].bullY-=10;
}
        else if (bullets[i].direct==3)
        {
            bullets[i].bullY+=10;
        }
        else if (bullets[i].direct==0)
        {
            bullets[i].bullX+=10;
        }
        else if (bullets[i].direct==1)
        {
            bullets[i].bullX-=10;
        }

            }
 }

/*
function bulletCollision(){
var remove = false;
for(var i = 0; i < bullets.length; i++){
    for(var j = 0; j < asteroids.length; j++){
        if(bullets[i].y <= (asteroids[j].y + enemies[j].h) && bullets[i].x >=             enemies[j].x && bullets[i].x <= (enemies[j].x + enemies[j].w)){
            remove = true;
            enemies[j].dead = true;
            //score++;
            //explosions.push(new Explosion((asteroids[j].x + (asteroids[j].w / 2)),      (asteroids[j].y + (asteroids[j].h / 2 )), asteroids[j].w));
            enemies.splice(j,1);

        }
    }
*/

function drawScene() { // main drawScene function
clear(); // clear canvas

// fill background
context.fillStyle = '#111';
context.fillRect(0, 0, canvas.width, canvas.height);

// save current context
context.save();

// walk through our array
for (var y = 0; y < iYCnt; y++) { 
    for (var x = 0; x < iXCnt; x++) {
        switch (aMap[y][x]) {
            case 0: // skip
                break;
            case 1: // draw brick block
                context.drawImage(imgBrick, 0, 0, iCellSize, iCellSize, x*iCellSize,     y*iCellSize, iCellSize, iCellSize);
                break;
            case 2: // draw steel block
                context.drawImage(imgSteel, 0, 0, iCellSize, iCellSize, x*iCellSize, y*iCellSize, iCellSize, iCellSize);
                break;
            case 3: // draw forest block
                context.drawImage(imgForest, 0, 0, iCellSize, iCellSize, x*iCellSize, y*iCellSize, iCellSize, iCellSize);
                break;
            case 4: // draw water block
                context.drawImage(imgWater, 0, 0, iCellSize, iCellSize, x*iCellSize, y*iCellSize, iCellSize, iCellSize);
                break;
        }
    }
}


// restore current context
context.restore();

// draw tank + bullets
context.drawImage(oTank.image, oTank.i*oTank.w, 0, oTank.w, oTank.h, oTank.x, oTank.y,     oTank.w, oTank.h);
for (var i = 0; i < bullets.length; i++) {
context.drawImage(imgBullet, bullets[i].bullX,  bullets[i].bullY);
}
}
// -------------------------------------------------------------

// initialization
$(function(){
canvas = document.getElementById('scene');
canvas.width  = iXCnt * iCellSize;
canvas.height = iYCnt * iCellSize;
context = canvas.getContext('2d');

// main scene Map array
aMap = ([
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
  [0, 0, 1, 1, 2, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 1, 1, 2, 2, 2, 2, 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 4, 4, 4, 4, 1, 1, 3, 3, 3, 3, 3, 3, 4, 4, 1, 1, 0, 0, 2, 2, 0, 0],
  [0, 0, 0, 0, 4, 4, 4, 4, 1, 1, 3, 3, 3, 3, 3, 3, 4, 4, 1, 1, 0, 0, 2, 2, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 4, 4, 1, 1, 1, 1, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 4, 4, 1, 1, 1, 1, 0, 0, 0, 0],
  [0, 0, 2, 2, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 2, 2, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [3, 3, 3, 3, 1, 1, 0, 0, 4, 4, 4, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],
  [3, 3, 3, 3, 1, 1, 0, 0, 4, 4, 4, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0],
  [3, 3, 3, 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 3, 3],
  [3, 3, 3, 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 3, 3],
  [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [2, 2, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 2, 2, 0, 0, 3, 3, 4, 4, 0, 0, 1, 1, 0, 0],
  [2, 2, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 2, 2, 0, 0, 3, 3, 4, 4, 0, 0, 1, 1, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 2, 2, 0, 0, 3, 3, 4, 4, 0, 0, 2, 3, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 2, 2, 0, 0, 3, 3, 4, 4, 0, 0, 2, 3, 0, 0],
  [0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0],
  [0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0],
  [0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0]
  ]);

// load images
imgBrick = new Image();
imgBrick.src = 'images/brick.png';
imgSteel = new Image();
imgSteel.src = 'images/steel.png';
imgWater = new Image();
imgWater.src = 'images/water.png';
imgForest = new Image();
imgForest.src = 'images/forest.png';
imgBullet = new Image();
imgBullet.src = 'images/bullet.png';

imgTank = new Image();
imgTank.src = 'images/tank.png';
oTank = new Tank(iCellSize*9, iCellSize*24, 48, 48, imgTank);




document.addEventListener('mousedown', function (event) {
    bullets.push(new Bullet(oTank.i, oTank.x+24, oTank.y+24, 1));
    (function(){
        var sound = new Audio('bullet_shot.ogg');
        sound.volume = 0.9;
        sound.addEventListener('ended', function() { // loop the sound


        }, false);
        sound.play();
    })();
});


$(window).keydown(function(event){ // keyboard alerts
    switch (event.keyCode) {
        case 87: // W key
            oTank.i = 2;

            // checking collisions
            var iCurCelX = (2 * oTank.x) / 48;
            var iCurCelY = (2 * oTank.y) / 48;
            if (iCurCelY) {
                var iTest1 = aMap[iCurCelY-1][iCurCelX];
                var iTest2 = aMap[iCurCelY-1][iCurCelX+1];

                if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
                    oTank.y-=24;
                    if (oTank.y < 0) {
                        oTank.y = 0;
                    }
                }
            }
            break;
        case 83: // S key
            oTank.i = 3;

            // checking collisions
            var iCurCelX = (2 * oTank.x) / 48;
            var iCurCelY = (2 * oTank.y) / 48;
            if (iCurCelY+2 < iYCnt) {
                var iTest1 = aMap[iCurCelY+2][iCurCelX];
                var iTest2 = aMap[iCurCelY+2][iCurCelX+1];

                if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
                    oTank.y+=24;
                    if (oTank.y > 576) { //iCellSize * (iYCnt-2)
                        oTank.y = 576;
                    }
                }
            }
            break;
        case 65: // A key
            oTank.i = 1;

            // checking collisions
            var iCurCelX = (2 * oTank.x) / 48;
            var iCurCelY = (2 * oTank.y) / 48;
            var iTest1 = aMap[iCurCelY][iCurCelX-1];
            var iTest2 = aMap[iCurCelY+1][iCurCelX-1];

            if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
                oTank.x-=24;
                if (oTank.x < 0) {
                    oTank.x = 0;
                }
            }
            break;
        case 68: // D key 
            oTank.i = 0;

            // checking collisions
            var iCurCelX = (2 * oTank.x) / 48;
            var iCurCelY = (2 * oTank.y) / 48;
            var iTest1 = aMap[iCurCelY][iCurCelX+2];
            var iTest2 = aMap[iCurCelY+1][iCurCelX+2];

            if ((iTest1 == 0 || iTest1 == 3) && (iTest2 == 0 || iTest2 == 3)) {
                oTank.x+=24;
                if (oTank.x > 576) { //iCellSize * (iXCnt-2)
                    oTank.x = 576;
                }
            }
            break;
    }
});

setInterval(drawScene, 40); // loop drawScene
setInterval(movebullets, 40);
});

1 个答案:

答案 0 :(得分:2)

你需要在for

中设置这样的子弹大小
for (var i = 0; i < bullets.length; i++) {
    //6px width and height
    context.drawImage(imgBullet, bullets[i].bullX,  bullets[i].bullY,6,6);    
}    

并且在movebullets()中你可以像这样调用bulletCollision

function movebullets()
{
    for (var i = 0; i < bullets.length; i++) {
        if (bullets[i].direct==2)
        {
            bullets[i].bullY-=10;
        }
        else if (bullets[i].direct==3)
        {
            bullets[i].bullY+=10;
        }
        else if (bullets[i].direct==0)
        {
            bullets[i].bullX+=10;
        }
        else if (bullets[i].direct==1)
        {
            bullets[i].bullX-=10;
        }
        bulletCollision(i);
    }
}
function bulletCollision(i){    
    //if the aMap value in the bullet position is not 0 
    if(aMap[parseInt(bullets[i].bullY/iCellSize)][parseInt(bullets[i].bullX/iCellSize)]!=0){
        alert("Collision");//do something
        bullets.splice(i, 1);//remove the current bullet 
    }
}