Menu

Collision_Systems

Hugh Greene

(Wiki Note: This article could use some images.)

In game development, a collision occurs when two
instances or shapes move to overlap each other
(even if it's just 1-pixel overlap). This concept is useful for
triggering a specific event. For instance, when a
player is falling, and then comes into contact with a platform, he
should stop. If he comes into contact with an enemy, he should either
take damage or damage the enemy. To detect when something comes into
contact with something else, you would use a collision event.

The exact specifics of when a collision occurs depend on the Mask
settings and Collision system selected, but generally, we can say that a
collision is deemed true when two things are overlapping or intersect by
any amount.

Event

First, understand an event, and the difference
between an object and an
instance.

An object obj_0 will define an event with another object obj_1 (or
even the same object). When any instance of obj_0 comes into contact
with any instance of obj_1, the event is fired inside of that instance
of obj_0. If multiple instances are involved in collisions in one
step, they will all fire collision events. If obj_1 also has a
collision event with obj_0, then both collision events will fire. If
you choose a collision event with the same object, then whenever any two
instances of that object collide, both of them will fire their collision
event.

A collision event will continue to occur every step
for as long as the two objects continue to overlap. Because of this, in
order to avoid repeatedly executing code (like constantly taking
damage), it can be wise to, when a collision occurs, do something to
make the collision stop happening. A few suggestions;

  • Destroy one or both of the objects.
  • Move one or both of the objects.
  • Set a variable, and only execute the event if the variable is a
    certain value. You might consider setting an
    alarm to determine when to reset the variable.

For your convenience, within a collision event, the
other variable can be used to refer to the other
object in the collision. For DND users, many
actions have an Applies to section at the top, with other listed
as one of the options. Other can be used to execute some piece of
code or action on the other object. For instance, collecting coins could
be done as follows:

In obj_player's collision event with obj_coin:
Set the score relative to 1
For other object: Destroy the instance.

Formulas and Settings

The fundamental formulas for collision detection are rather complex,
usually involving geometric polygon intersection algorithms, and even
pixel-overlap algorithms for pixel-perfect collision. Fortunately,
ENIGMA comes packed with several Collision
Systems
built in, and a default selected,
so all you need to do is add collision events to the instances that you
are interested in, and handle the event however you like. The selected
collision system will decide when to trigger the event and execute the
actions inside of it.

Using all defaults can quickly make your game feel very clunky, so once
you are familiar with the basics of collisions, you can then move on to
fine tuning the system. The sections below will provide you with the
different levels of tuning your collisions.

Masks

The region of an object that determines which parts are "solid" and
which parts are "air" is defined by the Mask. In the simplest sense, you
can think of a mask as a
silhouette of your object's
sprite. The dark regions are solid, and the light regions are air. A
collision occurs when the solid (dark) region of one object comes into
contact with the solid region of another object.

The mask of an object is determined by selecting a
sprite with the desired mask properties. By default, an object's mask is
set equal to its Sprite. To alter properties for
the object's mask, you can either alter the mask properties of the
sprite, or select a separate mask for that object. Note that the mask is
not visible in the game - only the sprite is drawn. The mask is only
used to determine collisions.

The mask can be read/set programmatically in-game via the
mask_index global
local
variable, or with the appropriate DND
action.

The exact properties of a mask are determined by which Collision System
you have selected. Please consult the respective Collision System's
documentation, under their Mask section. Obviously, if one collision
system's mask properties are insufficient for your game, you can select
another collision system.

Collision System

The selected collision system employs
the underlying formulas and algorithms to determine whether a collision
occurs. It determines the exact behavior of collision functions, as well
as the mask properties available. Since a collision event is determined
by collision functions, the collision system then also determines when
to trigger a collision event, based on the object's mask properties and
coordinates.

Different systems behave very differently, so choose carefully.
Generally, collision is a trade-off between efficiency (or calculation
speed) and precision (or how accurate the collision seems to be). We try
to select a default that is appropriate for the general case of most
games - that is, a nice balance between efficiency and precision.

To select a collision system, go to ENIGMA Settings > API >
Collisions, and select the desired system from the dropdown. Then click
the green checkmark to submit your changes.

The following systems are currently available for selection:

  • None - Collisions never occur. No collision functions are
    provided. Masks are meaningless. This is the most efficient system.
    It is useful for if you wish to handle collisions yourself, or do
    not intend to handle collisions at all.
  • Bounding Box (Current Default) - The mask
    of every object is a rectangular region defined by the sprite's
    bounding box. Object-collisions are entirely rectangle-based. A
    basic set of geometric collision functions are provided. Very
    efficient, but entirely restricted to rectangular objects.

The following systems we hope to make available in the future:

  • Circle/Sphere - The mask of every object is a circular region
    defined simply by an offset and a radius. Object-collisions are
    entirely point-distance based. A basic set of geometric collision
    functions are provided. Extremely efficient, but useless for more
    complex shapes.
  • Polygon - The mask of every object is a polygon - a set of
    outline points selected by the user. Object-collisions are entirely
    polygon-intersect based. An advanced set of geometric collision
    functions are provided. Fairly efficient, with more precision
    available by adding more points (at the cost of a bit of
    efficiency).
  • Pixel Perfect - The mask of every object is a bit map.
    Object-collisions are true if any solid bits overlap. An advanced
    set of geometric and pixel-perfect collision functions are provided.
    This is the most precise system, but is quite inefficient. Usually
    it is used in conjunction with the bounding box to rule out
    collisions in advance. This was the behavior that older versions of
    GM used.
  • Shape - The mask of every object is selected as one of the above
    shapes. Object-collisions perform an additional check to decide
    which collision function to use between two objects, An advanced set
    of geometric and pixel-perfect collision functions are provided. Not
    very efficient, but very versatile, and as precise as the Mask
    dictates.
  • Advanced Shape - Same as shape, but a simple bbox or
    distance-radius check is used first to determine whether the
    collision can be ruled out early. Because of this, it can be more
    efficient than Shape. On the other hand, if the additional check
    frequently doesn't rule out collisions, it can become less
    efficient, because it is an additional check. This is the behavior
    that GM uses (I think. Unless the shapes are just bit mapped).

(Wiki note: The above could probably be made into a table.)

Do it yourself

If none of the collision systems provided are suitable for your game,
and you would like to handle your own collisions, consider one of the
following:

  • Select None for collision system, and then handle all collisions
    in-game using your own formula
  • Select the closest collision system that will provide you with the
    best collision functions, not use collision events, and handle
    collisions in-game using the functions, or your own formulas where
    needed
  • Code your own Collision System into ENIGMA, compile it into ENIGMA,
    and then select it. If you think other people may benefit from your
    collision system, you can share it, or submit it for inclusion into
    ENIGMA (must be license-compliant).

Related

Wiki: Action
Wiki: Collision
Wiki: Collision_Detection
Wiki: Collision_Systems
Wiki: Collision_detection
Wiki: ENIGMA
Wiki: ENIGMA_compiler
Wiki: Event
Wiki: Other
Wiki: Sprite
Wiki: User:IsmAvatar

MongoDB Logo MongoDB