狡猾的JS碰撞运动

时间:2016-03-02 18:24:57

标签: javascript collision craftyjs

我目前正在玩crafty js,并创建了具有实体对象的2D自上而下的世界。

当任何固体物体发生碰撞事件时,我希望我的播放器不再能够朝着所述物体的方向移动(因为有一个固体物体挡住它的路径)。

我在网上找到了一些tutorials来涵盖这个主题,但是他们调用的方法和功能都被删除了。

    .onHit("solid", function(from) {
        console.log("ouch");
     }

当我的球员击中稳定时,我可以注册碰撞,但我不知道如何阻止这一动作。

我知道我可以为每次碰撞设置特定的解决方案(例如,顶部边框可以更新y以移除特定的顶部碰撞),但是我想要一个通用的方法,因此与我的角色中的任何可靠结果相撞都不能移动。

当我尝试拨打from.x时,我收到该元素为undefined,而其他元素(如from.length)确实有效,这对我来说没有意义。

或者提供一些兼容最新狡猾的演示代码?

1 个答案:

答案 0 :(得分:2)

碰撞数据

  

当我尝试拨打from.x时,我收到该元素为undefined,而其他元素(如from.length)确实有效,这对我来说没有意义。

onHit回调为您提供与hit函数相同的碰撞数据 - 碰撞结果数组。这就是您能够访问length属性的原因。

来自hit apidocs

  

返回的碰撞数据将是一个对象数组,其中包含使用的碰撞类型,对象发生碰撞,如果使用的类型是SAT(多边形用作命中框),则重叠量。

MBR碰撞

  

我知道我可以为每次碰撞设置特定的解决方案(例如,顶部边框可以更新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>

SAT碰撞

使用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,了解有关所用组件和事件的其他信息。