Author Topic: More simple (and reduced) WOW camera like style  (Read 574 times)

0 Members and 1 Guest are viewing this topic.

Offline jepalza

  • Friends
  • Gentleman (Lady)
  • *
  • Posts: 42
  • Reputation 5
  • 3D Crazy
More simple (and reduced) WOW camera like style
« on: October 21, 2015, 06:15:13 PM »
This is my reduced version of WOW like style camera (Word Of Warcraft). In this version, only movements for WALK, BACK and RUN are implemented. It's in order to create a simple camera for 3rd person adventures. Is in case you don't need a full of movements (jump, swin, crounch, dead, gun, etc.) .

It's released in one file only (12 kbytes):
Code: [Select]
dim shared as wvector position
dim shared as wvector rotation

Dim shared as single  forwardAngle, WalkSpeed, RunSpeed
Dim shared as integer Forward, Back, Runto, Walk, Idle

dim shared as single  CamUpdateSpeed
dim shared as single  CamZoomOffset
dim shared as integer want_smooth_return ' retorno suave de camara al centro

dim shared as single BR_TURN
dim shared as single K_TURN
dim shared as single walk_or_run ' andar o correr de uso interno

' variables de matematicas de giro
dim shared as single CamPan
dim shared as single CamTilt
dim shared as single CamZoom
dim shared as single maxZoom, minZoom
dim shared as single camSpeed
dim shared as wSceneNode camTarget
dim shared as wvector offset


' para la deteccion de teclas y raton
dim shared as integer Keys_Down(256)
dim shared as integer MWHEEL
dim shared as integer WALKING
dim shared as integer MBRIGHT
dim shared as integer MBLEFT
dim shared as integer MX, MY, OLDMX, OLDMY, OLDMPOSX, OLDMPOSY, MOUSEX, MOUSEY

dim shared as integer Key_For_Walk
dim shared as integer Key_For_Back
dim shared as integer Key_For_Left
dim shared as integer Key_For_Right
dim shared as integer Key_For_Run

Key_For_Walk=KEY_KEY_W
Key_For_Back=KEY_KEY_S
Key_For_Left=KEY_KEY_A
Key_For_Right=KEY_KEY_D
Key_For_Run=KEY_SHIFT ' correr

WalkSpeed=4
RunSpeed=10
walk_or_run=walkspeed ' andar o correr
want_smooth_return=0 ' camara retorna a posicion incial

' PITCH = giro principal de izq. a der.
' ROLL = giro de cabeza de hombro a hombro (no lo usamos)
' CROUCH = agachado
' SWIM = nadar

CamPan=0 ' giro principal YAW
CamTilt=-15 ' cabeceo PITCH

' ajustes del ZOOM
CamZoom=100 ' offset actual zoom
CamZoomOffset = 100
minZoom=50
maxZoom=250
CamSpeed = 3 ' ajuste de ruleta de raton???
CamUpdateSpeed = 0.005 ' velocidad de actualizacion de acercamiento de camara

' ajustes para la camara que queda tras el jugador
offset.X=0
offset.Y=20 ' separacion de la espalda del jugador
offset.Z=0 ' altura hacia los hombros desde el suelo

BR_TURN=50 ' velocidad de giro con boton derecgo
K_TURN= 2 ' giro con teclado



' ************************************
' control de eventos de raton y teclado
' ************************************

