|
The component we'll be focusing on is the updatePhysics() function - here's a code sample from that section:
;====== UPDATE PHYSICS =======================================
Function updatePhysics()
player.playerClass = Object.playerClass( localPlayer )
planetoid.planetoidClass = Object.planetoidClass( player\planetoid )
LinePick( EntityX( player\character ), EntityY( player\character ), EntityZ( player\character ), EntityX( planetoid\mesh ) - EntityX( player\character ), EntityY( planetoid\mesh ) - EntityY( player\character ), EntityZ( planetoid\mesh ) - EntityZ( player\character ) )
AlignToVector( player\character,
PickedNX(), PickedNY(), PickedNZ(), 2, 1 )
player\nX# = PickedNX()
player\nY# = PickedNY()
player\nZ# = PickedNZ()
If (EntityCollided( player\character, STATIC ) )
player\jumpTimer = MilliSecs()
player\vX# = 0
player\vY# = 0
player\vZ# = 0
Else
player\vX# = player\vX# - PickedNX()
player\vY# = player\vY# - PickedNY()
player\vZ# = player\vZ# - PickedNZ()
TranslateEntity(
player\character, player\vX#, player\vY#, player\vZ# )
EndIf
distance = EntityDistance( player\character, planetoid \mesh )
For planetoid.planetoidClass = Each planetoidClass
If ( EntityDistance(
player\character, planetoid\mesh ) < distance ) Then player\planetoid
= Handle( planetoid )
Next
End Function
;=============================================================
The first two lines in this function retrieve our player and the planetoid he inhabits. This sets us up to apply the calculations, which will allow gravity to occur between them. Next we cast a ray from our character's local center to the planetoids local center.
This call requires 6 parameters. The first 3 are the starting point of the ray and the last 3 are the distance along the (x, y, z) axes to cast our ray. We don't use the ray itself to calculate gravity. Instead we only use the ray to find a polygon between the player and the planetoid and extract its surface normal.

The first thing we do with the surface normal is character alignment. The call to AlignToVector() has 6 parameters; the object to be aligned, the vector to align to, the axis to align along, and the speed at which we interpolate or snap to this alignment.
|
PS Next time, set your example NOT at 640x480 fullscreen, or it will crash for users without a prehistoric monitor supporting that low resolution, I had to download the source and recompile it running on a window to see your stuff!
If it can work in Shockwave3D, it can work anywhere! ;-)
Now check out Serious Sam's gravity handling. They did it using zones (defined in the level editor) and it works very well. It is also easier to implement well since you don't need to worry about any smoothing. I suspect that SMG may well have used a hybrid of these two approaches.
This will help us to acquire some more basic knowledge about gravity and it's use on games, which are very demanding right now.
Keep up the good work, and I want to read the next ones.
The only problem I ran into using this method was that snapping an object instantly to a new surface normal sometimes caused its ray to hit the polygon that it was previously using to calculate its up vector (when moving slowly along a "downward" slope, that is). I ended up scrapping this method because of the jittery back and forth effect that it was causing, eventually spiraling the object out of control into oblivion... maybe if I had LERPed the rotation slowly as mentioned in this article, I wouldn't have had the problems that I did.
Oh well... live and learn. Good article! :)
I love mario brother, I used to play all day when i was a kid...missed them :)