基本画布游戏的碰撞检测问题

时间:2015-03-20 07:05:41

标签: javascript html5 canvas collision-detection

所以我收集了5个英雄,边缘检测和碰撞检测后,我用win屏幕创建了一个游戏版本。但是我的碰撞检测有点麻烦。我的怪物出现在一个街区,并没有重置。以下代码,任何人都有任何建议:

// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 512;
canvas.height = 480;
document.body.appendChild(canvas);

// Background image
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function () {
    bgReady = true;
};
bgImage.src = "images/background.png";

// Win Screen
var wsReady = false;
var wsImage = new Image();
wsImage.onload = function () {
    bgReady = true;
};
wsImage.src = "images/WinScreen.png";

// Hero image
var heroReady = false;
var heroImage = new Image();
heroImage.onload = function () {
    heroReady = true;
};
heroImage.src = "images/hero.png";

// Monster image
var monsterReady = false;
var monsterImage = new Image();
monsterImage.onload = function () {
    monsterReady = true;
};
monsterImage.src = "images/monster.png";

// Game objects
var hero = {
    speed: 256 // movement in pixels per second
};
var monster = {};
var monstersCaught = 0;

var block1 = {x:173,y:288,w:32,h:32};
var block2 = {x:300,y:288,w:162,h:32};
var block3 = {x:365,y:159,w:32,h:32};
var ground = {x:0,y:416,w:512,h:66};

var blocks=[block1,block2,block3,ground];

// Handle keyboard controls
var keysDown = {};

addEventListener("keydown", function (e) {
    keysDown[e.keyCode] = true;
}, false);

addEventListener("keyup", function (e) {
    delete keysDown[e.keyCode];
}, false);

// Reset the game when the player catches a monster
var reset = function () {
    hero.x = canvas.width / 2;
    hero.y = canvas.height / 2;
    hero.w = 32;
    hero.h = 32;

    // Throw the monster somewhere on the screen randomly
    monster.x = 32 + (Math.random() * (canvas.width - 64));
    monster.y = 32 + (Math.random() * (canvas.height - ground.h - 64));

        for (i=0;i < blocks.length ;i++ )
        {
            if (isTouching(monster,blocks[i]))
            {
                reset();
            }
        }
};


// Update game objects
var update = function (modifier) {
    if (38 in keysDown) { // Player holding up
        hero.y -= hero.speed * modifier;

        for (i=0;i < blocks.length ;i++ )
        {
            if (isTouching(hero,blocks[i]))
            {
                hero.y = blocks[i].y + blocks[i].h +1
            }
        }

    }
    if (40 in keysDown) { // Player holding down
        hero.y += hero.speed * modifier;

        for (i=0;i < blocks.length ;i++ )
        {
            if (isTouching(hero,blocks[i]))
            {
                hero.y = blocks[i].y - hero.h -1
            }
        }

    }
    if (37 in keysDown) { // Player holding left
        hero.x -= hero.speed * modifier;

        for (i=0;i < blocks.length ;i++ )
        {
            if (isTouching(hero,blocks[i]))
            {
                hero.x = blocks[i].x + blocks[i].w +1
            }
        }

    }
    if (39 in keysDown) { // Player holding right
        hero.x += hero.speed * modifier;

        for (i=0;i < blocks.length ;i++ )
        {
            if (isTouching(hero,blocks[i]))
            {
                hero.x = blocks[i].x - hero.w -1
            }
        }   

    }

    // Are they touching?
    if (
        hero.x <= (monster.x + 32)
        && monster.x <= (hero.x + 32)
        && hero.y <= (monster.y + 32)
        && monster.y <= (hero.y + 32)
    ) {
        ++monstersCaught;
        reset();
    }

    if (hero.x >= canvas.width - hero.w -1){
        hero.x = canvas.width - hero.w -1;
    }
    if (hero.x <= 1){
        hero.x = 1;
    }
    if (hero.y >= canvas.height - hero.h -1){
        hero.y = canvas.height - hero.h -1;
    }
    if (hero.y <= 1){
        hero.y = 1;
    }

};

// Draw everything
var render = function () {


    if (bgReady) {
        ctx.drawImage(bgImage, 0, 0);
    } 

    if (heroReady) {
        ctx.drawImage(heroImage, hero.x, hero.y);
    }

    if (monsterReady) {
        ctx.drawImage(monsterImage, monster.x, monster.y);
    }

    // Score
    ctx.fillStyle = "rgb(250, 250, 250)";
    ctx.font = "24px Helvetica";
    ctx.textAlign = "left";
    ctx.textBaseline = "top";
    ctx.fillText("    ALIENS CAUGHT: " + monstersCaught, 32, 32);

    if (monstersCaught > 4) {

    ctx.drawImage(wsImage, 0, 0);
    ctx.fillText("    ALIENS CAUGHT: " + monstersCaught, 32, 32);
    }

};

// The main game loop
var main = function () {
    var now = Date.now();
    var delta = now - then;

    update(delta / 1000);
    render();

    then = now;

    // Request to do this again ASAP
    requestAnimationFrame(main);


};

function  isTouching(a,b) {
            if( 
                a.x <= (b.x + b.w)
            && b.x <= (a.x + a.w)
            && a.y <= (b.y + b.h)
            && b.y <= (a.y + a.h) )
                {
                return true;
            }
            else {
                return false

            }
}

// Cross-browser support for requestAnimationFrame
var w = window;
requestAnimationFrame = w.requestAnimationFrame || w.webkitRequestAnimationFrame || w.msRequestAnimationFrame || w.mozRequestAnimationFrame;

// Let's play this game!
var then = Date.now();
reset();
main();

1 个答案:

答案 0 :(得分:0)

您的reset函数是递归的,不必要的。每次它进行递归时,它最终都会最终退回到reset()的原始呼叫并继续您离开的for循环。结果如何最终还不明显。

请尝试使用简单的do / while循环替换递归:

var touching;
do {
    // Throw the monster somewhere on the screen randomly
    monster.x = 32 + (Math.random() * (canvas.width - 64));
    monster.y = 32 + (Math.random() * (canvas.height - ground.h - 64));

    touching = false;
    for (i=0;i < blocks.length ;i++ )
    {
        if (isTouching(monster,blocks[i]))
        {
            touching = true;
            break;  // no need for any more tests
        }
    }
} while (touching);