Lingo Collision Detection, Part 3
by Gary Rosenzweig
|
For the last two weeks we have looked at collision detection. We've examined Lingo functions like intersect, intersects, inside and hitTest. We've also looked at mathematical distance formulas. Director 8 offers a new way to do collision detection. Thanks to the getPixel function, we can examine contents of individual pixels. So, if we take an image, say a character in a game, and examine every pixel in the bitmap, we can make a list of all the points in the image. We can rule out pixels that are the same as the background color of the bitmap. This will create a virtual mask of the image as a series of points. We can then compare this series of points to other bitmaps on the Stage. This point-by-point comparison will give us an accurate reading of when there is a collision. Better still, it can give us that reading before the sprite is actually moved. This will enable us to detect collisions before they happen and prevent them, rather than acting after the fact as we would have to do with the intersects function. Let's make a quick behavior that does this. The first step would be to define what is a background color and what is not. Then, to get a list of points in the image that are not transparent. We will use white as the background color, and even name the property pWhite, though another can be used depending on the image. property pPoints, pWhite This handler looks at all of the points in the image and adds those that are not the background color to a list. on findPoints me This list of points is then used in the next handler to compare with other sprites. To speed things up, only a small range of sprites are compared. The useful mapMemberToStage and mapStageToMember are used to translate points in the character's image to points on the Stage, and then those points to points in the other sprites' image. on checkCollision me On every frame, the "on checkCollision" handler is called. In this example, this information is only used to fill a text member. In a real situation, you will want to use this information to prevent movement. on exitFrame me In the example movie below, the sprite can be moved by dragging. This is enabled by just setting the moveable property of the sprite to TRUE.
Download the Director 8 sample movie in Mac or PC format. In a real-life situation, you will not want to use the mouse to move such a character. Instead, use the keyboard. This will enable you to get closer to objects. Using the mouse means that the character can quickly jump from one area of the screen to another. So, it could conceivably jump from one side to the other, and place it right in the middle of an object or wall. If you are trying to prevent such collisions, then you would not allow such movement, and the sprite would remain on the other. As to the best collision detection... we still have no definite answers. This week's solution can be very slow for larger sprites, and even slower if you have to adjust it for different character positions and movement animation. It is important to realize that you will have to create different collision detection solutions depending on what the desired result is. If you only wish to prevent collisions into walls, then rectangle intersections may be enough. However, if you wish to detect a sword thrust through a character, then this week's method may be needed, or at least the sprite intersects function. Keep all of these methods in mind and come up with your own based on an understanding of them.
|