Javascript画布冲突检测 [英] Javascript canvas collision detection

查看:152
本文介绍了Javascript画布冲突检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用canvas创建一个使用canvas的游戏,这需要碰撞检测,在这种情况下,如果玩家sprite击中一个框,则不允许玩家通过该框。



我有一个名为 blockList 的全局数组,其中包含所有正在绘制到画布上的框。它看起来像这样:

  var blockList = [[50,400,100,100]]; 

它们正在绘制到画布上:


$ bList [0] [0] [1],blockList [0] [2],blockList [0] [3] );

我也有一个player对象,它有一个update方法和一个draw方法。更新根据键盘输入等设置播放器的位置,并且绘制由主游戏循环使用以将播放器绘制到画布。播放器是这样绘制的:

  this.draw = function(timestamp){
if(this.state ==idle){
c.drawImage(this.idleSprite,this.idleSprite.frameWidth * this.idleSprite.frameCount,0,this.idleSprite.frameWidth,this.idleSprite.frameHeight,this.xpos,this .ypos,this.idleSprite.frameWidth,this.idleSprite.frameHeight);
if(timestamp - this.lastDraw> this.idleSprite.updateInterval){
this.lastDraw = timestamp;
if(this.idleSprite.frameCount< this.idleSprite.frames - 1){this.idleSprite.frameCount ++; } else {this.idleSprite.frameCount = 0; }
}
} else if(this.state ==running){
var height = 0;
if(this.facing ==left){height = 37; }
c.drawImage(this.runningSprite,this.runningSprite.frameWidth * this.runningSprite.frameCount,height,this.runningSprite.frameWidth,this.runningSprite.frameHeight,this.xpos,this.ypos,this.runningSprite .frameWidth,this.runningSprite.frameHeight);
if(timestamp - this.lastDraw> this.runningSprite.updateInterval){
this.lastDraw = timestamp;
if(this.runningSprite.frameCount< this.runningSprite.frames - 1){this.runningSprite.frameCount ++; } else {this.runningSprite.frameCount = 0; }
}
}
}

某些属性为 player.xpos player.ypos player.width player.height 。块存在相同的属性。所以我有我需要的一切,以实现碰撞检测,我只是不知道如何做到。我试过做的事情:

  if(player.x> blockList [0] [0]&& player.y> blockList [0] [1])$ ​​b $ b  

但它远不完美或可播放。



有人知道一个简单的方法或函数能够基于两个对象是否相互冲突返回true或false?

解决方案

我使用以下函数来检测两个矩形之间的碰撞:

  rect_collision = function(x1,y1,size1,x2,y2,size2){
var bottom1,bottom2,left1,left2,right1,right2,top1,top2;
left1 = x1 - size1;
right1 = x1 + size1;
top1 = y1 - size1;
bottom1 = y1 + size1;
left2 = x2 - size2;
right2 = x2 + size2;
top2 = y2 - size2;
bottom2 = y2 + size2;
return!(left1> right2 || left2> right1 || top1> bottom2 || top2> bottom1);
};

这决定了以(x1,y1) code>和(x2,y2),边长 2 * size1 > 2 * size2 。应该很容易改变 left1 right1 等的定义来处理一般矩形而不是



具体来说, left1 是第一个正方形的左侧, right1 右侧等。请注意,在我的坐标系统中,y轴反转( top1 ; bottom1 )。


I'm building a game in Javascript using canvas which requires collision detection, in this case if the player sprite hits a box, the player must not be allowed through the box.

I have a global array called blockList that holds all the boxes being drawn to the canvas. It looks like this:

var blockList = [[50, 400, 100, 100]];

And they're being drawn to the canvas like this:

c.fillRect(blockList[0][0], blockList[0][1], blockList[0][2], blockList[0][3]);

I also have a player object, which has an update method and a draw method. Update sets the position of the player based on keyboard input etc, and draw is used by the main game loop to draw the player to the canvas. The player is being drawn like this:

this.draw = function(timestamp) {
        if(this.state == "idle") {
            c.drawImage(this.idleSprite, this.idleSprite.frameWidth * this.idleSprite.frameCount, 0, this.idleSprite.frameWidth, this.idleSprite.frameHeight, this.xpos, this.ypos, this.idleSprite.frameWidth, this.idleSprite.frameHeight);
            if(timestamp - this.lastDraw > this.idleSprite.updateInterval) {
                this.lastDraw = timestamp;
                if(this.idleSprite.frameCount < this.idleSprite.frames - 1) { this.idleSprite.frameCount++; } else { this.idleSprite.frameCount = 0; }
            }
        } else if(this.state == "running") {
            var height = 0;
            if(this.facing == "left") { height = 37; }
            c.drawImage(this.runningSprite, this.runningSprite.frameWidth * this.runningSprite.frameCount, height, this.runningSprite.frameWidth, this.runningSprite.frameHeight, this.xpos, this.ypos, this.runningSprite.frameWidth, this.runningSprite.frameHeight);
            if(timestamp - this.lastDraw > this.runningSprite.updateInterval) {
                this.lastDraw = timestamp;
                if(this.runningSprite.frameCount < this.runningSprite.frames - 1) { this.runningSprite.frameCount++; } else { this.runningSprite.frameCount = 0; }
            }
        }
    }

Now, the player has certain properties being player.xpos, player.ypos, player.width, player.height. The same properties exist for the blocks. So I have everything I need to impliment collision detection, I just have no idea how to do it. I've tried doing things like:

if(player.x > blockList[0][0] && player.y > blockList[0][1])

but it's far from perfect or playable.

Does anyone know of a simple method or function to be able to return true or false based on if two objects are colliding?

解决方案

I use the following function for collision detection between two rectangles:

rect_collision = function(x1, y1, size1, x2, y2, size2) {
  var bottom1, bottom2, left1, left2, right1, right2, top1, top2;
  left1 = x1 - size1;
  right1 = x1 + size1;
  top1 = y1 - size1;
  bottom1 = y1 + size1;
  left2 = x2 - size2;
  right2 = x2 + size2;
  top2 = y2 - size2;
  bottom2 = y2 + size2;
  return !(left1 > right2 || left2 > right1 || top1 > bottom2 || top2 > bottom1);
};

This determines whether two squares, centered at (x1, y1) and (x2, y2), with side lengths 2*size1 and 2*size2, respectively, are overlapping. It should be easy enough to alter the definitions of left1, right1, etc. to deal with general rectangles rather than just squares and to use a different data format.

Specifically, left1 is the left side of the the first square, right1 the right side, etc. Note that, in my coordinate system, the y-axis is inverted (top1 < bottom1).

这篇关于Javascript画布冲突检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