Collision 组件

事件

HitOn [Data = { hitData }]
当碰撞发生时触发。除非此类型的碰撞停止,否则将不会再次触发,否则将再次请求事件(使用`resetHitChecks(component)`)。
HitOff [componentName = {String}]
当与特定组件类型的碰撞停止时触发

用于检测任何两个凸多边形碰撞的组件。

如果对多个组件进行了碰撞检查,并且与多个类型的碰撞发生了模拟,那么每次碰撞都会导致一个单独的事件发生。

注意:从事件接收到的所有数据只在事件的回调期间有效。如果你想保存数据,那就复制一份吧。

对于碰撞事件数据(上边的hitData)的描述,请参考文档 .hit().

参见

方法

Back to top

.cbr()

public Object .cbr([Object cbr])
cbr

用作输出的对象

[Returns]

一个带有_x, _y, _w, 和 _h属性的对象;如果一个对象被传入,它将被重用而不是创建一个新对象。

返回一个包含该实体的碰撞边界矩形的副本的对象。碰撞边界矩形包含了实体的自定义碰撞和它的最小边界矩形。如果定制的碰撞盒子不位于实体外部,它将返回实体的最小边界矩形 (.mbr())。

注意: 键有一个下划线前缀。这是由于x、y、w、h属性是setter和getter,用下划线(_x, _y, _w, _h)来包装底层属性。

参见

Back to top

.checkHits()

public this .checkHits(String componentList)
componentList

一个逗号分隔的组件列表,以检查是否与之发生碰撞。

public this .checkHits(String component1[, .., String componentN])
component#

用来检查碰撞的组件。

对在调用该方法时指定至少一个组件的所有实体执行碰撞检查。如果发生碰撞,将为包含该方法的实体触发一个包含碰撞信息的“HitOn”事件。请参阅.hit()的文档,用于描述事件中包含的碰撞数据。当报告的碰撞结束时,将会触发相应的“HitOff”事件。

对于相同的组件类型,多次调用该方法不会导致多余的碰撞检查。

如果您想要更细粒度的控制,请考虑使用.hit(),甚至是Crafty.map.search()

注意:在输入每个新帧时执行碰撞检查(使用EnterFrame事件)。在执行完检查之后,对象完全有可能在这一帧中移动(即使更多的是EnterFrame的结果,因为处理程序没有特定的顺序运行)。在这种情况下,除非在下一帧中执行下一个检查,才会触发命中事件。

例子

Crafty.e("2D, Collision")
    .checkHits('Solid') // check for collisions with entities that have the Solid component in each frame
    .bind("HitOn", function(hitData) {
        Crafty.log("Collision with Solid entity occurred for the first time.");
    })
    .bind("HitOff", function(comp) {
        Crafty.log("Collision with Solid entity ended.");
    });
Back to top

.collision()

事件

NewHitbox [Data = {Crafty.polygon}]
当一个新的碰撞盒子被分配时
public this .collision([Crafty.polygon polygon])
polygon

可选对象 Crafty.polygon 将作为碰撞区域

public this .collision([Array coordinatePairs])
coordinatePairs

可选的x,y坐标对数组用来生成一个碰撞区域的多边形。

public this .collision([x1, y1,.., xN, yN])
point#

可选的x,y坐标对列表用来生成一个碰撞区域的多边形。

构造函数接受一个多边形,一个点的数组或一个点的列表作为击中区域,点相对于物体在未旋转状态下的位置。

碰撞区域必须是凸形,而不是凹面,以使碰撞检测工作正常。

如果没有传递参数,将使用该实体的x、y、w、h属性,并且当该实体存在时,碰撞盒子将会调整大小。

如果在实体的边界之外设置了一个碰撞盒子,那么将会有一个小的性能损失,因为它被单独跟踪。

为了让定制的碰撞盒子有任何效果,您必须将Collision添加到该实体需要使用这个定制的碰撞盒子的所有其他实体中。相反,碰撞将使用默认的碰撞盒子来解决。参见.hit()MBR代表默认的碰撞盒子,SAT表示自定义的碰撞盒子。

例子

Crafty.e("2D, Collision").collision(
    new Crafty.polygon([50, 0,  100, 100,  0, 100])
);

Crafty.e("2D, Collision").collision([50, 0,  100, 100,  0, 100]);

Crafty.e("2D, Collision").collision(50, 0,  100, 100,  0, 100);
Back to top

.hit()

public Array .hit(String component)
component

检查与有此组件的实体之间的碰撞。

[Returns]

如果没有碰撞就会返回 null。如果检测到冲突,则返回一个碰撞数据对象数组(见下文)。

与具有指定组件的实体进行碰撞测试。如果检测到碰撞,将在该方法返回的阵列中显示关于碰撞的数据。如果没有发生冲突,则该方法返回null

下面是碰撞的描述数据对象,这种方法可能返回:返回的碰撞数据是一个用于碰撞类型的数组或对象,如果使用的类型是SAT(一个用于碰撞盒子的多边形),对象是物体碰撞的重叠量。

