Ooops
November 24, 2020, 09:46:16 AM

### Author Topic: [bmx] Rogue-like 3D perspective effect  (Read 2401 times)

#### Flanker

• Jr. Member
• Posts: 41
##### [bmx] Rogue-like 3D perspective effect
« on: November 17, 2017, 11:38:28 AM »
Here is a little experiment of a perspective effect based on a 3D level data, using 2D (ASCII in the example but can be replaced with tiles). Move with keyboard arrows, zoom with mousewheel (be aware that it can be very slow when zoomed out). Idea from here : http://www.squidi.net/three/entry.php?id=251

Code: [Select]
`'------------------------------------------------------------------------------------------------------------------------------------------------------------ GRAPHICS VARConst gfxWidth:Int = 800Const gfxHeight:Int = 600Const gfxDepth:Int = 0Const gfxHertz:Int = 60'------------------------------------------------------------------------------------------------------------------------------------------------------------ GRAPHICS INITGraphics gfxWidth,gfxHeight,gfxDepth,gfxHertz'------------------------------------------------------------------------------------------------------------------------------------------------------------ LEVEL DATAGlobal levelWidth:Int = 129Global levelHeight:Int = 129Global levelDepth:Int = 16Global levelData:Int[levelWidth,levelHeight,levelDepth]' >>>>>>>>>> FILL THE LEVEL WITH A GRID PATTERNFor Local x:Int = 0 To levelWidth-1 For Local y:Int = 0 To levelHeight-1 If (x/16.0) = Int(x/16.0) Or (y/16.0) = Int(y/16.0) For Local z:Int = 0 To levelDepth-1 levelData[x,y,z] = 35 ' >>>>>>>>>> WALLS Next Else levelData[x,y,0] = 46 ' >>>>>>>>>> FLOOR EndIf NextNext'------------------------------------------------------------------------------------------------------------------------------------------------------------ "CAMERA" VARGlobal cameraX:Float = 0Global cameraY:Float = 0Global cameraZ:Float = 20 ' >>>>>>>>>> ZOOM LEVELGlobal cameraP:Float = 20 ' >>>>>>>>>> PERSPECTIVE STRENGHT'------------------------------------------------------------------------------------------------------------------------------------------------------------ FPS VARGlobal fps:Int = gfxHertzGlobal fpsTime:Int = MilliSecs()Global fpsCount:Int'############################################################################################################################################################ MAIN LOOPWhile Not KeyHit(KEY_ESCAPE) And Not AppTerminate() Cls If KeyDown(KEY_LEFT) Then cameraX = cameraX - 0.5 If KeyDown(KEY_RIGHT) Then cameraX = cameraX + 0.5 If KeyDown(KEY_UP) Then cameraY = cameraY - 0.5 If KeyDown(KEY_DOWN) Then cameraY = cameraY + 0.5 cameraZ = cameraZ + MouseZSpeed() If cameraZ < 1 Then cameraZ = 1 DrawLevel() SetColor 255,255,255 SetScale 5,5 DrawText GetFPS(),10,10 Flip WendEnd'//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// FUNCTIONS'------------------------------------------------------------------------------------------------------------------------------------------------------------ LEVEL DATAFunction GetFPS() If MilliSecs()-fpsTime > 1000 fps = fpsCount fpsCount = 0 fpsTime = MilliSecs() Else fpsCount = fpsCount + 1 EndIf Return fpsEnd Function'------------------------------------------------------------------------------------------------------------------------------------------------------------Function DrawLevel() ' >>>>>>>>>> RESTRICTING DRAWING TO VISIBLE LEVEL DATA Local minX:Int = cameraX - GraphicsWidth()/2/cameraZ Local maxX:Int = cameraX + GraphicsWidth()/2/cameraZ Local minY:Int = cameraY - GraphicsHeight()/2/cameraZ Local maxY:Int = cameraY + GraphicsHeight()/2/cameraZ If minX < 0 Then minX = 0 If maxX > levelWidth-1 Then maxX = levelWidth-1 If minY < 0 Then minY = 0 If maxY > levelHeight-1 Then maxY = levelHeight-1 ' >>>>>>>>>> DRAWING FROM BOTTOM TO TOP For Local z:Float = 0 To levelDepth-1 SetScale cameraZ/10*(1+z/20),cameraZ/10*(1+z/20) ' >>>>>>>>>> SCALE FUNCTION OF HEIGHT Local color:Int = 255-224+z*14' >>>>>>>>>> COLOR FUNCTION OF HEIGHT SetColor color,color,color For Local y:Float = minY To maxY For Local x:Float = minX To maxX If levelData[x,y,z] > 0 Then DrawText Chr(levelData[x,y,z]),ProjectX(x,z),ProjectY(y,z) Next Next NextEnd Function'------------------------------------------------------------------------------------------------------------------------------------------------------------Function ProjectX:Float(x:Float,z:Float) ' >>>>>>>>>> LEVEL X-Z PROJECTION ON SCREEN Return GraphicsWidth()/2+(x-cameraX)*cameraZ*(1+z/cameraP)End Function'------------------------------------------------------------------------------------------------------------------------------------------------------------Function ProjectY:Float(y:Float,z:Float)' >>>>>>>>>> LEVEL Y-Z PROJECTION ON SCREEN Return GraphicsHeight()/2+(y-cameraY)*cameraZ*(1+z/cameraP)End Function`
Everyone knew it was impossible, until someone who didn't know made it.

#### GW

• Full Member
• Posts: 202
##### Re: [bmx] Rogue-like 3D perspective effect
« Reply #1 on: November 17, 2017, 06:29:38 PM »
Nice!
Did you try rendering the whole map to texture once and then drawing that image 'leveldepth' times?
I think you should get a speedup, but possibly some small scaling artifacts.

#### Flanker

• Jr. Member
• Posts: 41
##### Re: [bmx] Rogue-like 3D perspective effect
« Reply #2 on: November 17, 2017, 07:41:06 PM »
You're right, this should work and it's probably faster to render. Maybe I'll try that later.
Everyone knew it was impossible, until someone who didn't know made it.