Posted: 18th Dec 2021 4:59
Requires attached Heightmap (or any heightmap):
+ Code Snippet
// Move/Strafe + Mouselook
// By: Virtual Nomad
// show all errors
SetErrorMode(2)

// set window properties
SetWindowSize( 1280,720, 0 )
SetWindowAllowResize( 1 )
MaximizeWindow()

// set display properties
SetVirtualResolution( 1280,720)
SetOrientationAllowed( 1, 1, 1, 1 )
SetSyncRate( 30, 0 ) 
SetScissor( 0,0,0,0 )
UseNewDefaultFonts( 1 ) 

SetSkyBoxVisible(1)
	SetSkyBoxSunColor( 0,192,255 )
	SetSkyBoxSkyColor(0,0,0)
	SetSkyBoxHorizonColor(255,128,0)

terrain = CreateObjectFromHeightMap("YellowStone.png", 1024,192,1024,4,1)
	SetObjectImage(terrain, LoadImage("YellowStone.png"),0 )
	SetObjectColorEmissive(terrain, 128,64,0)
	SetObjectCollisionMode(terrain,1)

cx# = 512.0	:	cz# = 512.0
	ray = ObjectRayCast(terrain,cx#,200,cz#,cx#,-16,cz#)
	cy# = GetObjectRayCastY(0)
	SetCameraPosition(1,cx#,cy#+10,cz#)
	SetCameraRotation(1,0,0,0)

SetRawMousePosition(640,360)
SetRawMouseVisible(0)

Sensitivity# = 0.05

do
    If GetRawKeyState(27) then Exit

	MMX# = GetPointerX()-640.0	:	MMY# = GetPointerY()-360.0
	CAMYA# = GetCameraAngleY(1)

	SetCameraRotation(1, GetCameraAngleX(1)+MMY#*Sensitivity#, CAMYA# + MMX#*Sensitivity#, 0)

	angle# = GetCameraAngleY(1)
	
	if GetJoystickX() <> 0.0  or GetJoystickY() <> 0.0
		cx# = cx# + SIN(angle#)* -GetJoystickY()*5.0 //Move
		cz# = cz# + COS(angle#)* -GetJoystickY()*5.0

		cx# = cx# + SIN(angle#+90)* GetJoystickX()*5.0 //Strafe
		cz# = cz# + COS(angle#+90)* GetJoystickX()*5.0
		
		ray = ObjectRayCast(terrain,cx#,200,cz#,cx#,-16,cz#)
		cy# = GetObjectRayCastY(0)
		SetCameraPosition(1,cx#,cy#+10,cz#)
	Endif

    Print("[WASD] - Move/Strafe | [MouseLook]")
    
	SetRawMousePosition(640,360)
    Sync()
loop


for a nice terrain example with vehicle physics, see ando's offering HERE
Posted: 7th Nov 2022 5:34
This uses two objects. A box (camera) and a sphere (lookat). It attaches the sphere to the box and the moves the sphere along the z axis -5 units.
Think of the box as the car cabin and the sphere as the bonnet.

Then it positions the box at the starting point.

In the loop;
(rotation)
1. Depending on the x position of the mouse it will rotate the camera object left or right (Around the Y axis)
2. Depending on the y position of the mouse it will rotate the camera object up or down (Around the X axis)

(movement)
3. Depending on the state of the UP/DOWN/RIGHT/LEFT keys it will move the camera object
4. It gets the height at cameraX and cameraZ from the heightmap
5. it sets the camera to that position and makes the camera "look at" the lookat object


+ Code Snippet
// Move/Strafe + Mouselook
// By: Virtual Nomad
// show all errors


#constant KEY_LEFT=37
#constant KEY_UP=38
#constant KEY_RIGHT=39
#constant KEY_DOWN=40


SetErrorMode(2)

// set window properties
SetWindowSize( 1280,720, 0 )
SetWindowAllowResize( 1 )
MaximizeWindow()

// set display properties
SetVirtualResolution( 1280,720)
SetOrientationAllowed( 1, 1, 1, 1 )
SetSyncRate( 30, 0 ) 
SetScissor( 0,0,0,0 )
UseNewDefaultFonts( 1 ) 

SetSkyBoxVisible(1)
	SetSkyBoxSunColor( 0,192,255 )
	SetSkyBoxSkyColor(0,0,0)
	SetSkyBoxHorizonColor(255,128,0)

terrain = CreateObjectFromHeightMap("YellowStone.png", 1024,192,1024,4,1)
	SetObjectImage(terrain, LoadImage("YellowStone.png"),0 )
	SetObjectColorEmissive(terrain, 128,64,0)
	SetObjectCollisionMode(terrain,1)

cx# = 512.0	:	cz# = 512.0

SetRawMousePosition(640,360)
SetRawMouseVisible(0)

Sensitivity# = 0.05

Scale# = 0.5

Step# = 2

camera = CreateObjectBox(1,1,1)
SetObjectVisible(camera, 0)
lookat = CreateObjectSphere(0.2,8, 8)
SetObjectColor(lookat, 0xff, 0, 0, 0xff)

FixObjectToObject(lookat, camera)

MoveObjectLocalZ(lookat, -5)

SetObjectPosition(camera, cx#, 0, cz#)

do
    If GetRawKeyState(27) then Exit

//~	MMX# = GetPointerX()-640.0	:	MMY# = GetPointerY()-360.0
//~	
//~	CAMYA# = GetCameraAngleY(1)

//~	SetCameraRotation(1, GetCameraAngleX(1)+MMY#*Sensitivity#, CAMYA# + MMX#*Sensitivity#, 0)

//~	angle# = GetCameraAngleY(1)
	
//~	if GetJoystickX() <> 0.0  or GetJoystickY() <> 0.0
//~		cx# = cx# + SIN(angle#)* -GetJoystickY()*5.0 //Move
//~		cz# = cz# + COS(angle#)* -GetJoystickY()*5.0

//~		cx# = cx# + SIN(angle#+90)* GetJoystickX()*5.0 //Strafe
//~		cz# = cz# + COS(angle#+90)* GetJoystickX()*5.0
//~		
//~		ray = ObjectRayCast(terrain,cx#,200,cz#,cx#,-16,cz#)
//~		cy# = GetObjectRayCastY(0)
//~		SetCameraPosition(1,cx#,cy#+10,cz#)
//~	Endif

	mx# = GetPointerX()
	my# = GetPointerY()
	
	ax# = ((GetVirtualWidth() / 2) - mx#) * -1
	ay# = (GetVirtualheight() / 2) - my#
	
	SetObjectRotation(camera, ay# * scale#, ax# * scale#, 0)

	cy# = GetObjectHeightMapHeight(terrain, GetObjectX(camera), GetObjectZ(camera))

	SetObjectPosition(camera, GetObjectX(camera), cy# + 1, GetObjectZ(camera))
	SetCameraPosition(1, GetObjectX(camera), GetObjectY(camera), GetObjectZ(camera))
	SetCameraLookAt(1, GetObjectWorldX(lookat), GetObjectWorldY(lookat), GetObjectWorldZ(lookat), 0)
	
	if GetRawKeyState(KEY_UP)
		MoveObjectLocalZ(camera, -Step#)
	endif
	
	if GetRawKeyState(KEY_DOWN)
		MoveObjectLocalZ(camera, Step#)
	endif
	
	if GetRawKeyState(KEY_RIGHT)
		MoveObjectLocalX(camera, -Step#)
	endif

	
	if GetRawKeyState(KEY_LEFT)
		MoveObjectLocalX(camera, Step#)
	endif
			

    Print("[UP/DOWN/RIGHT/LEFT] - Move/Strafe | [MouseLook]")
    
    Sync()
loop

Posted: 21st Apr 2023 3:00
now with collectables!
+ Code Snippet
// Move/Strafe + Mouselook
// By: Virtual Nomad
// show all errors
SetErrorMode(2)

// set window properties
SetWindowSize( 1280,720, 0 )
SetWindowAllowResize( 1 )
MaximizeWindow()

// set display properties
SetVirtualResolution( 1280,720)
SetOrientationAllowed( 1, 1, 1, 1 )
SetSyncRate( 30, 0 ) 
SetScissor( 0,0,0,0 )
UseNewDefaultFonts( 1 ) 

SetSkyBoxVisible(1)
	SetSkyBoxSunColor( 0,192,255 )
	SetSkyBoxSkyColor(0,0,0)
	SetSkyBoxHorizonColor(255,128,0)
	
GLOBAL Score, Terrain, Objects as Integer []
terrain = CreateObjectFromHeightMap("YellowStone.png", 1024,192,1024,4,1)
	SetObjectImage(terrain, LoadImage("YellowStone.png"),0 )
	SetObjectColorEmissive(terrain, 128,64,0)
	SetObjectCollisionMode(terrain,1)

PlaceObs(20)

cx# = 512.0	:	cz# = 512.0
	ray = ObjectRayCast(terrain,cx#,200,cz#,cx#,-16,cz#)
	cy# = GetObjectRayCastY(0)
	SetCameraPosition(1,cx#,cy#+10,cz#)
	SetCameraRotation(1,0,0,0)


SetRawMousePosition(640,360)
SetRawMouseVisible(0)

Sensitivity# = 0.05

do
    If GetRawKeyState(27) then Exit

	MMX# = GetPointerX()-640.0	:	MMY# = GetPointerY()-360.0
	CAMYA# = GetCameraAngleY(1)

	SetCameraRotation(1, GetCameraAngleX(1)+MMY#*Sensitivity#, CAMYA# + MMX#*Sensitivity#, 0)

	angle# = GetCameraAngleY(1)
	
	if GetJoystickX() <> 0.0  or GetJoystickY() <> 0.0
		cx# = cx# + SIN(angle#)* -GetJoystickY()*5.0 //Move
		cz# = cz# + COS(angle#)* -GetJoystickY()*5.0

		cx# = cx# + SIN(angle#+90)* GetJoystickX()*5.0 //Strafe
		cz# = cz# + COS(angle#+90)* GetJoystickX()*5.0
		
		ray = ObjectRayCast(terrain,cx#,200,cz#,cx#,-16,cz#)
		cy# = GetObjectRayCastY(0)
		SetCameraPosition(1,cx#,cy#+10,cz#)
	Endif

    Print("[WASD] - Move/Strafe | [MouseLook]")

    CheckHits()
    Print("Score: " + STR(Score) )
	SetRawMousePosition(640,360)
    Sync()
loop

Function CheckHits()
	X# = GetCameraX(1)	:	Z# = GetCameraZ(1)
	Y# = GetObjectHeightMapHeight(Terrain, X#, Z#)
	For x = 0 to Objects.Length
		ThisOb = Objects[x]
		If ObjectRayCast(ThisOb, X#, Y# + 100, Z#, X#, Y#, Z#)
			INC Score
			Scatter(ThisOb)
		EndIf
	next x
EndFunction

Function PlaceObs(num)
	For x = 1 to num
		ThisOb = CreateObjectBox(20,30,20)
		SetObjectCollisionMode(ThisOb,1)
		Scatter(ThisOb)
		Objects.InsertSorted(ThisOb)
	next x
EndFunction

Function Scatter(ThisOb)
	ThisX# = Random(100,924)	:	ThisZ# = Random(100,924)
	ThisY# = GetObjectHeightMapHeight(Terrain, ThisX#, ThisZ#)
	SetObjectPosition(ThisOb, ThisX#, ThisY#, ThisZ#)
EndFunction

note: standard 3D rays don't like rotated boxes in my experience; consider physics rays or at least light bullet collision.
Posted: 22nd Apr 2023 17:48
Third person setup for this snipplet

+ Code Snippet
	    MMX# = GetPointerX()-512.0	:	MMY# = GetPointerY()-384.0
	    CAMYA# = GetobjectAngleY(player)

	    SetObjectRotation(player, 0, CAMYA# + MMX#*Sensitivity#, 0)
    
	    anglea# = GetObjectAngleY(player)
	
        SetObjectRotation(player, 0, anglea#+GetJoystickX(), 0)
    
        SetRawMousePosition(512,384)
 
        angle# = GetobjectAngleY(player)
 
	    if GetJoystickX() <> 0.0 and attack=0  or GetJoystickY() <> 0.0 and attack=0 or GetRawKeyState(38) and attack=0
		if moving = 1 then cx# = cx# + SIN(angle#)* -GetJoystickY()*1.0 //Move
		if moving = 1 then cz# = cz# + COS(angle#)* -GetJoystickY()*1.0

		if moving = 2 then cx# = cx# + SIN(angle#)* -GetJoystickY()*3.0 //Run
		if moving = 2 then cz# = cz# + COS(angle#)* -GetJoystickY()*3.0

		cx# = cx# + SIN(angle#+90)* GetJoystickX()*1.0 //Strafe
		cz# = cz# + COS(angle#+90)* GetJoystickX()*1.0
		
		if moving = 1 then cx# = cx# + SIN(angle#)* GetRawKeyState(38)*1.0 //Move
		if moving = 1 then cz# = cz# + COS(angle#)* GetRawKeyState(38)*1.0
		
		if moving = 2 then cx# = cx# + SIN(angle#)* GetRawKeyState(38)*3.0 //Run
		if moving = 2 then cz# = cz# + COS(angle#)* GetRawKeyState(38)*3.0
		
		ray = ObjectRayCast(terrain,cx#,120,cz#,cx#,-16,cz#)
		cy# = GetObjectRayCastY(0)
		SetobjectPosition(player,cx#,cy#+5,cz#)
    	Endif

   		  SetCameraPosition(1,GetObjectX(player),GetObjectY(player)+13,GetObjectZ(player))
		  SetCameraRotation(1,360-(GetObjectAngleX(player)),(GetObjectAngleY(player)),360-(GetObjectAngleZ(player)))
		  MoveCameraLocalZ(1,-23)