Articles Archive
Articles Search
Director Wiki
 

Lingo Collision Detection, Part 2

May 3, 2000
by Gary Rosenzweig

Last week we looked at some basic Lingo for collision detection: intersects, intersect, inside and hitTest. We also looked at mathematical ways to detect collisions. All of these methods fall short in one way or another. Most will not detect collisions around shapes more complex than a rectangle. Others will not detect collisions until the Stage has already been updated to show the objects overlapping.

Before looking at ways to improve collision detection, it is important to understand how objects move in computer programs. In real life, if you walk from one side of the room to the other, you pass through an infinite amount of points. At any moment you could stop, and at any moment another person could see you at a location. Time can be divided into smaller and smaller pieces to more accurately define your position at a given moment.

With computer animation, the movement happens in slices of time called frames. You can have 15 frames per second, 60 frames per second, or even up to 999 frames per second with Director 8. However, you cannot have an infinite number of frames per second. So an object on the screen must jump from one defined instant of time to the next, and never be somewhere in between.

There are two ways than an object can move. The first is instantaneous movement. This is when the object can suddenly jump from one point on the screen to another. This is what happens when a mouse is used to control an object. The user can simply flick his or her wrist to zap the object across the screen.

The other way that an object can move is incrementally. This is when the object can only move step-by-step. It is typical of arrow key movement.

Most video games require that the objects move incrementally. Think about it. If a bomb is raining down in Space Invaders, and the player's ship is to the right on the bomb, then the player moves the ship to the left of side of the screen, the ship cannot be allowed to skip over the bomb. It must impact and destroy the ship. If a mouse is used to control the ship, and the ship's position is directly linked to the mouse position, then the ship can simply jump from one side of the screen to another in an instant, avoiding objects that should be in the path.

Doing collision detection with instantaneous movement is very difficult. Every time the object changes position, you would have to look at the line between the old location and the new location and see if there was a collision. If so, you will have to take the object back to the point of collision. When irregular shapes are concerned, this will be nearly impossible to do with Lingo's primitive collision detection functions.

Incremental movement is much easier to deal with. If an object collides with another, you can simply take it one step back to avoid the collision. You would want to do this in the case of a wall or something that the player is not supposed to be able to get through.

So let's look at the example of a player character and a wall. The wall is an impenetrable object that the character cannot move through. The wall is perfectly rectangular. If you want to have a move complex shape, have many wall sprites instead of just one.

The following movie shows a character that can be moved around with the arrow keys. As each move is made, the program checks to make sure that no walls are hit. If a wall is to be hit, then the movement is not allowed.

Use the arrow keys to move the character around.
Director 8 download for Mac or Windows.

The intersect command is used to determine if there is a collision. It is used before the actual movement takes place. The way this is done is that the program calculates from the current rect of the sprite and the direction of movement what the new rect will be. It then compares that to the rect of the wall. If they intersect, then the movement is not allowed.

This idea of checking for collisions before the movement takes place is rarely used by Lingo programmers, but it should be used almost all the time. Here is the code that makes it work. First, there is the "on move" handler in the character sprite. This will work out the new rect of the sprite and check with all the possible wall sprites to see if there is a collision.

on move me, dx, dy
  
  -- get rect and add change to it
  oldRect = sprite(me.spriteNum).rect
  newRect = oldRect + rect(dx,dy,dx,dy)
  
  -- loop through possible wall sprites
  -- and detect collisions
  hitWall = FALSE
  repeat with i = 2 to 10
    if sendSprite(i,#hitWall,newRect) then
      hitWall = TRUE
      exit repeat
    end if
  end repeat
  
  -- if no collision, then move sprite
  if not hitWall then
    sprite(me.spriteNum).loc = sprite(me.spriteNum).loc + point(dx,dy)
  end if
  
end

In each wall sprite, in this case sprite 2 through 10, the "on hitWall" handler will return a TRUE only if the rect of the wall and the rect of the object intersect.

on hitWall me, objRect
  
  if intersect(sprite(me.spriteNum).rect,objRect) <> rect(0,0,0,0) then
    return TRUE
  else
    return FALSE
  end if
  
end

We could have done this intersect test inside the "on move" handler. However, this would assume that every sprite was in use and being used as a wall. This way, you can stick other objects in sprites and they will only respond with a possible TRUE if it is has the behavior attached to it with the "on hitWall" handler. If no sprite is there at all, or one without an "on hitWall" handler, then a VOID is returned. This is then interpreted as a FALSE by the "on move" handler.

If you want to study this type of collision detection more, I use it in the adventure game chapter of my "Advanced Lingo for Games" book. Next week, we'll take a closer look at how to actually detect when a collision has occurred. Director 8's new Imaging Lingo offers us some new tools there.

Gary Rosenzweig's latest book is "Advanced Lingo for Games." In it, you can find the source code for more than 20 complete games. More information about the book can be found at http://clevermedia.com/resources/bookstore/book4.html. It can be purchased there, or in your local bookstore.

Gary Rosenzweig is the Chief Engineer, founder, and owner of CleverMedia, a game and multimedia development company in Denver, Colorado. He is the author of ten books on Macromedia Director and Flash, including his latest, Special Edition Using Director MX.

Copyright 1997-2024, Director Online. Article content copyright by respective authors.