狡猾的JS碰撞运动
Crafty JS collision movement
我目前正在玩 crafty js 并创建了带有实体对象的 2D 俯视世界。
当任何固体物体发生碰撞事件时,我希望我的播放器不再能够朝所述物体的方向移动(因为有固体物体挡住了它的路径)。
我在网上找到了一些 tutorials 涵盖该主题的内容,但是它们调用的方法和函数已被删除。
.onHit("solid", function(from) {
console.log("ouch");
}
当我的播放器撞到固体时,我可以注册碰撞,但我不知道如何停止移动。
我知道我可以为每次碰撞设置特定的解决方案(例如,顶部边框可以更新 y 以离开特定的顶部碰撞),但是我想要一种通用的方法,因此不会与我的角色中的任何实体结果发生碰撞能够移动。
当我尝试调用 from.x
时,我收到的元素是 undefined
,而 from.length
等其他元素起作用,这对我来说没有意义。
或者提供一些兼容最新crafty的演示代码?
碰撞数据
When I try to call from.x
I receive that the element is undefined
, while other elements such as from.length
do work, which does not make sense to me.
onHit callback provides you with the same collision data as the hit 函数 - 碰撞结果数组。这就是您能够访问 length
属性 的原因。
来自hit apidocs:
The returned collision data will be an Array of Objects with the type of collision used, the object collided and if the type used was SAT (a polygon was used as the hitbox) then an amount of overlap.
MBR 冲突
I know that I can setup specific solutions per collision (for example, a top border can update y to move off the specific top collision), however I want a generic approach so colliding with any solid results in my character not being able to move.
水平碰撞 and/or 垂直碰撞是我所知道的两个 axis-aligned bounding boxes. AABBs are used as a default in Crafty's collision detection (and can be accessed via .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>
SAT 碰撞
Crafty 中有一个更复杂和精确的碰撞检测变体,使用 seperate axis theorem, which works between any two convex polygons. A custom polygon hitbox can be specified via .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 以获得有关所用组件和事件的更多信息。
我目前正在玩 crafty js 并创建了带有实体对象的 2D 俯视世界。
当任何固体物体发生碰撞事件时,我希望我的播放器不再能够朝所述物体的方向移动(因为有固体物体挡住了它的路径)。
我在网上找到了一些 tutorials 涵盖该主题的内容,但是它们调用的方法和函数已被删除。
.onHit("solid", function(from) {
console.log("ouch");
}
当我的播放器撞到固体时,我可以注册碰撞,但我不知道如何停止移动。
我知道我可以为每次碰撞设置特定的解决方案(例如,顶部边框可以更新 y 以离开特定的顶部碰撞),但是我想要一种通用的方法,因此不会与我的角色中的任何实体结果发生碰撞能够移动。
当我尝试调用 from.x
时,我收到的元素是 undefined
,而 from.length
等其他元素起作用,这对我来说没有意义。
或者提供一些兼容最新crafty的演示代码?
碰撞数据
When I try to call
from.x
I receive that the element isundefined
, while other elements such asfrom.length
do work, which does not make sense to me.
onHit callback provides you with the same collision data as the hit 函数 - 碰撞结果数组。这就是您能够访问 length
属性 的原因。
来自hit apidocs:
The returned collision data will be an Array of Objects with the type of collision used, the object collided and if the type used was SAT (a polygon was used as the hitbox) then an amount of overlap.
MBR 冲突
I know that I can setup specific solutions per collision (for example, a top border can update y to move off the specific top collision), however I want a generic approach so colliding with any solid results in my character not being able to move.
水平碰撞 and/or 垂直碰撞是我所知道的两个 axis-aligned bounding boxes. AABBs are used as a default in Crafty's collision detection (and can be accessed via .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>
SAT 碰撞
Crafty 中有一个更复杂和精确的碰撞检测变体,使用 seperate axis theorem, which works between any two convex polygons. A custom polygon hitbox can be specified via .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 以获得有关所用组件和事件的更多信息。