Petr Schreiber
22-09-2021, 20:02
Psychonauts 2 is a visual gem, one of those FEW games you play for a while on console aiming to relax, inspiring you to get back to the keyboard to recreate some effect from your code.
This is a little tribute to the broken hydrant fountain early in the game :)
uses "tbgl"
randomize timer
type FountainStream
turn as Single
length as Long
offset as Long
phase as single
function Reinvent(maxPhase as single)
me.turn = rnd(0, 359)
me.length = rnd(5, 30)
me.offset = rnd(me.length * 0.5, me.length * 0.8)
me.phase = rndf(0,maxPhase)
end function
function Render()
long i
single curlTurn = 180/(me.length - me.offset)
single cubeSize
tbgl_pushMatrix
tbgl_rotate me.turn, 0, 1, 0
tbgl_translate 0, 0, 2
for i = 1 to me.length * iif(me.phase*2 > 1, 1, me.phase*2)
cubeSize = cos(i/(me.length*me.phase)*m_pi/2)
tbgl_pushColor 64 * me.phase, 128 * me.phase, 255 * me.phase
tbgl_box(cubeSize, cubeSize, cubeSize)
tbgl_popColor
tbgl_translate 0, 1.5+me.phase/10, 0
if i > me.offset then tbgl_rotate curlTurn, 1, 0, 0
next
tbgl_popMatrix
end function
end type
function tbMain()
double frameRate
dWord hWnd = tbgl_createWindowEx("Psychonauts 2 inspired fountain - press ESC to quit", 720, 720, 32, %TBGL_WS_WINDOWED)
tbgl_showWindow
' -- Initialize lighting
tbgl_useLighting(%TRUE)
tbgl_useLightSource(%GL_LIGHT0, %TRUE)
tbgl_setLightParameter(%GL_LIGHT0, %TBGL_LIGHT_POSITION, 15, 10, 15, 1)
%NUM_FOUNTAINS = 16
dim i as long
dim f(%NUM_FOUNTAINS) as FountainStream
for i = 1 to %NUM_FOUNTAINS
f(i).Reinvent(0.5)
next
' -- Main loop
while tbgl_isWindow(hWnd)
frameRate = tbgl_getFrameRate
tbgl_clearFrame
tbgl_camera(50, 50, 50, 0, 20, 0)
tbgl_rotate timer*45, 0, 1, 0
for i = 1 to %NUM_FOUNTAINS
f(i).phase += 1/frameRate
if f(i).phase > 0.999 then
f(i).Reinvent(0.2)
end if
f(i).Render()
next
tbgl_drawFrame
' -- ESCAPE key to exit application
if tbgl_getWindowKeyState(hWnd, %VK_ESCAPE) then exit while
wend
tbgl_destroyWindow
end function
Petr
This is a little tribute to the broken hydrant fountain early in the game :)
uses "tbgl"
randomize timer
type FountainStream
turn as Single
length as Long
offset as Long
phase as single
function Reinvent(maxPhase as single)
me.turn = rnd(0, 359)
me.length = rnd(5, 30)
me.offset = rnd(me.length * 0.5, me.length * 0.8)
me.phase = rndf(0,maxPhase)
end function
function Render()
long i
single curlTurn = 180/(me.length - me.offset)
single cubeSize
tbgl_pushMatrix
tbgl_rotate me.turn, 0, 1, 0
tbgl_translate 0, 0, 2
for i = 1 to me.length * iif(me.phase*2 > 1, 1, me.phase*2)
cubeSize = cos(i/(me.length*me.phase)*m_pi/2)
tbgl_pushColor 64 * me.phase, 128 * me.phase, 255 * me.phase
tbgl_box(cubeSize, cubeSize, cubeSize)
tbgl_popColor
tbgl_translate 0, 1.5+me.phase/10, 0
if i > me.offset then tbgl_rotate curlTurn, 1, 0, 0
next
tbgl_popMatrix
end function
end type
function tbMain()
double frameRate
dWord hWnd = tbgl_createWindowEx("Psychonauts 2 inspired fountain - press ESC to quit", 720, 720, 32, %TBGL_WS_WINDOWED)
tbgl_showWindow
' -- Initialize lighting
tbgl_useLighting(%TRUE)
tbgl_useLightSource(%GL_LIGHT0, %TRUE)
tbgl_setLightParameter(%GL_LIGHT0, %TBGL_LIGHT_POSITION, 15, 10, 15, 1)
%NUM_FOUNTAINS = 16
dim i as long
dim f(%NUM_FOUNTAINS) as FountainStream
for i = 1 to %NUM_FOUNTAINS
f(i).Reinvent(0.5)
next
' -- Main loop
while tbgl_isWindow(hWnd)
frameRate = tbgl_getFrameRate
tbgl_clearFrame
tbgl_camera(50, 50, 50, 0, 20, 0)
tbgl_rotate timer*45, 0, 1, 0
for i = 1 to %NUM_FOUNTAINS
f(i).phase += 1/frameRate
if f(i).phase > 0.999 then
f(i).Reinvent(0.2)
end if
f(i).Render()
next
tbgl_drawFrame
' -- ESCAPE key to exit application
if tbgl_getWindowKeyState(hWnd, %VK_ESCAPE) then exit while
wend
tbgl_destroyWindow
end function
Petr