Sub MyEventReceiver()

   MWHEEL=0

   while wKeyEventAvailable
      KeyEvent = wReadKeyEvent ' capturamos teclas
      if KeyEvent->key = KEY_ESCAPE then end   ' EXIT

      if (KeyEvent->direction = wKEY_DOWN) then
      dim n as integer
      for n=1 to 255
      if (KeyEvent->key=n) then Keys_Down(n)=1
      next
      end if
     
      if (KeyEvent->direction = wKEY_UP) then
      dim n as integer
      for n=1 to 255
      if (KeyEvent->key=n) then Keys_Down(n)=0
      next
      end if   
   wend
   
   while wMouseEventAvailable
      MouseEvent = wReadMouseEvent
    if(MouseEvent->action = wME_RMOUSE_PRESSED_DOWN) then
    OLDMPOSX=MOUSEX
    OLDMPOSY=MOUSEY
    MBRIGHT=1
    end if
   
    if(MouseEvent->action = wME_RMOUSE_LEFT_UP) then
    MBRIGHT=0
    end if
   
    if(MouseEvent->action = wME_LMOUSE_PRESSED_DOWN) then
    OLDMPOSX=MOUSEX
    OLDMPOSY=MOUSEY
    MBLEFT=1
    end if
   
    if(MouseEvent->action = wME_LMOUSE_LEFT_UP) then
    MBLEFT=0
    end if
   
    if (MouseEvent->action = wME_MOUSE_WHEEL) then
       MWHEEL=MouseEvent->delta
    end if
   
    if (MouseEvent->action = wME_MOUSE_MOVED) then
    MOUSEX=MouseEvent->x
    MOUSEY=MouseEvent->y
    end if
   wend

end sub

' *******************************************
' animaciones
' *******************************************
sub NULLifyFlags()
Forward= 0
Back= 0
RunTo= 0
Walk= 0
Idle= 0
end sub

' correr
Sub RunForwardMode()
if (RunTo and Forward) then exit sub
NULLifyFlags()
RunTo=1
Forward=1
'wSetNodeAnimationRange(jugador,RunToFrames(0),RunToFrames(1))
'wSetNodeAnimationSpeed(jugador,RunToFrameSpeed)
End sub

' andar
Sub WalkForwardMode()
if (Walk and Forward) then exit sub
NULLifyFlags()
Walk=1
Forward=1
wSetNodeAnimationRange(jugador,161,183)
'wSetNodeAnimationSpeed(WalkFrameSpeed)
End sub

' retroceder
Sub WalkBackMode()
if Back then exit sub
NULLifyFlags()
Back=1
'wSetNodeAnimationRange(jugador,WALKBACKFrames(0),WALKBACKFrames(1))
'wSetNodeAnimationSpeed(jugador,WalkBackFrameSpeed)
End sub

' parado
Sub IdleMode()
if Idle then exit sub
NULLifyFlags()
Idle=1
'wSetNodeAnimationSpeed(jugador,StandFrameSpeed)
wSetNodeAnimationRange(jugador,0,150)
End Sub


' **************************************
' control de acciones
' **************************************

sub Turn (tdegrees as single)
dim as wvector r1
wgetnoderotation(jugador,r1.x,r1.y,r1.z)
r1.y+=tdegrees
wsetnodeRotation(jugador,r1.x,r1.y,r1.z)
end sub

Sub stepMotion (milliseconds as integer)
dim as single sTime=milliseconds/20
dim as wvector position
dim as wvector tmpv
dim as wvector rotation

wgetnodeposition(jugador,position.x,position.y,position.z)
wgetnodeRotation(jugador,rotation.x,rotation.y,rotation.z)

forwardAngle=rotation.Y

if(Walk and Forward) Then
    tmpv.X=+(cos(forwardAngle*PI/180)*walk_or_run)
    tmpv.Z=-(sin(forwardAngle*PI/180)*walk_or_run)
wsetnodeposition (jugador,position.X+tmpv.X*sTime,position.Y,position.Z+tmpv.Z*sTime)
End if

if (Runto=0 and Back) Then
    tmpv.X=-(cos(forwardAngle*PI/180)*walk_or_run)
    tmpv.Z=+(sin(forwardAngle*PI/180)*walk_or_run)
wsetnodeposition (jugador,position.X+tmpv.X*sTime,position.Y,position.Z+tmpv.Z*sTime)
End if

if (Runto and Forward) Then
tmpv.X=+(cos(forwardAngle*PI/180)*RunSpeed)
tmpv.Z=-(sin(forwardAngle*PI/180)*RunSpeed)
wsetnodeposition (jugador,position.X+tmpv.X*sTime,position.Y,position.Z+tmpv.Z*sTime)
End if

End Sub

sub newplayerposition(msecs as integer)

