我目前正在玩crafty js,并创建了具有实体对象的2D自上而下的世界。
当任何固体物体发生碰撞事件时,我希望我的播放器不再能够朝着所述物体的方向移动(因为有一个固体物体挡住它的路径)。
我在网上找到了一些tutorials来涵盖这个主题,但是他们调用的方法和功能都被删除了。
.onHit("solid", function(from) {
console.log("ouch");
}
当我的球员击中稳定时,我可以注册碰撞,但我不知道如何阻止这一动作。
我知道我可以为每次碰撞设置特定的解决方案(例如,顶部边框可以更新y以移除特定的顶部碰撞),但是我想要一个通用的方法,因此与我的角色中的任何可靠结果相撞都不能移动。
当我尝试拨打from.x
时,我收到该元素为undefined
,而其他元素(如from.length
)确实有效,这对我来说没有意义。
或者提供一些兼容最新狡猾的演示代码?
答案 0 :(得分:2)
当我尝试拨打
from.x
时,我收到该元素为undefined
,而其他元素(如from.length
)确实有效,这对我来说没有意义。
onHit回调为您提供与hit函数相同的碰撞数据 - 碰撞结果数组。这就是您能够访问length
属性的原因。
来自hit apidocs:
返回的碰撞数据将是一个对象数组,其中包含使用的碰撞类型,对象发生碰撞,如果使用的类型是SAT(多边形用作命中框),则重叠量。
我知道我可以为每次碰撞设置特定的解决方案(例如,顶部边框可以更新y以移除特定的顶部碰撞),但是我想要一个通用的方法,因此与我的角色中的任何可靠结果相撞都不能移动。
水平和/或垂直碰撞是我知道的两个axis-aligned bounding boxes之间碰撞的唯一两种情况。 AABB在Crafty的碰撞检测中用作默认值(可通过.mbr()访问)。
您提出的解决方案实际上是解决此类AABB冲突的常用方法。
使用箭头键或WASD移动绿色播放器。注意移动受黑墙的限制。
Crafty.init();
Crafty.e("2D, DOM, Color, Fourway, Collision, player")
.attr({x: 32, y: 32, w: 32, h: 32})
.color('green')
.fourway()
.bind('Moved', function(evt){
if (this.hit('solid'))
this[evt.axis] = evt.oldValue;
});
Crafty.e("2D, DOM, Color, solid, top")
.attr({x: 0, y: 0, w: 128, h: 1})
.color('black');
Crafty.e("2D, DOM, Color, solid, bottom")
.attr({x: 0, y: 127, w: 128, h: 1})
.color('black');
Crafty.e("2D, DOM, Color, solid, left")
.attr({x: 0, y: 0, w: 1, h: 128})
.color('black');
Crafty.e("2D, DOM, Color, solid, right")
.attr({x: 127, y: 0, w: 1, h: 128})
.color('black');
<script src="https://github.com/craftyjs/Crafty/releases/download/0.7.1/crafty-min.js"></script>
使用seperate axis theorem在Crafty中有一个更复杂和精确的碰撞检测变体,它可以在任意两个凸多边形之间起作用。可以通过.collision()指定自定义多边形命中框 类似的解决方案用于解决SAT冲突 - 使用碰撞结果中的信息将碰撞对象移回。
使用箭头键或WASD移动绿色播放器。注意移动是如何沿红线限制的,红线表示凸多边形命中框。
Crafty.init();
Crafty.e("2D, Fourway, Collision, DOM, Color, WiredHitBox, player")
.attr({x: 32, y: 32, w: 32, h: 32})
.collision([0, 16, 16, 0, 32, 16, 16, 32])
.color('green')
.fourway()
.bind('Moved', function(evt) {
var hitDatas, hitData;
if ((hitDatas = this.hit('solid'))) {
// resolving collision for just one collider here and assuming SAT collision
hitData = hitDatas[0];
this.x -= hitData.overlap * hitData.normal.x;
this.y -= hitData.overlap * hitData.normal.y;
}
});
Crafty.e("2D, Collision, DOM, Color, WiredHitBox, solid")
.attr({x: 64, y: 64, w: 64, h: 64})
.collision([0, 32, 32, 0, 64, 32, 32, 64])
.color('black');
<script src="https://github.com/craftyjs/Crafty/releases/download/0.7.1/crafty-min.js"></script>
请务必阅读apidocs,了解有关所用组件和事件的其他信息。