Gravity

Advanced game related topics
kcraft
User
User
Posts: 18
Joined: Sun Jul 13, 2003 7:29 am
Contact:

Gravity

Post by kcraft »

I posted in the Features request list about adding a function for Gravity. I attempted what was sent to me in a reply, but the results are semi-good?

Heres the code (more below the code):

Code: Select all

;
; ------------------------------------------------------------
;
;   PureBasic - SkyDome
;
;    (c) 2003 - Fantaisie Software
;
; ------------------------------------------------------------
;

#CameraSpeed = 25

IncludeFile "Screen3DRequester.pb"

DefType.f KeyX, KeyY, MouseX, MouseY

If InitEngine3D()

  Add3DArchive("Data\"          , #PB_3DArchive_FileSystem)
  Add3DArchive("Data\Skybox.zip", #PB_3DArchive_Zip)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    
    AmbientColor(RGB(255,255,255))
    
    CreateMaterial(0, LoadTexture(2, "r2skin.jpg"))
    CreateEntity  (0, LoadMesh(2, "Robot.mesh"), MaterialID(0), -1, -2, -3)
    CreateMaterial  (0, LoadTexture(0, "Terrain_Texture.jpg"))
    AddMaterialLayer(0, LoadTexture(1, "Terrain_Detail.jpg"), 1)

    CreateTerrain("Terrain.png", MaterialID(0), 40, 1, 40, 0)

    SkyDome("Clouds.jpg", 30)

    CreateCamera(0,0,0,100,100)
    CameraLocate(0,3700,20,1775)

    Repeat
      Screen3DEvents()
      Ground = TerrainHeight(oldx,oldz)      
      If ExamineKeyboard()
        
        If KeyboardPushed(#PB_Key_Left)
          KeyX = CameraX(0) - #CameraSpeed ;- I changed all of these to say CameraX(0)
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = CameraX(0) + #CameraSpeed 
        Else
          KeyX = CameraX(0)
        EndIf
                  
        If KeyboardPushed(#PB_Key_Up)
          KeyY = CameraZ(0) - #CameraSpeed 
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = CameraZ(0) + #CameraSpeed 
        Else
          KeyY = CameraZ(0)
        EndIf

      EndIf
      
      If ExamineMouse()
        MouseX = -(MouseDeltaX()/10)*#CameraSpeed/2
        MouseY = -(MouseDeltaY()/10)*#CameraSpeed/2
      EndIf
     
     
      oldx = CameraX(0)
      oldy = ground + 20
      oldz = CameraZ(0)
      ;- This is where I changed it to attempt a gravity effect -------------------
      CameraLocate(0, KeyX, oldy, KeyY)
      RotateCamera(0, MouseX, MouseY, RollZ)
      ;MoveCamera  (0, KeyX, 0, KeyY)
      
      
      ; Get Terrain Height -----------------------------------------------------------
      
      RenderWorld()
      Screen3DStats()      
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
    
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
  
All of the files it calls for are in the Examples/Data folder.

What happens here is:

1. The camera stays at 20 above the terrain height.
2. The camera can look around.
3. When you move, using the up arrow key, it only goes 1 direction.
same with all the other keys. The movement does not match what
way the camera is looking.

If anyone could throw some hints as to what I can do to get this working, it would be much appreciated.

Is there a function for determining where the camera is pointing? If so, how could I get the movement to change to that direction?

thanks
LarsG
Enthusiast
Enthusiast
Posts: 713
Joined: Mon Jun 02, 2003 1:06 pm
Location: Norway
Contact:

Post by LarsG »

If nobody replies to this, I'll take a look at it when I get home.. :)

-Lars

AMD Athlon XP2400, 512 MB RAM, Hercules 3D Prophet 9600 256MB RAM, WinXP
PIII 800MHz, 320 MB RAM, Nvidia Riva Tnt 2 Mach 64 (32MB), WinXP + Linux
17" iMac, 1.8 GHz G5, 512 MB DDR-RAM, 80 GB HD, 64 MB Geforce FX 5200, SuperDrive, OSX
LarsG
Enthusiast
Enthusiast
Posts: 713
Joined: Mon Jun 02, 2003 1:06 pm
Location: Norway
Contact:

Post by LarsG »

Okay, I had I little look at it...
And the first thing that happened when I comiled it, was that it crashed.. hehe (so I fixed that)..

Then after a bit tweaking and reorganizing of the code, I came up with this....
It's probably not the best way to do it, but it works.. :)

[edit] note that I also kept the media in the "data" directory [/edit]

Code: Select all

;
;
; Keeping constant distance to terrain example
; by Lars Gretnes, 2003
;

#CameraSpeed  = 20
#WalkSpeed    = 50

IncludeFile "Screen3DRequester.pb" 

DefType.f KeyX, KeyY, MouseX, MouseY 

If InitEngine3D() 

  Add3DArchive("Data\"          , #PB_3DArchive_FileSystem) 
  Add3DArchive("Data\Skybox.zip", #PB_3DArchive_Zip) 
  
  InitSprite() 
  InitKeyboard() 
  InitMouse() 
  
  If Screen3DRequester() 

    AmbientColor(RGB(255,255,255))

    ; load the mesh (robot)
    LoadMesh(0, "data\Robot.mesh")
    LoadTexture(2, "data\r2skin.jpg")
    CreateMaterial (0, TextureID(2))
    CreateEntity (0, MeshID(0), MaterialID(0), -1, -2, -3)
    
    ; load terrain
    LoadTexture (0, "data\Terrain_Texture.jpg")
    LoadTexture (1, "data\Terrain_Detail.jpg")
    CreateMaterial (1, TextureID(0))
    AddMaterialLayer(0, TextureID(1), 1) 
    CreateTerrain("data\Terrain.png", MaterialID(1), 40, 1, 40, 0) 

    SkyDome("data\Clouds.jpg", 30) 

    ; create and place the camera
    CreateCamera(0,0,0,100,100) 
    CameraLocate(0,3700,50,1775) 

    Repeat 
      Screen3DEvents() 
 
       ; get the key input
       If ExamineKeyboard() 
        If KeyboardPushed(#PB_Key_Left) 
          KeyX = -#WalkSpeed 
        ElseIf KeyboardPushed(#PB_Key_Right) 
          KeyX = #WalkSpeed 
        Else 
          KeyX = 0 
        EndIf 
                  
        If KeyboardPushed(#PB_Key_Up) 
          KeyY = -#WalkSpeed 
        ElseIf KeyboardPushed(#PB_Key_Down) 
          KeyY = #WalkSpeed 
        Else 
          KeyY = 0 
        EndIf

      EndIf
      
      ; get mousemovement
      If ExamineMouse() 
        MouseX = -(MouseDeltaX()/10)*#CameraSpeed/2 
        MouseY = -(MouseDeltaY()/10)*#CameraSpeed/2 
      EndIf 
      
      ; get the terrain heigh at the player coords
      ypos = TerrainHeight(CameraX(0) ,CameraZ(0)) + 50

      ; move the camera, and keep the height at +50
      RotateCamera (0, MouseX, MouseY, 0) 
      MoveCamera (0, KeyX, 0, KeyY)
      CameraLocate (0, CameraX(0), ypos, CameraZ(0))
 
      ; render world
      RenderWorld() 
      FlipBuffers() 

    Until KeyboardPushed(#PB_Key_Escape)
  EndIf 
    
Else 
  MessageRequester("Error", "The 3D Engine can't be initialized",0) 
EndIf 

AMD Athlon XP2400, 512 MB RAM, Hercules 3D Prophet 9600 256MB RAM, WinXP
PIII 800MHz, 320 MB RAM, Nvidia Riva Tnt 2 Mach 64 (32MB), WinXP + Linux
17" iMac, 1.8 GHz G5, 512 MB DDR-RAM, 80 GB HD, 64 MB Geforce FX 5200, SuperDrive, OSX
kcraft
User
User
Posts: 18
Joined: Sun Jul 13, 2003 7:29 am
Contact:

Great!

Post by kcraft »

That helps. Now I understand how it works. Thanks Alot.

lol. Now we have to figure out jumping, and we're set! :-)
LarsG
Enthusiast
Enthusiast
Posts: 713
Joined: Mon Jun 02, 2003 1:06 pm
Location: Norway
Contact:

Post by LarsG »

jumping , eh?!?
well.. it's not exactly optimized.. nor is it any good, but it may be something for you to work on?!?!

Code: Select all

;
;
; Keeping constant distance to terrain example
; by Lars Gretnes, 2003
;

#CameraSpeed  = 20
#WalkSpeed    = 50

jumping.b = 0
jumpvar.b = 0

IncludeFile "Screen3DRequester.pb" 

DefType.f KeyX, KeyY, MouseX, MouseY 

If InitEngine3D() 

  Add3DArchive("Data\"          , #PB_3DArchive_FileSystem) 
  Add3DArchive("Data\Skybox.zip", #PB_3DArchive_Zip) 
  
  InitSprite() 
  InitKeyboard() 
  InitMouse() 
  
  If Screen3DRequester() 

    AmbientColor(RGB(255,255,255))

    ; load the mesh (robot)
    LoadMesh(0, "data\Robot.mesh")
    LoadTexture(2, "data\r2skin.jpg")
    CreateMaterial (0, TextureID(2))
    CreateEntity (0, MeshID(0), MaterialID(0), -1, -2, -3)
    
    ; load terrain
    LoadTexture (0, "data\Terrain_Texture.jpg")
    LoadTexture (1, "data\Terrain_Detail.jpg")
    CreateMaterial (1, TextureID(0))
    AddMaterialLayer(0, TextureID(1), 1) 
    CreateTerrain("data\Terrain.png", MaterialID(1), 40, 1, 40, 0) 

    SkyDome("data\Clouds.jpg", 30) 

    ; create and place the camera
    CreateCamera(0,0,0,100,100) 
    CameraLocate(0,3700,50,1775) 

    Repeat 
      Screen3DEvents() 
 
      ; get the key input
      If ExamineKeyboard() 
        If KeyboardPushed(#PB_Key_Left) 
          KeyX = -#WalkSpeed 
        ElseIf KeyboardPushed(#PB_Key_Right) 
          KeyX = #WalkSpeed 
        Else 
          KeyX = 0 
        EndIf 
                  
        If KeyboardPushed(#PB_Key_Up) 
          KeyY = -#WalkSpeed 
        ElseIf KeyboardPushed(#PB_Key_Down) 
          KeyY = #WalkSpeed 
        Else 
          KeyY = 0 
        EndIf

        If KeyboardPushed(#PB_Key_Space)
          jumping = 1
        EndIf
      EndIf
      
      ; get mousemovement
      If ExamineMouse() 
        MouseX = -(MouseDeltaX()/10)*#CameraSpeed/2 
        MouseY = -(MouseDeltaY()/10)*#CameraSpeed/2 
      EndIf 
      
      If jumping > 0
        ; were jumping
        ; check if wer're going up or down
        If jumping = 1
          ; were going UP
          jumpvar +3
          If jumpvar => 60
            jumping = 2
          EndIf
        ElseIf jumping = 2
          jumpvar -3
          If jumpvar <= 0
            jumping = 0
          EndIf
        EndIf
      EndIf
      
      ; set the terrain heigh at the player coords
      ypos = TerrainHeight(CameraX(0) ,CameraZ(0)) + 50 + jumpvar
      ; move the camera, and keep the height at +50
      RotateCamera (0, MouseX, MouseY, 0) 
      MoveCamera (0, KeyX, 0, KeyY)
      CameraLocate (0, CameraX(0), ypos, CameraZ(0))
 
      ; render world
      RenderWorld() 
      FlipBuffers() 

    Until KeyboardPushed(#PB_Key_Escape)
  EndIf 
    
Else 
  MessageRequester("Error", "The 3D Engine can't be initialized",0) 
EndIf 

AMD Athlon XP2400, 512 MB RAM, Hercules 3D Prophet 9600 256MB RAM, WinXP
PIII 800MHz, 320 MB RAM, Nvidia Riva Tnt 2 Mach 64 (32MB), WinXP + Linux
17" iMac, 1.8 GHz G5, 512 MB DDR-RAM, 80 GB HD, 64 MB Geforce FX 5200, SuperDrive, OSX
LarsG
Enthusiast
Enthusiast
Posts: 713
Joined: Mon Jun 02, 2003 1:06 pm
Location: Norway
Contact:

Post by LarsG »

You might want to read up on the use of Sinus and Cosine to calculate the jump and gravity, as this is more correct, and gives you a much smoother transition when jumping... I've never calculated this is three dimensions, so I might have to read up on that as well... hehe ;)

-Lars

AMD Athlon XP2400, 512 MB RAM, Hercules 3D Prophet 9600 256MB RAM, WinXP
PIII 800MHz, 320 MB RAM, Nvidia Riva Tnt 2 Mach 64 (32MB), WinXP + Linux
17" iMac, 1.8 GHz G5, 512 MB DDR-RAM, 80 GB HD, 64 MB Geforce FX 5200, SuperDrive, OSX
kcraft
User
User
Posts: 18
Joined: Sun Jul 13, 2003 7:29 am
Contact:

Thanks Lars

Post by kcraft »

Thanks again! That really helps, I tweaked it a bit by putting a check in at the jump key

basically if ImJumping = 1 ignore the space bar.
kcraft
User
User
Posts: 18
Joined: Sun Jul 13, 2003 7:29 am
Contact:

sin and cos

Post by kcraft »

in reply to sin/cos

I kinda figured that I would. I was playing around with it earlier, made the mountains much taller, then tried to jump off of them and I basically hopped down the side, one step at a time. :-) It was rather funny. I have another game that I am baseing my movement off of, and when I jump it looks as if it determines whether I am moving forward/backward or not, and adjusts my height accordingly. When I take that system and jump from the top of a mountain, I fall to my death. Which is basically what I am looking for on my game, just gonna take time to figure out all the maths and such.

thanks again.
LarsG
Enthusiast
Enthusiast
Posts: 713
Joined: Mon Jun 02, 2003 1:06 pm
Location: Norway
Contact:

Post by LarsG »

Jumping up and down a mountain (or similar), will actually not be any problem when you get the physics up and running..
Basically, what you want to do, is to have a constant, #gravity, that pulls down the player constantly in the Y-axis (the correct value for Earth is 9.8, but you'd rather adjust it to suit your needs)...
Then, when the player makes a jump, you'd actually give him a push upward the Y-axis, and calculate the vector of the player when he's "in the air".. this is (normally) done by something like:
(note: I'm not sure if this specific formula would work cause I haven't tried it..)

Code: Select all

y_vector = sin(player_angle) * push_speed
then you add this vector to the player position and subtract the gravity as well.. (and subtract values for friction etc. if you want)

I guess I really have to test some of this later, but I think you get the general idea... :)
Good luck..

-Lars

AMD Athlon XP2400, 512 MB RAM, Hercules 3D Prophet 9600 256MB RAM, WinXP
PIII 800MHz, 320 MB RAM, Nvidia Riva Tnt 2 Mach 64 (32MB), WinXP + Linux
17" iMac, 1.8 GHz G5, 512 MB DDR-RAM, 80 GB HD, 64 MB Geforce FX 5200, SuperDrive, OSX
Post Reply