如何让两个画布动画相互碰撞?

时间:2014-11-24 12:33:56

标签: javascript animation canvas collision

我试图制作一个简单的游戏,我可以在其他bals射击球,然后他们消失。我设法使动画工作,我可以拍摄球,但我不知道如何使它们发生碰撞。

我试图在第72-74行做些事情,但我得到了错误"无法读取属性' y'未定义"。

要查看游戏演示,请点击链接DEMO

var canvas = document.getElementById("canvas");
    ctx = canvas.getContext("2d");
    var tileldig = Math.floor((Math.random() * 300) + 1);

    var kuler = [
        {r: 10, x: canvas.width/2, y: canvas.height-100, f: "red", dy:0},
        //{r: 50, x: tileldig, y: 50, vx:0 , vy: 3, f: "green"},
    ]



    var fiender = [
        {r: 10, x: tileldig, y: 50, vx:0 , vy: 1, },
    ]
    var skudder = [
        {r: 10, x:0+kuler.x, y: 0+kuler.y, f: "black"},
    ]




    function spill() {

        ctx.clearRect(0, 0, canvas.width, canvas.height);

        for (var i = 0; i < kuler.length; i++) {
            kuler[i].x += 0;
            kuler[i].y += kuler[i].dy;


            ctx.fillStyle = kuler[i].f;
            ctx.beginPath();
            ctx.arc(kuler[i].x, kuler[i].y, kuler[i].r, 2*Math.PI, 0);
            ctx.closePath();
            ctx.fill();


            if (kuler[0].x >= canvas.width-kuler[0].r) {
                kuler[0].x = canvas.width-kuler[0].r
            };
            if (kuler[0].x <= 0+kuler[0].r) {
                kuler[0].x = 0+kuler[0].r
            };
            if (kuler[0].y >= canvas.height-kuler[0].r) {
                kuler[0].y = canvas.height-kuler[0].r
            };
            if (kuler[0].y <= 0+kuler[0].r) {
                kuler[0].y = 0+kuler[0].r
            };


        };


        document.onkeydown = function tast (e) {            
          switch (e.keyCode) {
            case 37:
              kuler[0].x -= 10;
              break;
            case 39:
              kuler[0].x += 10;
              break;
            case 38:
              kuler[0].y -= 10;
              break;
            case 40:
              kuler[0].y += 10;
              break;
             case 32:
              newskudd()
              console.log("hit space")
              if(fiender[i].y >= skudder[1].y){
                alert();
              };
              break;
          }
        };

        for (var i = 0; i < fiender.length; i++) {
            ctx.fillStyle = "blue";
            ctx.beginPath();
            ctx.arc(fiender[i].x, fiender[i].y, fiender[i].r, 2*Math.PI, 0);
            ctx.closePath();
            ctx.fill();

            fiender[i].y += fiender[i].vy;

            if (fiender[i].y >= canvas.height) {
                fiender.splice(i,1);
                console.log("ute");
            };  
        }



        requestAnimationFrame(spill);
    }

    function newskudd () {
        var nyttskudd = 
        {x:kuler[0].x, y:kuler[0].y, r:5, dy:-5, f:"black"};
        kuler.push(nyttskudd);
    };

    setInterval(function(){
        fiender.push({r: 10, x: Math.floor((Math.random() * 300) + 1), y: 0, vx:0 , vy: 1, f: "green"});
    }, 1000);

    spill();


    /*if (circles.x >= canvas.height- circles.r){
        circles.splice(i,1);
    }*/

2 个答案:

答案 0 :(得分:1)

这是问题:

if(fiender[i].y >= skudder[1].y){

你在这里的循环之外,所以fiender[i]毫无意义。最快的解决方法是使用for循环遍历所有fiender项目,就像你之后做5-6行一样。像这样:

for (var i = 0; i < fiender.length; i++) {
    if(fiender[i].y >= skudder[1].y){
        alert();
    };
}

此外,skudder[1]似乎不存在,也许它应该是skudder[0]

您需要提供更多信息才能获得更准确的答案。

答案 1 :(得分:0)

更新: CODE sample as I promised

抱歉,我不得不重写你的很多代码,以便让我的事情变得更加干净。我试图保留你的姓名。

第72-74行不是你可以计算碰撞的地方;)

我会尝试给你一些提示。

删除此部分,您不需要它。

console.log("hit space")
if(fiender[i].y >= skudder[1].y){
  alert();
};

每次拍摄时,都会在&#34; kulers数组中添加新的子弹&#34;,这已在您的函数newskudd()中完成。

我猜你不想在太空被击中时杀死你的敌人,但当一个球遇到另一个时。

所以在spill()中,所有&#34;子弹&#34;并试图找出,如果有任何敌人被击中。 ==&GT;每次重绘你的程序都会测试,如果有什么东西被击中

JS我做了更新

// constants

var TILELDIG = Math.floor((Math.random() * 300) + 1);
var NEW_ENEMY_INTERVAL = 1000;

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");


