QB CULT MAGAZINE
Issue #7 - December 2000

Creating a Physics-Based Scroller

By QbProgger <qbprogger@tekscode.com>

By now, all of you have seen pixel-based, pixel-by-tile-based, tile-by-tile-based, and even screen-by-screen based engines in QB RPG's, but have you ever seen something that was physics-based?

Before I continue, let's define a physics-based engine:

Physics-based engine
Engine based on Velocity, Acceleration, Friction, and other environmental variables instead of a uniform speed environment.

After looking at this, you're probably thinking: "Huh?" Well, with a physics-based engine, instead of moving pixels at a time, you can move in fractions of pixels at a time.

If you haven't seen Bwong engine already, download it from here: <http://rbroomfield.hypermart.net/bwong15c.zip> [Editor's note: Bwong 15c is included in the downloadable version of this issue.]

Bwong engine is an example of a physics-based engine. If you notice, the character isn't moving exactly in pixels and will sometimes "slide" a little bit when turning a corner. This is achieved via fixed point math. Fixed point math is integer math used to simulate floating point numbers. Instead of numbers like 1.335315, numbers can only be in 1/x increments. For instance, 63.53153 can't exist, but 63 + 12/128 can. If you don't entirely understand fixed point math, look it up online before continuing with this column.

Now we're ready to start with the engine!

This is what an object looks like in a physics-based engine:

Type OBJECT
    X AS LONG
    Y AS LONG
    VelocityX AS INTEGER
    VelocityY AS INTEGER
    AccelX AS INTEGER
    AccelY AS INTEGER
    MaximumVelocityX AS INTEGER
    MaximumVelocityY AS INTEGER
    WalkingSpeedX AS INTEGER
    WalkingSpeedY AS INTEGER
END TYPE


Dim PointScale as integer
Dim ObjectBoy as OBJECT


PointScale=128

ObjectBoy.AccelX=ObjectBoy.WalkingSpeedX
ObjectBoy.AccelY=ObjectBoy.WalkingSpeedY
ObjectBoy.X=3593
ObjectBoy.Y=3091
ObjectBoy.MaximumVelocityX=PointScale*2  'This makes the maximum velocity 2 pixels
ObjectBoy.MaximumVelocityY=PointScale*2  'This makes the maximum velocity 2 pixels

Now, you're saying "hey wait a second, if my object can move in 1/128th pixel movements, doesn't that make my engine slower?

Well actually, it doesn't matter what PointScale you use, because the ultimate speed is the same. You could use 4096 as your pointscale and be accurate up to 1/4096th of a pixel without any slowdown! The higher your PointScale, the more accurate your engine will be.

Now, to display your object, all you do is this:

X=(ObjectBoy.X\PointScale)-(CameraX\PointScale)      'Remember that your camera can move in subpixels too!!!
Y=(ObjectBoy.Y\PointScale)-(CameraY\PointScale)

Put (X,Y),ObjectBoySprite 

To find out what tile your ObjectBoy is on, you just do:

TileX=ObjectBoy.X\(PointScale*SizeOfTilesInPixels)
TileY=ObjectBoy.Y\(PointScale*SizeOfTilesInPixels)

Remember to check for all 4 corners of your object (but you already knew that). IF you're going for pixel-accuracy, remember that each pixel is now PointScale X PointScale sub-pixels. You should already know how to implement velocity and acceleration, but if you need further help, see the example below.

'Update Velocity
ObjectBoy.VelocityX=ObjectBoy.VelocityX+ObjectBoy.AccelX
ObjectBoy.VelocityY=ObjectBoy.VelocityY+ObjectBoy.AccelY

'Modify velocity for friction
ObjectBoy.VelocityX=ObjectBoy.VelocityX*FrictionX!
ObjectBoy.VelocityY=ObjectBoy.VelocityY*FrictionY!


'Make sure you're not going toooo fast.
If ObjectBoy.VelocityX>ObjectBoy.MaximumVelocityX then ObjectBoy.VelocityX=ObjectBoy.MaximumVelocityX
If ObjectBoy.VelocityY>ObjectBoy.MaximumVelocityY then ObjectBoy.VelocityY=ObjectBoy.MaximumVelocityY
If ObjectBoy.VelocityX<-ObjectBoy.MaximumVelocityX then ObjectBoy.VelocityX=-ObjectBoy.MaximumVelocityX
If ObjectBoy.VelocityY<-ObjectBoy.MaximumVelocityY then ObjectBoy.VelocityY=-ObjectBoy.MaximumVelocityY


'Update player
ObjectBoy.X=ObjectBoy.X+ObjectBoy.VelocityX
ObjectBoy.Y=ObjectBoy.Y+ObjectBoy.VelocityY

(***REMEMBER TO UPDATE YOUR COLLISION DETECTION ROUTINE WITH POINTSCALE ACCURACY!***)

That's it! Your engines will now have INSANE accuracy with no slowdown or floating point usage! Show off your engine with slippery roads (no friction) or make muddy paths (high friction). This looks to be the next big tactic with QB engines, I hope you've learned something new today :)

-QbProgger