Gamasutra is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Gamasutra: The Art & Business of Making Gamesspacer
Games Demystified: Portal
arrowPress Releases
June 2, 2020
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

Question
Question — Remote, California, United States
[05.30.20]

Senior Gameplay Engineer (Unreal Engine, Work from Home)
Question
Question — Remote, California, United States
[05.30.20]

Senior Network Engineer (Unreal Engine, Work from Home)
Remedy Entertainment
Remedy Entertainment — Espoo, Finland
[05.29.20]

Senior Programmer
Remedy Entertainment
Remedy Entertainment — Espoo, Finland
[05.29.20]

Senior Rigging Artist





Loading Comments

loader image