// basic graphic constructs (prototypes)

var EntityBall = function (position, color, delta, speed, size) {
    this.size = size || 10;
    this.position = position || [0, 0];
    this.delta = delta || [0, 0];
    this.speed = speed || [0, 0];
    this.color = color || "black";
};


var Kuler = function (position) {
    EntityBall.call(this, position, "black", [0, -10], [0, 0], 5);
};


var Fiender = function (position) {
    EntityBall.call(this, position, "blue", [0, 1]);
};


var Skudder = function (position) {
    EntityBall.call(this, position, "red", [0, 0], [5, 5]);
}


// Program constructor

var Program = function (ctx, canvas) {
    this.ctx = ctx;
    this.canvas = canvas;
    this.init();
};

// Program inicialization
Program.prototype.init = function () {
    // these arrays store living things
    this.kulers = [];
    this.fienders = [];
    this.skudders = [];
    this.hordeUpdate = null;

    var player1 = new Skudder([canvas.width*0.5, canvas.height*0.75 ]);
    this.skudders.push(player1);
    // here you bind keys for moving main ball (player1)
    document.addEventListener("keydown", this.player1Actions.bind(this, player1));
};

// handle player moves
Program.prototype.player1Actions = function (player1, e) {
    switch (e.keyCode) {
        case 37:
            player1.position[0] -= player1.speed[0];
            break;
        case 39:
            player1.position[0] += player1.speed[0];
            break;
        case 38:
            player1.position[1] -= player1.speed[1];
            break;
        case 40:
            player1.position[1] += player1.speed[1];
            break;
        case 32:
            this.attack(player1);
            console.log("hit space");
            break;
    }
    if(player1.position[0] < 0) {
        player1.position[0] = 0;
    }
    if(player1.position[0] > canvas.width) {
        player1.position[0] = canvas.width;
    }
    if(player1.position[1] < 0) {
        player1.position[1] = 0;
    }
    if(player1.position[1] > canvas.height) {
        player1.position[1] = canvas.height;
    }
};

// only spawns bullet, but doesnt calculate collision
Program.prototype.attack = function (player) {
    var kulerPosition = [player.position[0], player.position[1]];
    var kuler = new Kuler(kulerPosition);
    this.kulers.push(kuler);
};

// main Program thread (refreshed 60 times per second)
Program.prototype.refresh = function () {
    var canvas = this.canvas;
    this.ctx.clearRect(0, 0, canvas.width, canvas.height);

    // update all positions (delta move of each entity)
    var list = [this.kulers, this.fienders, this.skudders];
    for (var i = 0; i < list.length; i++) {
        for (var j = 0; j < list[i].length; j++) {
            // find new position
            list[i][j].position[0] += list[i][j].delta[0];
            list[i][j].position[1] += list[i][j].delta[1];

            // delete entity if it is out of canvas (else all browser memory will be eaten by blue balls)
            if (list[i][j].position[1] > canvas.height || list[i][j].position[1] < 0 || list[i][j].position[0] > canvas.width || list[i][j].position[0] < 0) {
                list[i].splice(j, 1); // this delete it
            };
        }
    }

    // calculate bullets collision
    for (var i = 0; i < this.kulers.length; i++) { // go thrue all bullets
        for (var j = 0; j < this.fienders.length; j++) { // for each bullet go thrue all enemies
            // find if this enemy is being hit
            // (5 + 2.5), 5 is r of blue ball, 2.5 is r of black ball, you dont want to find perfect hit, scratches counts too
            if ((this.kulers[i].position[0] >= this.fienders[j].position[0] - (5 + 2.5) && this.kulers[i].position[0] <= this.fienders[j].position[0] + (5 + 2.5)) && this.kulers[i].position[1] <= this.fienders[j].position[1]) {
                this.kulers.splice(i, 1); // delete bullet that hits
                this.fienders.splice(j, 1); // delete dead enemy
                break;
            }
        }
    }

    // after all removes, draw all living entities
    for (var i = 0; i < list.length; i++) {
        for (var j = 0; j < list[i].length; j++) {
            this.ctx.fillStyle = list[i][j].color;
            ctx.beginPath();
            ctx.arc(list[i][j].position[0], list[i][j].position[1], list[i][j].size, 2 * Math.PI, 0);
            ctx.closePath();
            ctx.fill();
        }
    }

    // repeat
    requestAnimationFrame(this.refresh.bind(this));
};

// this will start blue enemies coming
Program.prototype.hordeComing = function () {
    this.hordeUpdate = setInterval(this.addEnemy.bind(this), NEW_ENEMY_INTERVAL);
};

// this spawn enemy
Program.prototype.addEnemy = function () {
    var position = [Math.floor(Math.random() * canvas.width / 2) * 2, 0];
    var fiender = new Fiender(position);
    this.fienders.push(fiender);
};


// run program with params

var program1 = new Program(ctx, canvas);
program1.refresh();
program1.hordeComing();