Collision Events

This tutorial shows how to use collision events in Quorum.

Detecting Collisions with Events

In this tutorial, we will learn about collision events.

In addition to testing for input using events, we can also use events to detect when two Items have collided in our game. In this last sample program, a black rectangle will be at the center of the screen. A white circle will be on the left side of the screen, which will pass over the rectangle as it moves off the right edge of the screen, and reappears on the left side. Every time the circle and the rectangle begin overlapping, a sound will play, the rectangle will turn blue, and the circle will turn red. Every time the circle and the rectangle begin overlapping, a sound will play, the rectangle will turn blue, and the circle will turn red. The complete sample, including audio, can be downloaded by clicking here .

Our code is in a single file.

use Libraries.Game.Game
use Libraries.Game.Graphics.Drawable
use Libraries.Game.Graphics.Color
use Libraries.Interface.Events.CollisionListener2D
use Libraries.Sound.Audio
use Libraries.Interface.Events.CollisionEvent2D
use Libraries.Interface.Item2D

class Main is Game, CollisionListener2D

   Drawable block
   Drawable circle

   Audio beginSound
   Audio finishSound
   action Main
       StartGame()
   end

   action CreateGame
       // These two lines load our sound files
       beginSound:Load("AudioFiles/lightSound.wav")
       finishSound:Load("AudioFiles/heavySound.wav")

       // These lines are used to load and draw the circle and square.
       block:LoadFilledRectangle(300, 200)
       Color white
       white = white:White()
       circle:LoadFilledCircle(60, white)
       block:SetPosition(250, 200)
       circle:SetPosition(0, 240)
       Add(block)
       Add(circle)

       // These two lines give our Drawables a name so that we can identify
       // each object and do things to them when they begin or finish colliding
       block:SetName("block")
       circle:SetName("circle")

       // These two lines are used to make the two items detect collisions.
       block:SetCollidable(true)
       circle:SetCollidable(true)

       // This line is used to make our Game class listen for and handle collisions
       AddCollisionListener(me)
   end

   action Update(number seconds)
       // The Update action is used in this program to make the circle move.
       circle:SetX(circle:GetX() + 200 * seconds)
       if circle:GetX() > GetScreenWidth()
           circle:SetX(0 - circle:GetWidth())
       end
   end

   /*
   This is the action that gets called automatically by the game engine when
   a collision begins between two collidable items. We are passed an item
   that represents the event of the collision. From that item we can get the
   items that are colliding.
   */
   action BeginCollision(CollisionEvent2D event)
       // First things first, play the begin collision sound
       beginSound:Play()

       // Next, we want to get our items out of the collision event
       Drawable itemA = cast(Drawable, event:GetItemA())
       Drawable itemB = cast(Drawable, event:GetItemB())

       // the block will turn blue when they start colliding
       Color blue
       blue = blue:Blue()

       // the circle will turn red when they start colliding
       Color red
       red = red:Red()
       if itemA:GetName() = "block"
           // if itemA is the block, then itemA gets the color blue and itemB
           // bets the color red.
           itemA:SetColor(blue)
           itemB:SetColor(red)
       else
           // otherwise, the reverse is true
           itemA:SetColor(red)
           itemB:SetColor(blue)
       end
   end

   /*
   This is the action that gets called automatically by the game engine when
   a collision finishes between two collidable items. We are passed an item
   that represents the event of the collision. From that item we can get the
   items that are colliding.
   */
   action FinishCollision(CollisionEvent2D event)
       // First things first, play the finish collision sound
       finishSound:Play()

       // Next, we want to get our items out of the collision event
       Drawable itemA = cast(Drawable, event:GetItemA())
       Drawable itemB = cast(Drawable, event:GetItemB())

       // the block will turn black when they finish colliding
       Color black
       black = black:Black()

       // the circle will turn white when they finish colliding
       Color white
       white = white:White()

       if itemA:GetName() = "block"
           // if itemA is the block, then itemA gets the color black and itemB
           // bets the color white.
           itemA:SetColor(black)
           itemB:SetColor(white)
       else
           // otherwise, the reverse is true
           itemA:SetColor(white)
           itemB:SetColor(black)
       end
   end
