Originally posted as answers in two other threads.
Simple follow camera with smooth camera panning.
+ Code Snippettype tPlayer
objId
moveSpeed as float
turnSpeed as float
endtype
type tCamera
dummyId
distance as float
height as float
lookHeight as float
smoothing as float
endtype
// display
SetWindowSize(1280, 720, 0)
SetVirtualResolution(1280, 720)
SetSyncRate(0, 1)
UseNewDefaultFonts(1)
// make player
Player as tPlayer
Player.objId = CreateObjectBox(0.5, 2.0, 0.4)
Player.moveSpeed = 2.0
Player.turnSpeed = 90.0
MoveObjectLocalY(Player.objId, 1.0)
FixObjectPivot(Player.objId)
// make camera
Camera as tCamera
Camera.dummyId = CreateObjectBox(1,1,1)
Camera.distance = 5.0
Camera.height = 2.0
Camera.lookHeight = 1.8
Camera.smoothing = 0.1 // this should be set between 0 and 1
SetObjectVisible(Camera.dummyId, 0)
// make ground
oGround = CreateObjectPlane(20, 20)
SetObjectColor(oGround, 64, 128, 64, 255)
RotateObjectGlobalX(oGround, 90)
FixObjectPivot(oGround)
do
delta# = GetFrameTime()
HandlePlayer(Player, delta#)
HandleCamera(Camera, Player.objId, delta#)
print("Move with WASD")
sync()
loop
function HandlePlayer(player ref as tPlayer, delta as float)
// handle rotation
turn# = (GetRawKeyState(68) - GetRawKeyState(65)) * player.turnSpeed * delta
RotateObjectGlobalY(player.objId, turn#)
// handle movement
move# = (GetRawKeyState(87) - GetRawKeyState(83)) * player.moveSpeed * delta
MoveObjectLocalZ(player.objId, move#)
endfunction
function HandleCamera(camera ref as tCamera, targetObject, delta as float)
// set camera dummy to target position
SetObjectPosition(camera.dummyId, GetObjectX(targetObject), GetObjectY(targetObject), GetObjectZ(targetObject))
// lerp the camera dummy y rotation smoothly to target y rotation.
// the 1.0 - pow(smoothing, delta) formula creates framerate indepenence
ylerp# = LerpAngle(GetObjectAngleY(camera.dummyId), GetObjectAngleY(targetObject), 1.0 - pow(camera.smoothing, delta))
SetObjectRotation(camera.dummyId, 0, ylerp#, 0)
// move camera dummy back by distance and up by height
MoveObjectLocalZ(camera.dummyId, -camera.distance)
MoveObjectLocalY(camera.dummyId, camera.height)
// position camera at dummy
SetCameraPosition(1, GetObjectX(camera.dummyId), GetObjectY(camera.dummyId), GetObjectZ(camera.dummyId))
// point camera at target + lookHeight
SetCameraLookAt(1, GetObjectX(targetObject), GetObjectY(targetObject) + camera.lookHeight, GetObjectZ(targetObject), 0)
endfunction
// Lerp between two angles, taking shortest path
function LerpAngle(a as float, b as float, t as float)
if abs(b-a) > 180
if b > a
a = a + 360
else
b = b + 360
endif
endif
l# = a + (b-a) * t
endfunction l#
Simple orbit camera with basic camera collision
+ Code Snippettype tPlayer
objId
moveSpeed as float
endtype
type tCamera
distance as float
currentPitch as float
pitchRange as float
targetHeightOffset as float
collisionRadius as float
mouseSensitivity as float
endtype
// mouse movement vars
global gMouseDeltaX as float
global gMouseDeltaY as float
// create player
Player as tPlayer
Player.objId = CreateObjectBox(0.5,2.0,0.4)
Player.moveSpeed = 4.0
SetObjectPosition(Player.objId, 0, 1.0, 0)
FixObjectPivot(Player.objId)
SetObjectCollisionMode(Player.objId, 0)
// create camera
Camera as tCamera
Camera.distance = 4.0
Camera.pitchRange = 80.0
Camera.targetHeightOffset = 1.8
Camera.collisionRadius = 0.25
Camera.mouseSensitivity = 0.2
// create ground
oGround = CreateObjectPlane(30, 30)
SetObjectColor(oGround, 64, 128, 64, 255)
RotateObjectGlobalX(oGround,90)
FixObjectPivot(oGround)
// create some random boxes to test camera collision
for i = 0 to 10
height# = random(1,2)
b = CreateObjectBox(1, height#, 1)
SetObjectColor(b, 128, 64, 64, 255)
SetObjectPosition(b, random(0,20) - 10, height# / 2, random(0, 20) - 10)
next i
// display
SetWindowSize(1280,720,0)
SetVirtualResolution(1280,720)
SetSyncRate(60,1)
UseNewDefaultFonts(1)
// other setup
SetRawMouseVisible(0)
SetCameraRange(1,0.01,1000)
// main loop
while not GetRawKeyState(27)
delta# = GetFrameTime()
// calculate mouse delta
gMouseDeltaX = GetRawMouseX() - gMouseDeltaX
gMouseDeltaY = GetRawMouseY() - gMouseDeltaY
HandlePlayerMovement(Player, delta#)
HandleCamera(Camera, Player.objId, delta#)
HandlePlayerRotation(Player, delta#)
// re-center the mouse
SetRawMousePosition(GetVirtualWidth()/2, GetVirtualHeight()/2)
gMouseDeltaX = GetRawMouseX()
gMouseDeltaY = GetRawMouseY()
print("Move with WASD")
print("Mouse controls the camera")
sync()
endwhile
function HandlePlayerMovement(player ref as tPlayer, delta as float)
moveV# = GetRawKeyState(87) - GetRawKeyState(83)
moveH# = GetRawKeyState(68) - GetRawKeyState(65)
// normalize the movement vector if needed,
// so that speed is consistent in all directions
mag# = sqrt(moveV# * moveV# + moveH# * moveH#)
if mag# > 1.0
moveV# = moveV# / mag#
moveH# = moveH# / mag#
endif
MoveObjectLocalZ(player.objId, moveV# * player.moveSpeed * delta)
MoveObjectLocalX(player.objId, moveH# * player.moveSpeed * delta)
endfunction
function HandlePlayerRotation(player ref as tPlayer, delta as float)
// get camera forward vector on XZ plane
cOldX# = GetCameraX(1)
cOldY# = GetCameraY(1)
cOldZ# = GetCameraZ(1)
MoveCameraLocalZ(1,1)
cForwardX# = GetCameraX(1) - cOldX#
cForwardZ# = GetCameraZ(1) - cOldZ#
SetCameraPosition(1, cOldX#, cOldY#, cOldZ#)
// rotate player to camera orientation
SetObjectLookAt(player.objId, GetObjectX(player.objId) + cForwardX#, GetObjectY(player.objId), GetObjectZ(player.objId) + cForwardZ#, 0)
endfunction
function HandleCamera(camera ref as tCamera, targetObject, delta as float)
// store the target position
tx# = GetObjectX(targetObject)
ty# = GetObjectY(targetObject) + camera.targetHeightOffset
tz# = GetObjectZ(targetObject)
// position camera at target
SetCameraPosition(1, tx#, ty#, tz#)
// rotate camera on Y axis with mouse X
SetCameraRotation(1, 0, GetCameraAngleY(1) + gMouseDeltaX * camera.mouseSensitivity, 0)
// rotate camera on X axis with mouse Y
camera.currentPitch = camera.currentPitch + gMouseDeltaY * camera.mouseSensitivity
camera.currentPitch = ClampFloat(camera.currentPitch, -camera.pitchRange, camera.pitchRange)
RotateCameraLocalX(1, camera.currentPitch)
// move camera back by distance
MoveCameraLocalZ(1, -camera.distance)
// detect camera collision and move camera forward if needed
hit = ObjectSphereCast(0, tx#, ty#, tz#, GetCameraX(1), GetCameraY(1), GetCameraZ(1), camera.collisionRadius)
if hit
SetCameraPosition(1, GetObjectRayCastX(0), GetObjectRayCastY(0), GetObjectRayCastZ(0))
endif
endfunction
function ClampFloat(in as float, min as float, max as float)
if in < min then exitfunction min
if in > max then exitfunction max
endfunction in