【问题标题】:Crafty JS collision movement狡猾的 JS 碰撞动作
【发布时间】:2016-03-02 18:24:57
【问题描述】:

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

当任何固体物体发生碰撞事件时,我希望我的玩家不再能够向所述物体的方向移动(因为有固体物体挡住了它的路径)。

我在网上找到了几个tutorials 涵盖了这个主题,但是他们调用的方法和函数被贬低了。

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

我可以在我的玩家击中实体时记录碰撞,但我不知道如何停止移动。

我知道我可以为每个碰撞设置特定的解决方案(例如,顶部边框可以更新 y 以移出特定的顶部碰撞),但是我想要一种通用的方法,因此与任何可靠的结果发生碰撞会导致我的角色无法移动。

当我尝试调用 from.x 时,我收到该元素是 undefined,而其他元素(例如 from.length)可以工作,这对我来说没有意义。

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

【问题讨论】:

    标签: javascript collision craftyjs


    【解决方案1】:

    碰撞数据

    当我尝试调用 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 碰撞

    Crafty 中有一个更复杂、更精确的碰撞检测变体,使用 seperate axis theorem,它适用于任意两个凸多边形。可以通过.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,了解有关所用组件和事件的更多信息。

    【讨论】:

    • 优秀的答案。谢谢。
    猜你喜欢
    • 2015-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 2011-01-19
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多