If you’ve been playing around with Popfly Game Creator long enough, you’ve probably noticed that if actors get going fast enough, they can sometimes manage to fly right through a wall.  There are some things you can do to get around this like making your walls extra thick, or making sure your actors go slow, but I’ll be the first to admit that this can get kind of annoying.

The issue is that with the alpha release of PGC, we only check for collisions once during each frame.  If your actor is moving so fast that one frame it’s on the left side of the wall and on the next it’s on the right, we will never know that in between it should have collided.  We have to actually catch the actors colliding during a frame in order to realize they collided and then resolve the collision.  This was due to both time limitations and the performance limitations of running on the browser’s JavaScript engine (we could probably do it, but given our short timeframe before releasing the Alpha, we chose to go with the “good enough” method you see in the Alpha) since doing continuous collision checking is both harder to code and less performant [yes, I know this is not a word that means fast – but dude, English is a living language] due to all the math.

We’ll probably do something about this down the road sometime after Silverlight 2.0 RTMs, we begin requiring it and can begin using C# (no promises as usual).  But in the meantime, I figured I’d post some quick custom code which you can help dealing with this by capping the speed of your actor.

You might think that you can just use the “Max Speed” value in the motion dialog and be done, however there are many cases where this isn’t good enough.  While Max Speed does work, it only concerns itself with the current behavior.  What Max Speed does under the covers is calculate the amount of acceleration to apply such that the contribution from that behavior will reach terminal velocity at the value you enter.  If you have two behaviors, both with a Max Speed of 100, and they both are pushing in the same direction, your max speed will actually be 200.  While that example is a little contrived, there are many times, especially in physics based games like Badly Built Wall, that over time, the contribution from various behaviors and collisions will add up to making you go really fast.

How do you overcome this?  Why with a custom behavior of course!  Adding a custom behavior with the following code should do the trick:

var maxSpeed = 200;
var maxSpeedSquared = maxSpeed * maxSpeed;

var velX = this.GetValue("XVelocity");
var velY = this.GetValue("YVelocity");

var velocity = {X: velX, Y: velY};
var speedSquared = Vector2.MagnitudeSquared(velocity);

if (speedSquared > maxSpeedSquared)
{

var normalizedVelocity = Vector2.Normalize(velocity);

this.SetValue("XVelocity", normalizedVelocity.X * maxSpeed);

this.SetValue("YVelocity", normalizedVelocity.Y * maxSpeed);
}

Add this as a the last behavior to your actor and set its event to Timer->Every Frame.  What this code does is check your speed every frame after all your motion behaviors have contributed to it and if it exceeds the value you set for maxSpeed at the top, resets your velocity to point in the same direction as before, but to go only as fast as maxSpeed.  You can set maxSpeed to a whatever value you want, and as long as that value is low enough that your actor can’t pass through the thickness of your walls in a single frame, you should avoid any unexpected jumping through walls. [Note:  All the *Squared values are used as a programmer’s trick to avoid the square root operation (Math.sqrt) which is fairly costly in terms of processing time.] For even simpler code, check out the following from Badly Built Wall:

var velX = this.GetValue("XVelocity");
var velY = this.GetValue("YVelocity");

if (velX > 201) this.SetValue("XVelocity", 200);
if (velY > 201) this.SetValue("YVelocity", 200);

This code doesn't actually cap the max speed, but rather the velocity in the vertical and horizontal directions. This is subtly different in that it means you could actually end up going 200 in the horizontal and 200 in the vertical directions, which, if we remember our distance formula means we end up going sqrt(200^2 + 200^2) altogether or about 283 pixels / second total.  Basically, it means you can go faster in the diagonals than you can just straight up and down or left and right.  As you can probably tell it’s quite a bit less complicated (and therefore faster) and even though it’s less general can actually be desirable in games like Badly Built Wall where you are colliding mostly against axis aligned rectangles (their sides are horizontal or vertical rather than at an angle).

Happy creating!