TPS camera with mouse and collision control

Blitz3D Forums/Blitz3D Beginners Area/TPS camera with mouse and collision control

Move WSAD, jump SPACE or RMB



;*************
;3rd person camera control with move, jump, collison
;by Mike0101
;I'm sure somebody makes  better this weak code
;but this code works right
;*************
Type Timer
	Field start
	Field timeOut
	Field vel_start#;=90
	Field vel_down#;=-2
End Type

;System
Global AppFPS =45
Global screen_width% = 1024
Global screen_height% = 768
Global screen_halfwidth% = screen_width/2
Global screen_halfheight% = screen_height/2
Global camHeight#=4.5  ; default height of the camera behind player
Global camDist#=-7 ; default distance of the camera behind player
Global dest_xang# 
Global dest_yang# 
Global pl_gravity#=-.5
Global pl_jump=0
Global Jump_Move#=0
Global Move_For_Back#
Global Move_Left_Right#
Global Move_Slow#=.1
;CONST
Const C_PLAYER=1, C_LEVEL=2

AppTitle "TPS Camera movement"
HidePointer

;Screen
Graphics3D screen_width,screen_height,32,1
SetBuffer BackBuffer()

CreateWorld()

;CAMERA
camera =CreateCamera()

;Player Pivot
plpivot=CreatePivot()
EntityType plpivot, C_PLAYER
EntityRadius plpivot,1.8,3
PositionEntity plpivot, 0, 3,0

;Player, now a cube but you can change for a nice model
Player=CreateCube(plpivot)
ScaleEntity player,1,3,.7
MoveEntity player,0,1,0
EntityColor Player,255,0,255

;I'm using 2 pivots for camera controlling
;Pivot for the camera controlling
;One Front of the player,
FrontPivot=CreatePivot(plpivot)
PositionEntity Frontpivot,0,4,10

;One behind player
;This pivot controlls the collisions and "finds" the right position of the camera behind player
Backpivot=CreatePivot(plpivot)
EntityRadius Backpivot,1
EntityType BackPivot, C_PLAYER


Collisions C_PLAYER, C_LEVEL ,2,2


; -------------
; Main loop
; -------------
FramePeriod = 1000 / AppFPS
FrameTime = MilliSecs () - FramePeriod
While Not KeyHit(1)
 
; --------------------------
	; Frame rate limiting
	; --------------------------
	Repeat
		FrameElapsed = MilliSecs () - FrameTime
	Until FrameElapsed

	FrameTicks = FrameElapsed / FramePeriod
	FrameTween# = Float (FrameElapsed Mod FramePeriod) / Float (FramePeriod)

	; -----------------------
	; Update tweening
	; -----------------------
	For FrameLimit = 1 To FrameTicks
		If FrameLimit = FrameTicks Then
			CaptureWorld
		EndIf
		FrameTime = FrameTime + FramePeriod
		
              UpdateCamera(plpivot,MouseXSpeed(),MouseYSpeed(), Frontpivot, Backpivot, Camera)
              UpdatePosition(plpivot)
              UpdateWorld

      Next
     
  RenderWorld FrameTween
  ; Crosshair :)
  Text screen_halfwidth%, screen_halfheight%, "+"

  Flip 0

Wend

End


Function updatecamera(ent,mxs#, mys#, pivot1, pivothatso, camera)
;ent : Player pivot
;mxs: MouseXmove
;mys: MouseYmove
;pivot1: pivot before player
;pivothatso: pivot behind player
;Camera: 

    MoveMouse screen_halfwidth%, screen_halfheight%
  
    ; Limit of the "look up", "look down"  
    If dest_xang + mys > 120 Or dest_xang + mys < -45 Then ;
        mys=0 
    EndIf


      dest_xang# = dest_xang + mys

      ; When the player looks up, the front pivot moves UP, when looks down the back pivot moves down
      TranslateEntity pivot1,0,-MYS#*.15,0
 
     angle#=  Sin(EntityPitch(camera))*6
      tempkkammag#=camheight + (angle*.8)
      tempkkamtav#=   camdist  + Abs( angle) 

      dest_yang# = dest_yang - (mxs*.5)
 
       RotateEntity ent, 0, dest_yang,0
     
        dx#=(EntityX(pivothatso,True)-EntityX(camera,True)) *.1
	dy#=(EntityY(pivothatso,True)-EntityY(camera,True)) *.9
	dz#=(EntityZ(pivothatso,True)-EntityZ(camera,True)) *.1
	
	TranslateEntity camera,dx,dy,dz
        PointEntity camera,pivot1
	PositionEntity pivothatso,0,0,0
	ResetEntity pivothatso

       	PositionEntity pivothatso,0,tempkkammag,tempkkamtav
End Function


Function UpdatePosition(ent)
;MOVEMENT
If pl_jump=0
  If KeyDown(200) Or KeyDown(17) Then 
	Move_For_Back=.3
  End If
  If KeyDown (208) Or KeyDown(31) Then
	Move_For_Back=-.2
  End If
  If KeyDown(203) Or KeyDown(30) Then 
      Move_Left_Right=-.2
  End If
  If KeyDown (205) Or KeyDown(32) Then
       Move_Left_Right=.2
  End If
EndIf

If ( MouseHit(2)  Or KeyHit(57))  And pl_jump=0
     t.Timer = JumpTimer (1500)
    ;When jumps slides in the air doesn't stop quickly
     Move_Slow#=.999
     pl_jump=1
EndIf

If jump_timeout()=1
    pl_jump=0
   ;when goes stops quickly
    Move_Slow#=.1
EndIf

   MoveEntity ent, Move_Left_Right, Jump_Move, Move_For_Back
  TranslateEntity ent,0,pl_gravity,0

  ;Smooth movement
  move_left_right = move_left_right * move_slow
  move_for_back = move_for_back  * move_slow

End Function

Function JumpTimer.timer (timeOut)
	t.Timer = New Timer
	t\start   = MilliSecs ()
	t\timeOut = t\start + timeOut
        t\vel_start#=90
        t\vel_down#=-2
	Return t
End Function

; Check for timeout:
Function Jump_TimeOut ()
	For test.timer= Each timer
		If test\timeOut < MilliSecs ()
 		       Jump_move=0
			Delete test
			Return 1
	      Else
	           Jump_Move=Sin(test\vel_start#)
	            test\vel_start=test\vel_start#- test\vel_down#
        	   Return 0
       	EndIf
     Next		
End Function


Function CreateWorld()
;Light
light=CreateLight(1)
PositionEntity light ,0,50,0

;Plan
plan=CreatePlane()
EntityColor plan,255,0,0
EntityType plan, C_LEVEL

;OBJECT
cube1=CreateCube()
ScaleEntity cube1,10,10,10
PositionEntity cube1,13,0,13
EntityType cube1,C_LEVEL

cube2=CreateCube()
ScaleEntity cube2,20,20,20
PositionEntity cube2,33,0,33
EntityType cube2,C_LEVEL

;bridge right side
cube3=CreateCube()
ScaleEntity cube3,20,20,15
PositionEntity cube3,83,0,33
EntityType cube3,C_LEVEL

;bridge
cube4=CreateCube()
ScaleEntity cube4,5,2,20
PositionEntity cube4,83,18,63
EntityType cube4,C_LEVEL

cube5=CreateCube()
ScaleEntity cube5,30,15,35
PositionEntity cube5,153,0,33
EntityType cube5,C_LEVEL

;Bridge left side
cube6=CreateCube()
ScaleEntity cube6,20,20,15
PositionEntity cube6,83,0,93 
EntityType cube6,C_LEVEL
End Function