# QB CULT MAGAZINEIssue #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.

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.

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