if (MBRIGHT or MBLEFT) Then
   whidemouse
end if

if (MBRIGHT=0 and MBLEFT=0) Then
wshowmouse
end if

' parado
if ( (Keys_Down(Key_For_Walk)=0) _
     and (Keys_Down(Key_For_Back)=0) _
     and (Keys_Down(Key_For_Left)=0) _
     and (Keys_Down(Key_For_Right)=0) _
     and (MBRIGHT=0 or MBLEFT=0)) Then
    IdleMode()
end if

' andar
if ( (Keys_Down(Key_For_Walk) _
               or (MBRIGHT and MBLEFT)) _
               and (Keys_Down(Key_For_Back)=0) _
               and (Keys_Down(Key_For_Left)=0) _
               and (Keys_Down(Key_For_Right)=0) ) Then         

    if Keys_Down(Key_For_Run) Then
    RunForwardMode()
    walk_or_run=runspeed
    else
       WalkForwardMode()
       walk_or_run=walkspeed
    end if

End If

' retroceder
if (Keys_Down(Key_For_Back) _
             and ((MBLEFT and MBRIGHT)=0) _
             and (Keys_Down(Key_For_Walk)=0) _
             and (Keys_Down(Key_For_Left)=0) _
             and (Keys_Down(Key_For_Right)=0) ) Then             
WalkBackMode()
end if

