Jun*_*aid 4 html5 collision-detection kineticjs
我正在kineticjs通过http://www.html5canvastutorials.com上提供的教程学习,事情很好且易于理解但是,我在理解getIntersection我想要在dragging检测collision / overlapping对象时在不同对象中使用的功能时遇到问题.
据我所知,该getIntersection函数需要一个位置并检查它是否与任何其他对象相交.
虽然我得到了它们但有一些问题.
我无法做到这一点..
下面是我现在尝试过的代码..
<script>
var stage = new Kinetic.Stage({
container: 'container',
width: 1000,
height: 500,
opacity: 0.5
});
var layer = new Kinetic.Layer();
var previous_position;
var new_position;
var collision = false;
var colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'];
var yellowBox = null;
for(var n = 0; n < 6; n++) {
// anonymous function to induce scope
(function() {
var i = n;
if(n < 3){
y = 50;
x = i * 100 + i * 10;
}else{
y = 150;
x = (i - 3) * 100 + (i - 3) * 10 ;
if(n == 3){
x = 0;
}
}
var box = new Kinetic.Rect({
x: x,
y: y,
width: 100,
height: 50,
fill: colors[i],
stroke: 'black',
strokeWidth: 4,
draggable: true,
name: colors[i]
});
box.on('dragstart', function() {
previous_position = {
x: this.attrs.x,
y: this.attrs.y
};
});
box.on('dragend', function() {
if(collision){
//this.setPosition(previous_position);
layer.draw();
collision = false;
}else{
//this.setPosition(new_position);
layer.draw();
}
});
box.on("dragmove", function(evt) {
console.log(layer.children.length);
if(layer.children.length > 1){
console.log('dragging');
new_position = {x: this.attrs.x,
y: this.attrs.y};
// var posBL = {x: this.attrs.x,
// y: this.attrs.height + this.attrs.y};
// var posTR = {x: this.attrs.x + this.attrs.width,
// y: this.attrs.y};
var posBR = {x: this.attrs.x + this.attrs.width,
y: this.attrs.y + this.attrs.height };
var collisionTL = this.getStage().getIntersections(new_position);
// var collisionBL = this.getStage().getIntersections(posBL);
// var collisionTR = this.getStage().getIntersections(posTR);
// var collisionBR = this.getStage().getIntersections(posBR);
console.log(collisionTL);
console.log(collisionTL.shapes);
// if(collisionTL.length > 1 || collisionBL.length > 0 || collisionTR.length > 0 || collisionBR.length > 0){
if(collisionTL.length > 1){
console.log(collisionTL.shapes);
collision = true;
}else{ //if(collisionBR.length > 0){
collision = true;
}
// for(i=0; i < collision.length; i++){
// // console.log(collision[i]._id);
// }
}
});
if(colors[i] === 'yellow') {
yellowBox = box;
}
layer.add(box);
})();
}
stage.add(layer);
</script>
Run Code Online (Sandbox Code Playgroud)
在dragmove事件中,你guyz可以看到我拿到拖箱{现在评论}的四个角落位置,并与这我能够检测重叠/冲突,但它有2个问题:
1.我的测试中只有3个物体很慢
2.如果没有角点相交,它就不会发生碰撞事件{因为这个盒子可以更大,所以它可以完全覆盖另一个盒子}
如果有人能帮我完成这些东西,我会高度赞成的.
[A]任何对象拖动,如果通过任何方式重叠任何其他对象,我希望它显示碰撞.
[B]如果可能的话,尽可能getIntersection在特定的图层组上工作[C]除了kineticJS完成上述任务之外的任何其他解决方法
问候
好吧,KineticJS的开发人员正在努力改进.getIntersections()函数......或者至少他说他是.但是,在功能得到改进之前,您必须制作自己的碰撞检测功能.假设您的对象是矩形或可以分成一系列点,您应该使用以下内容:
创建一个函数,确定一个点是否在一个形状中(如果一个矩形的一角在另一个矩形内),如下所示:
function checkCollide(pointX, pointY, objectx, objecty, objectw, objecth) { // pointX, pointY belong to one rectangle, while the object variables belong to another rectangle
var oTop = objecty;
var oLeft = objectx;
var oRight = objectx+objectw;
var oBottom = objecty+objecth;
if(pointX > oLeft && pointX < oRight){
if(pointY > oTop && pointY < oBottom ){
return 1;
}
}
else
return 0;
};
Run Code Online (Sandbox Code Playgroud)
然后你可以做一个大循环,遍历层中的所有对象来检查碰撞,如下所示:
var children = layer.getChildren();
for( var i=0; i<children.length; i++){ // for each single shape
for( var j=0; j<children.length; j++){ //check each other shape
if(i != j){ //skip if shape is the same
if(checkCollide(children[i].getX(), children[i].getY(), children[j].getX(), children[j].getY(), children[j].getWidth(), children[j].getHeight()))
alert('top left corner collided');
}
}
}
Run Code Online (Sandbox Code Playgroud)
我提供的checkCollide函数只检查每个形状左上角的碰撞,所以你必须修改函数来检查所有角落,这不是一个很长的重写,甚至还有很多教程在stackoverflow上处理'边界'矩形碰撞检测'
这似乎是一个非常繁重的函数,但令人惊讶的是它仍然比.getIntersections()更快.此外,您应该引入额外的if语句,以便该函数不会一直运行所有检查.
我自己创建了一个游戏并且正在使用.intersects()并且运行速度很慢.我切换到这种"更简单"的碰撞检测,现在我的游戏运行大约60FPS.http://cs.neiu.edu/~tsam/physics/index.phtml(测试/测试)如果你想看看它.您可以查看页面源以查看我如何使碰撞检测更有效(例如在checkIntersectsGoal()函数中.