end

Just like other events, we can declare one or more of our game objects as a listener for that event. In this case, our Main class also listens for collisions between two 2D items via the line class Main is Game, CollisionListener2D . Similarly to other events, the game engine automatically passes an object representing the event to our actions for handling that event; in this case, we are passed a CollisionEvent2D object representing a collision between two 2D items in our BeginCollision and FinishCollision actions.

If we want the game engine to tell us when two items are colliding, we need to tell the game engine that those items are collidable. We do this by calling the SetCollidable action on the items with the parameter true . A handy place to do this is in our CreateGame action.

It is important to note that collidable items can only collide with other items that have been declared collidable. So, if two items are overlapping in our game, but one of them has not been set to be collidable, we will not receive a collision event for those two items. On the other hand, if two items are overlapping and both of them have been declared collidable, we will receive a collision event for these two items.

// This line is used to make our Game class listen for and handle collisions
AddCollisionListener(me)

All objects declared as collision listeners should implement an action for handling when items start to collide, called BeginCollision. This action is passed a CollisionEvent2D or CollisionEvent3D object (depending on whether the listener is listening for 2D or 3D collisions) that represents the collision.

action BeginCollision(CollisionEvent2D event)

end

Similarly, objects declared as collision listeners should implement an action called FinishCollision for handling when two items stop colliding. This action also takes as a parameter an event object representing either the 2D or 3D collision event.

action FinishCollision(CollisionEvent2D event)

end

In the above mentioned BeginCollision and FinishCollision actions, we should perform the actions that we want to occur when items either begin or finish colliding. Both of the items that are colliding are in the event object passed to the BeginCollision and FinishCollision actions. We can get the colliding items from the event object by calling the GetItemA() and GetItemB() actions on the event object. From there, we can do the things that we want to happen when items are overlapping such as playing a sound or changing the color of the items.

action BeginCollision(CollisionEvent2D event)
   // First things first, play the begin collision sound
   beginSound:Play()

   // Next, we want to get our items out of the collision event
   Drawable itemA = cast(Drawable, event:GetItemA())
   Drawable itemB = cast(Drawable, event:GetItemB())

   // the block will turn blue when they start colliding
   Color blue
   blue = blue:Blue()

   // the circle will turn red when they start colliding
   Color red
   red = red:Red()

   if itemA:GetName() = "block
       // if itemA is the block, then itemA gets the color blue and itemB
       // bets the color red.
       itemA:SetColor(blue)
       itemB:SetColor(red)
   else
       // otherwise, the reverse is true
       itemA:SetColor(red)
       itemB:SetColor(blue)
   end
end

With our Main class filled, our program is ready. The Game should consist of a circle moving from left to right, making a sound when it begins overlapping the rectangle and changing its color to red and the rectangle's color to white. When it stops overlapping with the rectangle, a different sound is played, it changes color to white, and the rectangle changes color to black.

The Image on the left is when the red circle make a sound that it has collided with the blue rectangle and the picture on the right is when the white circle leaves the black rectangle making a sound.

This is an image of a red circle enter in a blue rectangle This is an image of a white circle leave in a black rectangle
// These two lines are used to make the two items detect collisions.
block:SetCollidable(true)
circle:SetCollidable(true)

Additionally, if we want to be notified about collision events, we need to tell our game about our collision listener object. We do so by calling the AddCollisionListener action and passing it the object that should be listening for collisions. Again, a great place to do this is in our CreateGame action.

Resources

The"lightSound.wav"sound file is used under the Creative Commons Attribution 3.0 license: Sword Swing.

The"heavySound.wav"sound file is used under the Creative Commons Attribution 3.0 license: Battle Axe Sound

End of Lesson

You have reached the end of the lesson for User Interaction and Events. To view more tutorials, press the button below or you can go back to the previous lesson pages.