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:
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