overidon.com Central Database for Overidon Omnimedia

June 23, 2013

2D Character AI and Trace Debugging

Filed under: Programming — Tyler @ 9:16 pm
Click the image to see the code (rough)

Click the image to see the code (rough)

When designing 2-Dimensional characters in their appropriate 2D worlds, it’s easy to make dull characters that have buggy and unexciting movement patterns. My current project which originally was just going to be a simple character/inventory simulator with 2D movement has expanded into a rudimentary 2D Arcade-like action game. This new direction has added complexity to the project and it also has increased its value to me as a showcase project. As usual when the program is finished, this showcase project will have the full code available for download. In this case the program is being written in Actionscript 3.0.

One of the problems I was having with my first, “bad guy” named, “bladeSkel1” which is short for Blade Wielding Skeleton Number One, was that the skeleton didn’t move correctly. I wanted him to change direction whenever he hit a wall. At first, when he’d hit a wall, there was a chance that he would change direction…but not always. Sometimes the skeleton would get caught in the wall and then strangely walk completely off the stage. I was astonished to see all my hard work simply exit the workspace. It was as if my critter didn’t want to participate in the program anymore and wanted to leave my game!

After looking at the issue after a day of letting it sit, I realized that I needed to “trace” the problem down. By using the, “trace()” command I was able to see that the skeleton wasn’t changing his x and y location properly after hitting a wall. Instead of simply changing his velocity, the skeleton should also be redirected to an “x” coordinate which was constant if he hit the “west” or “east” borders. And if he hit the “north” or “south” borders, a new “y” coordinate needed to be implemented.

Now you might be thinking, “Why not change both the “x” and the “y” coordinates? Doesn’t the skeleton have both an X and Y location on the stage?” And you’d be quite right for asking that. But you’ll see in your own projects, that if your character is hitting a wall or border in a 2D game environment…then the character already has both an X and Y location.

So by adjusting only the X location when the horizontal borders are touched and adjusting the Y location when the vertical borders are touched…you save yourself from having to use extra dispatch events. You can simply keep the Y location as it is when the skeleton hits a horizontal border. This kind of thinking can lead to greater efficiency in coding.

The first half of the Blade Skeleton’s ai is in the picture. And here’s the second half:

// begin code snippet
bladeSkel1.x = bladeSkel1.x + _skelVx;
 bladeSkel1.y = bladeSkel1.y + _skelVy;
 // begin the test bladeskel1 ai
 {if ((southBorder.hitTestObject(bladeSkel1)) || (westBorder.hitTestObject(bladeSkel1)) 
|| (eastBorder.hitTestObject(bladeSkel1)) || (northBorder.hitTestObject(bladeSkel1)))}
 {
 if (_skelVx != 0)
 {
 trace(_skelVx);
 _skelVx = 0;
 if (bladeSkel1.x >= 350)
 {
 bladeSkel1.x = 488;
 }
 else
 {
 bladeSkel1.x = 64;
 }
 _binaryRand = Math.round(Math.random());
trace(_binaryRand);
if (_binaryRand == 1)
 {
 _skelVy = -6;
 }
 else
 {
 _skelVy = 6;
 }
 }
 else if (_skelVy != 0)
 {
 _skelVy = 0
 _binaryRand = Math.round(Math.random());
if (bladeSkel1.y >= 272)
 {
 bladeSkel1.y = 338;
 }
 else
 {
 bladeSkel1.y = 73;
 }
if (_binaryRand == 1)
 {
 _skelVx = -6;
 }
 else
 {
 _skelVx = 6;
 }
 }
 }
// End code snippet

Now you may be wondering what I’m doing with the “_binaryRand” and it is a fun subject to discuss. The _binaryRand is a private variable that creates a random decimal number between 0 and 1  and then rounds that number to either 0 or 1. The end result is a type of switch. ‘0’ means the switch is off, and ‘1’ means the switch is on. In the case of the Blade Skeleton, I’m using that variable to spice things up whenever the skeleton hits a wall.

As the skeleton hits a wall, he will change direction. But that direction will be random. The character walks like a “rook” in chess. He can’t walk diagonally according to his programming. This is evident in the code by how whenever his “_skelVx” which is short for “Blade Skeleton’s Velocity in the X Direction” is zero…then his _skelVy is always a number other than zero. Never will you see both velocities as zero (which would mean the skeleton has stopped moving) and also never would you see both velocities as numbers other than zero (that would mean the skeleton is moving diagonally).

Now to make the movement of the enemy character more exciting you can read the code in the above image. If you click on the image the code will become readable. This code creates a “timer” of sorts which makes the skeleton change directions every 100 frames or so. So when the “_skelTrav” variable reaches the number 100, then the skeleton will move in a new direction at a faster rate than normal. The fun aspect to this type of code is that it makes the enemy seem more “alive” than if it walked always at a constant rate.

I hope you enjoyed this article and I’ll keep everyone posted as more features and progress are implemented into this game which will be free to play at overidon.com

-Tyler

*SHARE*

Powered by WordPress