''''''''''''''''''''''''''''''''''''''''''''''''''''

if (MBRIGHT or MBLEFT and (MOUSEY <> OLDMPOSY)) Then
SetMouse(OLDMPOSX,OLDMPOSY)
end if

if (MBRIGHT and (MOUSEX <> OLDMPOSX)) Then
turn(((MOUSEX-OLDMPOSX)/BR_TURN)) ' velocidad de giro con el boton derecho
SetMouse(OLDMPOSX,OLDMPOSY)
end if

if (MBLEFT=1 and MBRIGHT=0 and (MOUSEX <> OLDMPOSX)) Then
SetMouse(OLDMPOSX,OLDMPOSY)
End If

if (Keys_Down(Key_For_Left) and MBRIGHT=0) Then
turn(-K_TURN) ' velocidad de giro tecla izq.
End If

if (Keys_Down(Key_For_Right) and MBRIGHT=0) Then
turn(K_TURN) ' velocidad de giro tecla der.
End If

stepMotion(msecs)

end sub

' ****************************************
' matematica de giros
' ****************************************
sub newcameraposition()

dim as wVector CPosVector
dim as wVector NewCamLocation
dim as wVector Target1

dim as wVector RotCam

CPosVector.X=cos((camPan+180)*PI/180)*sin((camTilt+90)*PI/180)
CPosVector.Y=cos((camTilt+90)*PI/180)
CPosVector.Z=sin((camPan+180)*PI/180)*sin((camTilt+90)*PI/180)

   ' cogemos la actual rotacion de la camara en grados
wgetnoderotation(jugador,RotCam.x,RotCam.y,RotCam.z)
wsetnoderotation(jugador,RotCam.x,RotCam.y,RotCam.z)

   ' ----------  convierte un vector 3D en radianes y lo mete en una matriz --------
   dim M(8) as single ' matriz de 0 a 8 , 9 elementos
     
      ' pasamos a radianes
      RotCam.X= RotCam.X * PI /180
      RotCam.Y= RotCam.Y * PI /180
      RotCam.Z= RotCam.Z * PI /180
     
      ' guardamos los grados en una matriz 3x3
Dim as Single sinr = sin( RotCam.X ) ' roll
Dim as Single cosr = cos( RotCam.X )
Dim as Single sinp = sin( RotCam.Y ) ' pitch
Dim as Single cosp = cos( RotCam.Y )
Dim as Single siny = sin( RotCam.Z ) ' yaw
Dim as Single cosy = cos( RotCam.Z )

Dim as Single cosr_sinp = cosr*sinp
Dim as Single sinr_sinp = sinr*sinp

M(0) = ( cosp*cosy )
M(1) = ( cosp*siny )
M(2) = ( -sinp )

M(3) = ( sinr_sinp*cosy-cosr*siny )
M(4) = ( sinr_sinp*siny+cosr*cosy )
M(5) = ( sinr*cosp )

M(6) = ( cosr_sinp*cosy+sinr*siny )
M(7) = ( cosr_sinp*siny-sinr*cosy )
M(8) = ( cosr*cosp )

'------- multiplica el nuevo vector deseado por la matriz anterior ---------

Dim as wvector vector
vector.X = CPosVector.X*M(0) + CPosVector.Y*M(3) + CPosVector.Z*M(6)
vector.Y = CPosVector.X*M(1) + CPosVector.Y*M(4) + CPosVector.Z*M(7)
vector.Z = CPosVector.X*M(2) + CPosVector.Y*M(5) + CPosVector.Z*M(8)

      ' recogemos el nuevo vector ( y pasamos a grados otra vez --> noooo por ahora)
CPosVector.X = vector.X '* 180 / PI
CPosVector.Y = vector.Y '* 180 / PI
CPosVector.Z = vector.Z '* 180 / PI

'----------------------------------------------------------------------------

wgetnodePosition(jugador,Target1.X,Target1.Y,Target1.Z)

NewCamLocation.X=(Target1.X+offset.X)+CPosVector.X*camZoom
NewCamLocation.Y=(Target1.Y+offset.Y)+CPosVector.Y*camZoom
NewCamLocation.Z=(Target1.Z+offset.Z)+CPosVector.Z*camZoom

wSetnodePosition (cameranode,NewCamLocation.X,NewCamLocation.Y,NewCamLocation.Z)
wSetCameraTarget (cameranode,Target1.X,Target1.Y,Target1.Z)


end sub

' ***********************************
' movemos el personaje
' ***********************************

sub MovePlayer(ElapsedTime as single)
   
      ' camtilt = cabeceo arriba-abajo
if (MBRIGHT or MBLEFT and (MOUSEY<>OLDMPOSY)) then
CamTilt=CamTilt-(MOUSEY-OLDMPOSY)/20
if(CamTilt<-89) then CamTilt=-89 ' altura maxima visto en planta
if(CamTilt> 45) then CamTilt= 45 ' altura maxima de giro de barbilla hacia arriba
SetMouse(OLDMPOSX,OLDMPOSY)
end if

if (MBRIGHT and (MOUSEX<>OLDMPOSX)) then
SetMouse(OLDMPOSX,OLDMPOSY)
end if

' campan = giro horizontal, solo con raton izq.
if (MBLEFT and (MBRIGHT=0) and (MOUSEX<>OLDMPOSX)) then
CamPan=CamPan-(MOUSEX-OLDMPOSX)/20
if( CamPan >= 360 ) then CamPan = 0
if( CamPan < -360 ) then CamPan = 0
SetMouse(OLDMPOSX,OLDMPOSY)
end if

' acercamiento suavizado
if (MWHEEL<>0) then
   CamZoomOffset -= CamSpeed * MWHEEL * ElapsedTime  
   if (CamZoomOffset < minZoom ) then CamZoomOffset = minZoom
   if (CamZoomOffset > maxZoom ) then CamZoomOffset = maxZoom
   MWHEEL = 0
end if

CamZoom += ( CamZoomOffset - CamZoom ) * CamUpdateSpeed * ElapsedTime

' retorna la camara al centro al soltar el raton izq.
if want_smooth_return then
    if ( MBLEFT=0 ) then
      CamPan += ( -CamPan ) * 0.005f * ElapsedTime
    end if
end if

   ' estudia pulsaciones de raton y teclado para ver como queremos mover
newplayerposition(ElapsedTime)

' actualiza posicion camaras
newcameraposition()

end sub


Offline Nikolas - WS3D Developer

  • Programmer
  • Global Moderator
  • Viscount
  • *
  • Posts: 719
  • Reputation 49
Re: More simple (and reduced) WOW camera like style
« Reply #1 on: October 22, 2015, 03:57:11 PM »
Super!  :)
Под лежачий камень мы всегда успеем...