Gamasutra: The Art & Business of Making Gamesspacer
Games Demystified: Portal
View All     RSS
February 21, 2019
arrowPress Releases
February 21, 2019
Games Press
View All     RSS







If you enjoy reading this site, you might also want to check out these UBM Tech sites:


 

Games Demystified: Portal


August 26, 2008 Article Start Previous Page 2 of 3 Next
 

In order to break this down we will visit our old friend velocity, which is a vector. A vector is a magnitude coupled with a direction. Velocity is a vector whose magnitude is representative of speed. When the player collides with a portal we can extract the speed component of our velocity and redirect it to form a new velocity vector.

Now what term from the last column do we remember most of all? Those who remembered "surface normal" get a pat on the back along with a cookie. When a portal is applied to a wall, floor, or ramp in the game, the surface normal of the surface is communicated to the portal inhabiting it.

We then take the velocity we entered a portal with, and break it down into components. To do this we multiply by the surface normals of the exit portal.

In the end, Portal uses the traditional teleportation mechanic with a velocity and orientation change. Here's a simple code snippet, again written in Blitz3D, which is an excellent tool for quick prototyping like this.

;====== UPDATE PLAYER PHYSICS ======

Function updatePlayerPhysics()

player.playerClass = Object.playerClass( localPlayer )

AlignToVector( player\skeleton, 0, 1, 0, 2, 0.05 )

portalCollision = EntityCollided( player\skeleton, PORTALSTATIC )
If ( portalCollision <> 0 And portalOpen() )

EntityType( player\skeleton, STATIC )

For portal.portalClass = Each portalClass
If portal\entrance <> portalCollision Then Exit
Next

PositionEntity( player\skeleton, EntityX( portal\entrance ), EntityY( portal\entrance ), EntityZ( portal\entrance ) )

velocity# = Sqr( player\vX# ^ 2 + player\vY# ^ 2 + player\vZ# ^ 2 )

player\vX# = portal\nX# * velocity# * 1.2
player\vY# = portal\nY# * velocity# * 1.2
player\vZ# = portal\nZ# * velocity# * 1.2

RotateEntity( player\skeleton, VectorPitch( portal\nX#, portal\nY#, portal\nZ# ), EntityYaw( portal\entrance ) + 180 - ( EntityYaw( portalCollision ) - EntityYaw( player\skeleton ) ), 0 )
TranslateEntity( player\skeleton, 10 * portal\nX#, 10 * portal\nY#, 10 * portal\nZ# )

EntityType( player\skeleton, DYNAMIC )

CaptureWorld()
UpdateWorld()
RenderWorld( 1 )

Else

If ( EntityCollided( player\skeleton, STATIC ) )
player\vX# = 0
player\vZ# = 0
If ( CollisionNY( player\skeleton, 1 ) > 0.5 )
player\vY# = 0
MoveEntity( player\skeleton, player\mX#, 0, player\mZ# )
player\jumpTimer = MilliSecs()
EndIf
Else
player\vX# = player\vX#
player\vY# = player\vY# - 1
player\vZ# = player\vZ#
TranslateEntity( player\skeleton, player\vX#, player\vY#, player\vZ# )
MoveEntity( player\skeleton, player\mX#, 0, player\mZ# )
EndIf

If player\jumpTimer + 250 > MilliSecs() Then player\vY# = player\vY# + player\mY#

EndIf

End Function

;======


Article Start Previous Page 2 of 3 Next

Related Jobs

Sucker Punch Productions
Sucker Punch Productions — Bellevue, Washington, United States
[02.20.19]

Visual Effects (VFX) Artist
Wizards of the Coast
Wizards of the Coast — Renton, Washington, United States
[02.20.19]

Sr Software Engineer
Wizards of the Coast
Wizards of the Coast — Renton, Washington, United States
[02.20.19]

Lead Software Engineer
Wizards of the Coast
Wizards of the Coast — Renton, Washington, United States
[02.20.19]

Senior Software Engineering Lead





Loading Comments

loader image