- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在通过 http://www.html5canvastutorials.com 提供的教程学习 kineticjs
,事情很好,也很容易理解,但是,我在理解 getIntersection
函数时遇到了问题,我想在 dragging
检测 collision/重叠
对象。
据我所知,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>
在 dragmove
事件中,你们可以看到我得到了拖动框的四个角位置{现在评论},这样我就能够检测到重叠/碰撞,但它有 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;
};
然后你可以做一个大循环,遍历一个层中的所有对象来检查碰撞,像这样:
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');
}
}
}
我提供的 checkCollide 函数只检查每个形状左上角的碰撞,所以你必须修改函数来检查所有的角,重写的时间不长,甚至在 stackoverflow 上也有很多教程可以处理带有“边界矩形碰撞检测”
这似乎是一个非常繁重的函数,但令人惊讶的是它仍然比 .getIntersections() 更快。此外,您应该加入额外的 if 语句,这样函数就不会一直运行所有检查。
我自己创建了一个游戏并使用 .intersects() 并且速度很慢。我切换到这种“更简单”的碰撞检测,现在我的游戏运行速度约为 60FPS。 http://cs.neiu.edu/~tsam/physics/index.phtml (测试/测试)如果你想检查一下。您可以查看页面源代码以了解我如何构建更高效的碰撞检测(例如在 checkIntersectsGoal() 函数中)。
关于HTML5/kineticJS getIntersection函数实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14875119/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!