[{
   obj: [entity],
   type: ["MBR" or "SAT"],
   overlap: [number]
}]
  • obj:碰撞发生的实体。
  • type: 碰撞检测方法。下边之一:
    • MBR:标准轴对准矩形交点 (.intersect 在 2D 组件中).
    • SAT: 两个凸多边形之间的碰撞。当两个碰撞的实体都有Collision组件应用到它们的时候。
  • overlap:如果使用了SAT碰撞,这将表示碰撞实体之间的重叠百分比。

请记住,两个实体都需要有Collision组件,如果您想要检查它们之间的SAT(定制的碰撞盒子)碰撞。

如果您想要更细粒度的控制,请考虑使用Crafty.map.search().

例子

解决与移动实体(玩家)的静态碰撞(墙)的碰撞。

Crafty.e("2D, Fourway, Collision, player")
      .attr({x: 32, y: 32, w: 32, h: 32})
      .collision([0, 16, 16, 0, 32, 16, 16, 32])
      .fourway()
      .bind('Moved', function(evt) { // after player moved
        var hitDatas, hitData;
        if ((hitDatas = this.hit('wall'))) { // check for collision with walls
          hitData = hitDatas[0]; // resolving collision for just one collider
          if (hitData.type === 'SAT') { // SAT, advanced collision resolution
            // move player back by amount of overlap
            this.x -= hitData.overlap * hitData.normal.x;
            this.y -= hitData.overlap * hitData.normal.y;
          } else { // MBR, simple collision resolution
            // move player to position before he moved (on respective axis)
            this[evt.axis] = evt.oldValue;
          }
        }
      });
Back to top

.ignoreHits()

public this .ignoreHits()
public this .ignoreHits(String componentList)
componentList

逗号分隔的组件列表,以停止检查与之碰撞。

public this .ignoreHits(String component1[, .., String componentN])
component#

一个停止检查与碰撞的组件。

停止检查与所有或某些组件的碰撞。如果没有参数调用,该方法将导致对实体的所有碰撞检查停止。要禁用与特定组件的碰撞检查,请将组件指定为逗号分隔的字符串或作为一组参数。

使用组件名的方式调用此方法时,在没有碰撞检测的情况下没有效果。

例子

Crafty.e("2D, Collision")
    .checkHits('Solid')
    ...
    .ignoreHits('Solid'); // stop checking for collisions with entities that have the Solid component
Back to top

.onHit()

public this .onHit(String component, Function callbackOn[, Function callbackOff])
component

用于检查碰撞的组件。

callbackOn

回调方法在与组件发生碰撞时执行。传递的第一个参数将是碰撞检查的结果,其格式与hit()记录的格式相同。第二个参数传递的是一个布尔值,指示是否第一次发生与组件的冲突。

callbackOff

一旦冲突停止,回调方法就会执行一次。

Creates an EnterFrame event calling .hit() each frame. When a collision is detected the callbackOn will be invoked.

Note that the callbackOn will be invoked every frame the collision is active, not just the first time the collision occurs. Use the second argument passed to callbackOn to differentiate that, which will be true if it's the first time the collision occurs.

If you want more fine-grained control consider using .checkHits(), .hit() or even Crafty.map.search().

例子

对玩家和子弹之间的碰撞做出反应。

Crafty.e("2D, Collision, player")
      .attr({ health: 100 })
      .onHit('bullet', function(hitDatas) { // on collision with bullets
        for (var i = 0, l = hitDatas.length; i < l; ++i) { // for each bullet hit
          hitDatas[i].obj.destroy(); // destroy the bullet
          this.health -= 25; // player looses health
          if (this.health <= 0) // once player's health depletes
            this.destroy(); // player dies
        }
      });
Back to top

.resetHitChecks()

public this .resetHitChecks()
public this .resetHitChecks(String componentList)
componentList

一个逗号分隔的组件列表,以重新检查与之碰撞。

public this .resetHitChecks(String component1[, .., String componentN])
component#

用于重新检查与之碰撞的组件。

在已经发生的碰撞中,会引起碰撞事件(通常情况下,在碰撞停止并再次发生之前,一个额外的事件不会发生)。如果没有参数调用,该方法将导致对实体的所有碰撞检查再次触发事件。要重新检查与特定组件的碰撞,请将组件指定为逗号分隔的字符串或作为一组参数。

使用组件名的方式调用此方法时,在没有碰撞检测的情况下没有效果。

例子

// this example fires the HitOn event each frame the collision with the Solid entity is active, instead of just the first time the collision occurs.
Crafty.e("2D, Collision")
    .checkHits('Solid')
    .bind("HitOn", function(hitData) {
        Crafty.log("Collision with Solid entity was reported in this frame again!");
        this.resetHitChecks('Solid'); // fire the HitOn event in the next frame also, if the collision is still active.
    })