Collision Component

Events

HitOn [Data = { hitData }]
Triggered when collisions occur. Will not trigger again until collisions of this type cease, or an event is requested once more (using `resetHitChecks(component)`).
HitOff [componentName = {String}]
Triggered when collision with a specific component type ceases

Component to detect collision between any two convex polygons.

If collision checks are registered for multiple component and collisions with multiple types occur simultaniously, each collision will cause an individual event to fire.

Note: All data received from events is only valid for the duration of the event's callback. If you wish to preserve the data, make a copy of it.

For a description of collision event data (hitData above), see the documentation for .hit().

See Also

Methods

Back to top

.cbr()

public Object .cbr([Object cbr])
cbr

an object to use as output

[Returns]

an object with _x, _y, _w, and _h properties; if an object is passed in, it will be reused rather than creating a new object.

Return an object containing a copy of this entity's collision bounding rectangle. The CBR encompasses both the entity's custom collision hitbox and its MBR. If the custom collision hitbox does not sit outside the entity it will return the entity's minimum bounding rectangle (.mbr()) instead.

Note: The keys have an underscore prefix. This is due to the x, y, w, h properties being setters and getters that wrap the underlying properties with an underscore (_x, _y, _w, _h).

See Also

Back to top

.checkHits()

public this .checkHits(String componentList)
componentList

A comma seperated list of components to check for collisions with.

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

A component to check for collisions with.

Performs collision checks against all entities that have at least one of the components specified when calling this method. If collisions occur, a "HitOn" event containing the collision information will be fired for the entity on which this method was invoked. See the documentation for .hit() for a description of collision data contained in the event. When a collision that was reported ends, a corresponding "HitOff" event will be fired.

Calling this method more than once for the same component type will not cause redundant hit checks.

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

Note: Hit checks are performed on each new frame (using the UpdateFrame event). It is entirely possible for object to move in said frame after the checks were performed (even if the more is the result of UpdateFrame, as handlers run in no particular order). In such a case, the hit events will not fire until the next check is performed in the following frame.

Example

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()

Events

NewHitbox [Data = {Crafty.polygon}]
when a new hitbox is assigned
public this .collision([Crafty.polygon polygon])
polygon

Optional Crafty.polygon object that will act as the hit area.

public this .collision([Array coordinatePairs])
coordinatePairs

Optional array of x, y coordinate pairs to generate a hit area polygon.

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

Optional list of x, y coordinate pairs to generate a hit area polygon.

Constructor that takes a polygon, an array of points or a list of points to use as the hit area, with points being relative to the object's position in its unrotated state.

The hit area must be a convex shape and not concave for collision detection to work properly.

If no parameter is passed, the x, y, w, h properties of the entity will be used, and the hitbox will be resized when the entity is.

If a hitbox is set that is outside of the bounds of the entity itself, there will be a small performance penalty as it is tracked separately.

In order for your custom hitbox to have any effect, you have to add the Collision component to all other entities this entity needs to collide with using this custom hitbox. On the contrary the collisions will be resolved using the default hitbox. See .hit() - MBR represents default hitbox collision, SAT represents custom hitbox collision.

Example

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[, Array results])
component

Check collision with entities that have this component applied to them.

results

If a results array is supplied, any collisions will be appended to it

[Returns]

null if there is no collision. If a collision is detected, returns an Array of collision data objects (see below). If the results parameter was passed, it will be used as the return value.

Tests for collisions with entities that have the specified component applied to them. If a collision is detected, data regarding the collision will be present in the array returned by this method. If no collisions occur, this method returns null.

When testing for collisions, if both entities have the Collision component, then the collision test will use the Separating Axis Theorem (SAT), and provide more detailed information about the collision. Otherwise, it will be a simple test of whether the minimal bounding rectangles (MBR) overlap.

Following is a description of a collision data object that this method may return: 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.

[{
   obj: [entity],
   type: ["MBR" or "SAT"],
   overlap: [number],
   nx: [number],
   ny: [number]
}]

All collision results will have these properties:

  • obj: The entity with which the collision occured.
  • type: Collision detection method used. One of:
    • MBR: Standard axis aligned rectangle intersection (.intersect in the 2D component).
    • SAT: Collision between any two convex polygons. Used when both colliding entities have the Collision component applied to them.

If the collision result type is SAT then there will be three additional properties, which represent the minimum translation vector (MTV) -- the direction and distance of the minimal translation that will result in non-overlapping entities.

  • overlap: The magnitude of the translation vector.
  • nx: The x component of the MTV.
  • ny: The y component of the MTV.

These additional properties (returned only when both entities have the "Collision" component) are useful when providing more natural collision resolution.

If you want more fine-grained control consider using Crafty.map.search().

Example

Resolving collisions with static colliders (walls) for moving entity (player).

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('Move', 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.nx;
            this.y -= hitData.overlap * hitData.ny;
          } else { // MBR, simple collision resolution
            // move player to previous position
            this.x = evt._x;
            this.y = evt._y;
          }
        }
      });
Back to top

.ignoreHits()

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

A comma separated list of components to stop checking for collisions with.

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

A component to stop checking for collisions with.

Stops checking for collisions with all, or certain, components. If called without arguments, this method will cause all collision checks on the entity to cease. To disable checks for collisions with specific components, specify the components as a comma separated string or as a set of arguments.

Calling this method with component names for which there are no collision checks has no effect.

Example

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

Component to check collisions for.

callbackOn

Callback method to execute upon collision with the component. The first argument passed will be the results of the collision check in the same format documented for hit(). The second argument passed will be a Boolean indicating whether the collision with a component occurs for the first time.

callbackOff

Callback method executed once as soon as collision stops. No arguments are passed.

Creates an UpdateFrame 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().

Example

Respond to collisions between player and bullets.

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

A comma seperated list of components to re-check for collisions with.

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

A component to re-check for collisions with.

Causes collision events to be received for collisions that are already taking place (normally, an additional event would not fire before said collisions cease and happen another time). If called without arguments, this method will cause all collision checks on the entity to fire events once more. To re-check for collisions with specific components, specify the components as a comma separated string or as a set of arguments.

Calling this method with component names for which there are no collision checks has no effect.

Example

// 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.
    })