Flash Game Making Tutorial - Part 5
Today we will teach Ninja Square how to walk into stuff. Walking into stuff eh!? Not very ninja like I hear you say. Well, since we’ll be controlling our hero, it will be up to us to make sure he avoids walking into any dangers. Oh man, the responsibility that lies in our hands as gamers, people just don’t understand!
Open up you file from last week and lets get into it …
There are many ways in which we can work out collision detection, but the more precise you get, the more complex the code becomes. In my opinion, it’s good to find some tricks/workarounds if you want to keep things simple and stay sane.
Flash has an inbuilt collision detection method called the hitTest.
The way to use the hitTest is simple …
if (wall.hitTest(ninja._x, ninja._y, true)) { etc…
This basically says:
If the wall touches the center of the ninja MovieClip, then we do something. The parameter true has to be set in order for the walls shape to be tested against the Ninja, instead of its bounding box.

With the hitTest you can only test bounding box against bounding box or shape against a single point. The bounding box will always remain a box around the extremities of the object, even if the object is rotated. For our game, we’re going to use the point hitTest, as we can build on it to make it more flexible.
Now, I’ve had many failed attempts trying to get the hitTest to work for our specific situation and I won’t bore you with all the details (as we could be here all night), but thanks to Emanuele Feronato, I’ve found the best/simplest way!
Normally we would not use the WHILE loop, as it can really use up processing power and your game can come to a halt. In this case however, the WHILE loop works better then the IF statement and without much demand on the processor.
Before we type the code in, remember that Ninja Squares dimensions are 10×10 pixels. Since the hitTest will only test the middle of our MovieClip, we will have to add/subtract 5 pixels for all the hitTests (depending on the direction traveled).
Under the Ninja layer, make a new layer and call it “wall”.
On the “wall” layer, create a square (any size) and give it the instance name of “wall”.
Enter this code inside the onEnterFrame function, right after the code from last lesson …
while (_root.wall.hitTest(ninja._x-5, ninja._y, true)) { ninja._x+=1; } while (_root.wall.hitTest(ninja._x, ninja._y-5, true)) { ninja._y+=1; } while (_root.wall.hitTest(ninja._x+5, ninja._y, true)) { ninja._x-=1; } while (_root.wall.hitTest(ninja._x, ninja._y+5, true)) { ninja._y-=1; }
Basically, the code above tests if Ninja Square is touching the wall and if it is, it moves it away by 1 pixel per frame, before doing anything else.
Click on the movie below to give it focus and have a play …
Now, if you’ve tested the movie above, you would have noticed that there is a small problem. When you walk at the wall from the right or from the top, Ninja Square stops about 1 pixel away from the wall. The only way I have managed to overcome this problem is by changing the amount of pixels added/subtracted from the hitTest, from 5 to 4pixels for the problem directions.
Change the code we just typed in, to the following …
while (_root.wall.hitTest(ninja._x-4, ninja._y, true)) { ninja._x+=1; } while (_root.wall.hitTest(ninja._x, ninja._y-5, true)) { ninja._y+=1; } while (_root.wall.hitTest(ninja._x+5, ninja._y, true)) { ninja._x-=1; } while (_root.wall.hitTest(ninja._x, ninja._y+4, true)) { ninja._y-=1; }
As you see, everything now works as it should.
See you guys in the next lesson!
PS. Here is all code as it should be so far …
stop(); minX = 0; maxX = 522; minY = 0; maxY = 294; speed = 2; onEnterFrame = function() { if ((Key.isDown(key.LEFT)) and (ninja._x-5 > minX)) { ninja._x -= speed; ninja.gotoAndStop("left"); left = true; } else { left = false; } if ((Key.isDown(key.RIGHT)) and (ninja._x+5 < maxX)) { ninja._x += speed; ninja.gotoAndStop("right"); right = true; } else { right = false; } if ((Key.isDown(key.UP)) and (ninja._y-5 > minY)) { ninja._y -= speed; ninja.gotoAndStop("up"); up = true; } else { up = false; } if ((Key.isDown(key.DOWN)) and (ninja._y+5 < maxY)) { ninja._y += speed; ninja.gotoAndStop("down"); down = true; } else { down = false; } if ((!left) and (!right) and (!up) and (!down)) { ninja.gotoAndStop("idle"); } while (_root.wall.hitTest(ninja._x-4, ninja._y, true)) { ninja._x+=1; } while (_root.wall.hitTest(ninja._x, ninja._y-5, true)) { ninja._y+=1; } while (_root.wall.hitTest(ninja._x+5, ninja._y, true)) { ninja._x-=1; } while (_root.wall.hitTest(ninja._x, ninja._y+4, true)) { ninja._y-=1; } }

) Your Reply...