Hovercraft race (terrain + physics)

Everything related to 3D programming
Kelebrindae
Enthusiast
Enthusiast
Posts: 151
Joined: Tue Apr 01, 2008 3:23 pm

Hovercraft race (terrain + physics)

Post by Kelebrindae »

Hi!

This is a little game (heavily) inspired by an old tutorial from a guy nicknamed Binary Moon. The hovercraft's mesh is from him, too.
(Find the tuto here: http://www.thegamecreators.com/?m=view_ ... rial_index)
My goal here was to test the new 3D functionnalities of PB5 and I must say it works real fine! :D

The rules are simple: you've got to get to the checkpoint before your opponents.
There's a few constants at the beginning of the code to set the number of opponents, the number of opponent teams (1-3), the trees, etc..
There's still a lot of flaws here and there (eg. the tree textures) and the game has no end, but it's playable; see it more as a proof of concept. A convincing one, I hope... :wink:

Grab the code & medias here (3. 6Mo):
http://keleb.free.fr/codecorner/downloa ... rcraft.zip

[UPDATE]: A PB 5.10 version, with more features, is available here:
http://keleb.free.fr/codecorner/downloa ... Racers.zip
(19.6 Mo, source included)

Screenshot: Image

Have fun!

Code: Select all

;************************************************************************************
;  Hovercraft race (inspired by the Binary Moon tutorials for DarkBasic)
;  PB version: 5.00 b6
;  Date: October, 23, 2012
;- F1 -> Change camera view
;- F2 -> Change camera target
;- F5 : Display physic bodies
;- F6 : Wireframe mode
;************************************************************************************

;************************************************************************************
;-                          ---- Constants and structure ----
;************************************************************************************

#NUMTERRAIN = 0
#TerrainMiniX = 0
#TerrainMiniY = 0
#TerrainMaxiX = 0
#TerrainMaxiY = 0

#CAMERA = 0
#NB_HOVERCRAFTS = 6   ; Nb hovercrafts (except you)
#NB_TEAMS = 3         ; Nb teams (except yours)
#NB_CRATESTACKS = 20
#NB_TREES = 100
Enumeration
  #RearView
  #SideView
  #FrontView
  #TopView
  
  #END_VIEWLIST
EndEnumeration


Structure hover_struct
  node.i
  frontNode.i
  backNode.i
  leftNode.i
  rightNode.i
  cameraNode.i
  
  hovercraftMesh.i
  hovercraftEntity.i
  
  physicsEntity.i
  physicsMesh.i
  mass.f
  restitution.f
  friction.f
  
  radius.f
  centerHeight.f
    
  thrust.f
EndStructure
Global Dim hovercraft.hover_struct(#NB_HOVERCRAFTS+1)

Structure checkpoint_struct
  node.i
  particle.i
  
  x.f
  y.f
  z.f
  
  radius.f
EndStructure
Global currentCheckpoint.checkpoint_struct

Global Dim treeMesh.i(4)
Global Dim scoreSprite.i(4)
Global Dim score.i(4)
Global Dim scoreColor.i(4)
scoreColor(0) = $0000FF
scoreColor(1) = $FF0000
scoreColor(2) = $00FF00
scoreColor(3) = $00FFFF
Global Dim nomMatAi.s(4)
nomMatAi(0) = "hoverblue"
nomMatAi(1) = "hovergreen"
nomMatAi(2) = "hoveryellow"
Global arrowMesh.i,arrowEntity.i

EnableExplicit

;************************************************************************************
;-                                 ---- Macros ----
;************************************************************************************

; Those two macros are from Comtois. Merci Comtois !
Macro NEWXVALUE(x, Angle, Distance)
  ((x) + Cos(Radian(Angle+90)) * (Distance))
EndMacro

Macro NEWZVALUE(z, Angle, Distance)
  ((z) - Sin(Radian(Angle+90)) * (Distance))
EndMacro

Macro ANGLE2CHECKPOINT(idHovercraft)
  Degree(ATan2(NodeZ(hovercraft(idHovercraft)\node) - currentCheckpoint\z , NodeX(hovercraft(idHovercraft)\node) - currentCheckpoint\x ))
EndMacro

Macro DRAWSCORESPRITE(numTeam)
  StartDrawing(SpriteOutput(scoreSprite(numTeam)))
  Box(0,0,20,20,scoreColor(numTeam))
  DrawText(32,2,RSet(Str(score(numTeam)),3,"0"))
  DrawingMode(#PB_2DDrawing_Outlined)
  Box(0,0,64,20,scoreColor(numTeam))  
  StopDrawing()
EndMacro

;************************************************************************************
;-                                 ---- Procedures ----
;************************************************************************************

; Terrain blendmaps management, from Comtois 
Procedure Clamp(*var.float, min.f, max.f)
  If *var\f < min
    *var\f = min
  ElseIf *var\f > max
    *var\f = max
  EndIf
EndProcedure

Procedure InitBlendMaps()
  Protected minHeight1.f,fadeDist1.f,minHeight2.f,fadeDist2.f
  Protected x.i,y.i,tx.i,ty.i,size.i
  Protected height.f, val.f
  
  minHeight1 = 0
  fadeDist1 = 15
  minHeight2 = 25
  fadeDist2 = 15
  
  For ty = #TerrainMiniY To #TerrainMaxiY
    For tx = #TerrainMiniX To #TerrainMaxiX
      Size = TerrainTileLayerMapSize(#NUMTERRAIN, tx, ty)
      For y = 0 To Size-1
        For x = 0 To Size-1
          Height = TerrainTileHeightAtPosition(#NUMTERRAIN, tx, ty, 1, x, y)
          
          val = (Height - minHeight1) / fadeDist1
          Clamp(@val, 0, 1)
          SetTerrainTileLayerBlend(#NUMTERRAIN, tx, ty, 1, x, y, val)
          
          val = (Height - minHeight2) / fadeDist2
          Clamp(@val, 0, 1)
          SetTerrainTileLayerBlend(#NUMTERRAIN, tx, ty, 2, x, y, val)
        Next
      Next
      UpdateTerrainTileLayerBlend(#NUMTERRAIN, tx, ty, 1)
      UpdateTerrainTileLayerBlend(#NUMTERRAIN, tx, ty, 2)
    Next
  Next  
EndProcedure  

; ************** end of terrain procs *************


; Keep an angle in the 0-360 range
Procedure.f wrapValue(angle.f)
  If angle < 0
    angle + 360
  ElseIf angle >=360
    angle-360
  EndIf

  ProcedureReturn angle
EndProcedure

; This procedure is from Comtois. Merci Comtois !
; Calcule une valeur progressive allant de la valeur actuelle à la valeur cible
Procedure.f curveValue(actuelle.f, Cible.f, P.f)
  If P > 1000.0
    P = 1000.0
  EndIf
  ProcedureReturn (actuelle + ( (Cible - actuelle) * P / 1000.0))
EndProcedure


; Create a given number of random trees
; (The tree mesh is chosen according to altitude)
Procedure createTrees(nbTrees.i)
  Protected i.i,tree.i,numMesh.i
  Protected posX.f,posY.f,posZ.f
  
  treeMesh(0) = LoadMesh(#PB_Any,"arbol_mort.mesh") ; Dead tree (in the desert areas)
  treeMesh(1) = LoadMesh(#PB_Any,"arbol_sec.mesh")  ; Dried up tree (low areas)
  treeMesh(2) = LoadMesh(#PB_Any,"arbol.mesh")      ; Standard tree (medium height)
  treeMesh(3) = LoadMesh(#PB_Any,"sapin.mesh")      ; Pine tree (high areas)
  BuildMeshShadowVolume(treeMesh(0))
  BuildMeshShadowVolume(treeMesh(1))
  BuildMeshShadowVolume(treeMesh(2))
  BuildMeshShadowVolume(treeMesh(3))
  
  For i= 1 To nbTrees
    posX = Random(900) - 450
    posZ = Random(900) - 450
    posY = TerrainHeight(#NUMTERRAIN,posX,posZ)-0.2
    numMesh = Round(posY / 10, #PB_Round_Down)
    If numMesh < 0
      numMesh = 0
    ElseIf numMesh > 3
      numMesh = 3
    EndIf
    
    ; Create the entity, rotate and scale it randomly so all trees don't look the same
    tree = CreateEntity(#PB_Any,MeshID(treeMesh(numMesh)),#PB_Material_None,posX,posY,posZ)
    RotateEntity(tree,-90,Random(360),0)
    ScaleEntity(tree,(70 + Random(60))/100.0,(70 + Random(60))/100.0,(70 + Random(60))/100.0)
    
    EntityRenderMode(tree,#PB_Entity_CastShadow)
    EntityPhysicBody(tree,#PB_Entity_StaticBody,99,1.0,1.0)  
  Next i
  
EndProcedure

; Create a given number of crates stacks, just so the hovercrafts can ram through them :)
Procedure createCrates(nbStacks.i)
  Protected i.i,j.i,temp.i
  Protected cubeMesh.i,crateTexture.i,crateMat.i
  Protected oriX.f,oriZ.f,posX.f,posY,posZ.f
  
  cubeMesh = CreateCube(#PB_Any,1)
  crateTexture = LoadTexture(#PB_Any,"crate.png")
  crateMat = CreateMaterial(#PB_Any,TextureID(crateTexture))
  
  For j=1 To nbStacks
    posX = Random(900) - 450
    oriZ = Random(900) - 450
    For i = 0 To 2
      temp = CreateEntity(#PB_Any, MeshID(cubeMesh), MaterialID(crateMat))
      posZ = oriZ + (i*1.1)
      EntityLocate(temp,posX,TerrainHeight(#NUMTERRAIN,posX,posZ)+0.5,posZ)
      EntityPhysicBody(temp, #PB_Entity_BoxBody, 0.25)
    Next i
    For i = 0 To 1
      temp = CreateEntity(#PB_Any, MeshID(cubeMesh), MaterialID(crateMat))
      posZ = oriZ + 0.5 + (i*1.1)
      EntityLocate(temp,posX,TerrainHeight(#NUMTERRAIN,posX,posZ)+1.5,posZ)
      EntityPhysicBody(temp, #PB_Entity_BoxBody, 0.25)
    Next i
    
    temp = CreateEntity(#PB_Any, MeshID(cubeMesh), MaterialID(crateMat))
    posZ = oriZ + 1
    EntityLocate(temp,posX,TerrainHeight(#NUMTERRAIN,posX,posZ)+2.5,posZ)
    EntityPhysicBody(temp, #PB_Entity_BoxBody, 0.25)
  Next j
  
EndProcedure

; Create an hovercraft and initialize its position, friction, max thrust, etc. + entity and physics.
; (Hovercraft #0 is the player's one)
Procedure createHovercraft(id.i,nomMesh.s,posX.f, posZ.f, mass.f, restitution.f, friction.f, thrust.f, centerHeight.f)
  Protected numMat.i
  
  ; Material
  If id = 0
    numMat = GetScriptMaterial(#PB_Any,"hoverred")
  Else
    numMat = GetScriptMaterial(#PB_Any,nomMatAi((id-1) % #NB_TEAMS))
  EndIf
  
  ; Hovercraft entity
  hovercraft(id)\hovercraftMesh = LoadMesh(#PB_Any,"hovercraft.mesh")  
  hovercraft(id)\hovercraftEntity = CreateEntity(#PB_Any,MeshID(hovercraft(id)\hovercraftMesh),MaterialID(numMat))
  EntityRenderMode(hovercraft(id)\hovercraftEntity,#PB_Entity_CastShadow)
  EntityPhysicBody(hovercraft(id)\hovercraftEntity,#PB_Entity_None)
  
  ; Hovercraft parameters
  hovercraft(id)\thrust = thrust
  hovercraft(id)\radius = MeshRadius(hovercraft(id)\hovercraftMesh)*1.33
  hovercraft(id)\centerHeight = centerHeight
  hovercraft(id)\mass = mass
  hovercraft(id)\restitution = restitution
  hovercraft(id)\friction = friction
  
  ; Main node
  hovercraft(id)\node = CreateNode(#PB_Any)
  AttachNodeObject(hovercraft(id)\node,EntityID(hovercraft(id)\hovercraftEntity))
  
  ; These nodes are used to get terrain height at different points of the hovercraft, according to its rotation
  hovercraft(id)\frontNode = CreateNode(#PB_Any,0,0,-hovercraft(id)\radius)
  hovercraft(id)\backNode = CreateNode(#PB_Any,0,0,hovercraft(id)\radius)
  hovercraft(id)\leftNode = CreateNode(#PB_Any,-hovercraft(id)\radius,0,0)
  hovercraft(id)\rightNode = CreateNode(#PB_Any,hovercraft(id)\radius,0,0)
  
  AttachNodeObject(hovercraft(id)\node,NodeID(hovercraft(id)\frontNode))
  AttachNodeObject(hovercraft(id)\node,NodeID(hovercraft(id)\backNode))
  AttachNodeObject(hovercraft(id)\node,NodeID(hovercraft(id)\leftNode))
  AttachNodeObject(hovercraft(id)\node,NodeID(hovercraft(id)\rightNode))
  
  ; Camera Node
  hovercraft(id)\cameraNode = CreateNode(#PB_Any,0,1,5)
  AttachNodeObject(hovercraft(id)\node,NodeID(hovercraft(id)\cameraNode))
  
  ; Physics entity for the hovercraft
  hovercraft(id)\physicsMesh = CreateSphere(#PB_Any,hovercraft(id)\radius * 0.8)
  hovercraft(id)\physicsEntity = CreateEntity(#PB_Any,MeshID(hovercraft(id)\physicsMesh),MaterialID(999),posX,TerrainHeight(#NUMTERRAIN,posX,posZ)+1,posZ)
  EntityRenderMode(hovercraft(id)\physicsEntity,0)
  EntityPhysicBody(hovercraft(id)\physicsEntity,#PB_Entity_SphereBody,hovercraft(id)\mass,hovercraft(id)\restitution,hovercraft(id)\friction)
  HideEntity(hovercraft(id)\physicsEntity,#True)
  
EndProcedure


; Apply thrust and steering, and reposition an hovercraft
Procedure moveHovercraft(id.i ,forward.i, backward.i, left.i, right.i)
  Protected xPos.f, yPos.f, zPos.f
  Protected frontHeight.f,backHeight.f,leftHeight.f,rightHeight.f
  Protected xAng.f,yAng.f, zAng.f
  Protected xSlide.f,zSlide.f
  Protected thrustAngle.f, thrust.f
  
  ; Position the hovercraft and get its yaw
  xPos = EntityX(hovercraft(id)\physicsEntity)
  yPos = EntityY(hovercraft(id)\physicsEntity) - hovercraft(id)\radius
  zPos = EntityZ(hovercraft(id)\physicsEntity)
  yAng = NodeYaw(hovercraft(id)\node)
  
  ; The hovercraft can rotate left/right, even in the air
  If left = #True
    RotateNode(hovercraft(id)\node,0,wrapvalue(yAng+4),0)
  ElseIf right = #True
    RotateNode(hovercraft(id)\node,0,wrapvalue(yAng-4),0)
  EndIf
  
  ; If the player is on ground:
  ;   - its pitch/roll must change according to terrain slope;
  ;   - it can accelerate / deccelerate;
  ClearDebugOutput()
  If yPos < TerrainHeight(#NUMTERRAIN,xPos,zPos)
     
    ; Put the hovercraft on the ground
    yPos = TerrainHeight(#NUMTERRAIN,xPos,zPos)
  
    ; Positions of the front, back, left and right nodes
    frontHeight = TerrainHeight(#NUMTERRAIN,NodeX(hovercraft(id)\frontNode),NodeZ(hovercraft(id)\frontNode))
    backHeight  = TerrainHeight(#NUMTERRAIN,NodeX(hovercraft(id)\backNode),NodeZ(hovercraft(id)\backNode))
    leftHeight  = TerrainHeight(#NUMTERRAIN,NodeX(hovercraft(id)\leftNode),NodeZ(hovercraft(id)\leftNode))
    rightHeight = TerrainHeight(#NUMTERRAIN,NodeX(hovercraft(id)\rightNode),NodeZ(hovercraft(id)\rightNode))
    
    ; Quick hack to estimate hovercraft's angle
    xAng = (frontHeight - backHeight) * 30
    zAng = (rightHeight - leftHeight) * 30
    
    ; Update the vehicle's pitch & roll
    RotateEntity(hovercraft(id)\hovercraftEntity,xAng,0,0,#PB_Absolute)
    RotateEntity(hovercraft(id)\hovercraftEntity,0,0,zAng,#PB_Relative)
  
    ; Apply forward/backward movement
    If forward = #True
      thrustAngle = 270 - NodeYaw(hovercraft(id)\node)
      thrust = hovercraft(id)\thrust
    ElseIf backward = #True
      thrustAngle = 270 - NodeYaw(hovercraft(id)\node)
      thrust = -hovercraft(id)\thrust
    EndIf
    
    ; Adjust thrust according to pitch
    thrust * (1 - (xAng/30))
    ;Debug StrF(xpos,2)+" , "+StrF(zpos,2)
    ;Debug "Angle = " + StrF(xAng,2) + "° | Thrust factor = " + StrF((1 - (xAng/30)),2)
        
    ; Move the hovercraft
    DisableEntityBody(hovercraft(id)\physicsEntity,#False)
    ApplyEntityForce(hovercraft(id)\physicsEntity,thrust * Cos(Radian(thrustAngle)),0,thrust * Sin(Radian(thrustAngle)) )
    SetEntityAttribute(hovercraft(id)\physicsEntity, #PB_Entity_MaxVelocity, hovercraft(id)\thrust)
  EndIf
  
  ; Reposition the player object
  NodeLocate(hovercraft(id)\node,xPos,yPos + hovercraft(id)\centerHeight,zPos)
  
EndProcedure

; Opponents AI (just steer towards the checkpoint and move forward)
Procedure moveAiHovercraft()
  Protected id.i
  Protected forward.b = #True, backward.b, left.b, right.b
  Protected angle.f
  
  For id = 1 To #NB_HOVERCRAFTS
    
    If wrapValue(ANGLE2CHECKPOINT(id) - NodeYaw(hovercraft(id)\node)) < 180
      left=#True
      right=#False
    Else
      left=#False
      right=#True
    EndIf
    
    moveHovercraft(id,forward,backward,left,right)
  Next id
  
EndProcedure

; Animate the checkpoint and check if an hovercraft reached it.
Procedure manageCheckpoint(*ptrCheckPoint.checkpoint_struct)
  Protected i.i, team.i
  Protected posX.f = *ptrCheckPoint\x + *ptrCheckPoint\radius * Cos(Radian(ElapsedMilliseconds()*2))
  Protected posZ.f = *ptrCheckPoint\z + *ptrCheckPoint\radius * Sin(Radian(ElapsedMilliseconds()*2))
  
  NodeLocate(*ptrCheckPoint\node,posX,TerrainHeight(#NUMTERRAIN,posX,posZ)+ *ptrCheckPoint\y,posZ)
  
  ; If an hovercraft reach the checkpoint, change its position
  For i=0 To #NB_HOVERCRAFTS
    If (*ptrCheckPoint\x - NodeX(hovercraft(i)\node)) * (*ptrCheckPoint\x - NodeX(hovercraft(i)\node)) + (*ptrCheckPoint\z - NodeZ(hovercraft(i)\node)) * (*ptrCheckPoint\z - NodeZ(hovercraft(i)\node)) < *ptrCheckPoint\radius * *ptrCheckPoint\radius
      ; New position
      *ptrCheckPoint\x = Random(900) - 450
      *ptrCheckPoint\z = Random(900) - 450
      
      ; Increase and redraw score
      If i > 0
        team = 1 + ((i-1) % #NB_TEAMS)
      EndIf
      score(team) + 10
      DRAWSCORESPRITE(team)

    EndIf  
  Next i
  
EndProcedure

; Position the camera
Procedure manageCamera(mode.i,id.i)
  Protected posX.f, posY.f, posZ.f
  Static cameraAngle.f

  Select Mode

    Case #FrontView
      cameraAngle = CurveValue(cameraAngle, NodeYaw(hovercraft(id)\node), 100)
      posX = CurveValue(CameraX(#CAMERA), NEWXVALUE(NodeX(hovercraft(id)\node), cameraAngle, 6), 100)
      posY = CurveValue(CameraY(#CAMERA), NodeY(hovercraft(id)\node) + 3, 100)
      posZ = CurveValue(CameraZ(#CAMERA), NEWZVALUE(NodeZ(hovercraft(id)\node), cameraAngle, 6), 100)

    Case #TopView
      cameraAngle = CurveValue(cameraAngle, NodeYaw(hovercraft(id)\node) + 180, 100)
      posX = CurveValue(CameraX(#CAMERA), NEWXVALUE(NodeX(hovercraft(id)\node), cameraAngle, 4), 30)
      posY = CurveValue(CameraY(#CAMERA), NodeY(hovercraft(id)\node) + 30, 30)
      posZ = CurveValue(CameraZ(#CAMERA), NEWZVALUE(NodeZ(hovercraft(id)\node), cameraAngle, 4), 30)

    Case #RearView
      cameraAngle = CurveValue(cameraAngle, NodeYaw(hovercraft(id)\node) + 180, 100)
      posX = CurveValue(CameraX(#CAMERA), NodeX(hovercraft(id)\cameraNode), 100)
      posZ = CurveValue(CameraZ(#CAMERA), NodeZ(hovercraft(id)\cameraNode), 100)
      posY = CurveValue(CameraY(#CAMERA), NodeY(hovercraft(id)\node) + 1, 100)
      If posY < TerrainHeight(#NUMTERRAIN,posX,posZ) + 1
        posY = TerrainHeight(#NUMTERRAIN,posX,posZ) + 1
      EndIf
     
    Case #SideView
      cameraAngle = CurveValue(cameraAngle, NodeYaw(hovercraft(id)\node) + 90, 100)
      posX = CurveValue(CameraX(#CAMERA), NEWXVALUE(NodeX(hovercraft(id)\node), cameraAngle, 8), 100)
      posY = CurveValue(CameraY(#CAMERA), NodeY(hovercraft(id)\node) + 4, 100)
      posZ = CurveValue(CameraZ(#CAMERA), NEWZVALUE(NodeZ(hovercraft(id)\node), cameraAngle, 8), 100)

  EndSelect
  
  CameraLocate(#CAMERA, posX, posY, posZ)
  CameraLookAt(#CAMERA, NodeX(hovercraft(id)\node), NodeY(hovercraft(id)\node), NodeZ(hovercraft(id)\node))
  
EndProcedure

DisableExplicit


;************************************************************************************
;-                                 ---- Main program ----
;************************************************************************************

If InitEngine3D() = 0
  MessageRequester( "Error" , "Can't initialize 3D, check if engine3D.dll is available")
End
ElseIf InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester( "Error" , "Can't initialize screen and/or controlers")
  End
EndIf

;- Window & Screen
OpenWindow(0,0, 0, 800 , 500 ,"Hovercraft race")
OpenWindowedScreen(WindowID(0),0,0, 800, 500,0,0,0,#PB_Screen_SmartSynchronization)

;- 3d archives
Add3DArchive("meshes/", #PB_3DArchive_FileSystem)
Add3DArchive("materials/", #PB_3DArchive_FileSystem)
Add3DArchive("textures/", #PB_3DArchive_FileSystem)
Add3DArchive("medias/", #PB_3DArchive_FileSystem)
Parse3DScripts()  

;- Lighting
light = CreateLight(#PB_Any ,$FFFFFF, 500, 1000, 500,#PB_Light_Directional)
LightColor(light, $555555, #PB_Light_SpecularColor)
LightDirection(light, 0.55, -0.5, -0.75)
AmbientColor($222222)
WorldShadows(#PB_Shadow_Modulative)
Fog($C2AF80,20,10,1000) ; a little blueish fog increase the depth perception

;- Camera 
CreateCamera(#CAMERA, 0, 0, 100, 100)
CameraBackColor(#CAMERA,$FF7755)
CameraLocate(#CAMERA,0,50,150)

;- Arrow
arrowMesh = LoadMesh(#PB_Any,"arrow.mesh")
arrowEntity = CreateEntity(#PB_Any,MeshID(arrowMesh),#PB_Material_None)
ScaleEntity(arrowEntity,0.5,0.5,0.5)

;- Terrain definition
SetupTerrains(LightID(light), 3000, #PB_Terrain_NormalMapping)
CreateTerrain(#NUMTERRAIN, 1025, 1000, 50, 3, "hovercraft", "dat")
AddTerrainTexture(#NUMTERRAIN,  0, 10, "sand.jpg", "sand_n.jpg")
AddTerrainTexture(#NUMTERRAIN,  1,  20, "grass.jpg", "grass_n.jpg")
AddTerrainTexture(#NUMTERRAIN,  2, 30, "rock.jpg",  "rock_n.jpg")

; Build terrains
For ty = #TerrainMiniY To #TerrainMaxiY
  For tx = #TerrainMiniX To #TerrainMaxiX
    imported = DefineTerrainTile(#NUMTERRAIN, tx, ty, "heightmap_2.png", ty % 2, tx % 2)  
  Next
Next  
BuildTerrain(#NUMTERRAIN)
TerrainPhysicBody(#NUMTERRAIN,0.1,2.0)

If imported = #True
  InitBlendMaps() 
  UpdateTerrain(#NUMTERRAIN)
  SaveTerrain(#NUMTERRAIN, #False)
EndIf  

;- Wireframe material 
; (used To display the hovercraft's physics entity)
CreateTexture(999,16,16)
StartDrawing(TextureOutput(999))
Box(0,0,16,16,$FFFF00)
StopDrawing()
CreateMaterial(999,TextureID(999))
DisableMaterialLighting(999, State)
MaterialShadingMode(999, #PB_Material_Wireframe)


;- Hovercrafts
createHovercraft(0,"hovercraft.mesh",0,150,1,0.1,2.0,15,0.4)     ; player
radius.f = 5
For i=1 To #NB_HOVERCRAFTS  
  posX = radius * Cos(Radian(i * 36))
  posZ = 150 + radius * Sin(Radian(i * 36))
  radius + 0.5
  
  createHovercraft(i,"hovercraft.mesh",posX,posZ,1,0.1,2.0,14.5,0.4)  ; opponents (slightly slower)
Next i

;- Crates
cubeMesh = CreateCube(#PB_Any,1)
createCrates(#NB_CRATESTACKS)

;- Trees
createTrees(#NB_TREES)

;- Checkpoint
currentCheckpoint\particle = GetScriptParticleEmitter(#PB_Any,"flareFountain")
currentCheckpoint\x = 0
currentCheckpoint\z = 0
currentCheckpoint\radius = 3
currentCheckpoint\node = CreateNode(#PB_Any)
AttachNodeObject(currentCheckpoint\node,ParticleEmitterID(currentCheckpoint\particle))

;- Score sprites
For i = 0 To #NB_TEAMS
  scoreSprite(i) = CreateSprite(#PB_Any,64,20)
  DRAWSCORESPRITE(i)
Next i

;- --- Main loop ---
showPhysicBody = #False
wireframe = #False
cameraMode = #rearView
Repeat
  While WindowEvent(): Wend
  
  ;- Controls
  forward = #False:backward=#False:left=#False:right=#False
  If ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Up)
      forward = #True
    ElseIf KeyboardPushed(#PB_Key_Down)
      backward=#True
    EndIf    
    If KeyboardPushed(#PB_Key_Left)
      left = #True
    ElseIf KeyboardPushed(#PB_Key_Right)
      right=#True
    EndIf
  
    ;Change camera view & target
    If KeyboardReleased(#PB_Key_F1)
      cameraMode = (cameraMode + 1) % #END_VIEWLIST
    EndIf
    If KeyboardReleased(#PB_Key_F2)
      cameraTarget = (cameraTarget + 1) % (#NB_HOVERCRAFTS + 1)
    EndIf
    
    ; Display physic body
    If KeyboardReleased(#PB_Key_F5)
      showPhysicBody = 1 - showPhysicBody
      If showPhysicBody = #True
        WorldDebug(#PB_World_DebugBody)
      Else
        WorldDebug(#PB_World_DebugNone)
      EndIf
    EndIf
    ; Wireframe display
    If KeyboardReleased(#PB_Key_F6)
      wireframe = 1 - wireframe
      If wireframe = #True
        CameraRenderMode(#CAMERA,#PB_Camera_Wireframe)
      Else
        CameraRenderMode(#CAMERA,#PB_Camera_Textured)
      EndIf
    EndIf

  EndIf
  
  ;- Checkpoint
  manageCheckpoint(@currentCheckpoint)
  
  ;- Move the hovercrafts
  moveHovercraft(0,forward,backward,left,right)
  moveAiHovercraft()
  
  ;- Move the camera
  ManageCamera(cameraMode,cameraTarget)
  
  ;- Display hud (3D)
  MoveCamera(#CAMERA,0,1.60,-5)
  EntityLocate(arrowEntity,CameraX(#CAMERA),CameraY(#CAMERA),CameraZ(#CAMERA))
  RotateEntity(arrowEntity,30,ANGLE2CHECKPOINT(cameraTarget),0)
  MoveCamera(#CAMERA,0,-1.60,5)
  
  RenderWorld()
  
  ;- Display scores (2D)
  For i = 0 To #NB_TEAMS
    DisplayTransparentSprite(scoreSprite(i),i*80,8)
  Next i
  
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
Last edited by Kelebrindae on Tue Mar 19, 2013 10:22 am, edited 1 time in total.
User avatar
idle
Always Here
Always Here
Posts: 5834
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: [PB5.00 b7] Hovercraft race (terrain + physics)

Post by idle »

Everything seems fine except the terrain doesn't display on linux?
Will have a look at it later today. Thanks
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: [PB5.00 b7] Hovercraft race (terrain + physics)

Post by Tenaja »

Does it work with Beta 5?
I get an error on Win7-64, using the either the 64-bit or the x86 compiler:
The program can't start because d3dx9_42.dll is missing from your computer. Try reinstalling the program to fix this problem.
I hit OK, and get this error:
Can't initialize 3d, check if engine3D.dll is available.
Thanks for sharing.
User avatar
idle
Always Here
Always Here
Posts: 5834
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: [PB5.00 b7] Hovercraft race (terrain + physics)

Post by idle »

change line at 474, then it works on linux
to InitEngine3D(#PB_Engine3D_EnableCG)

@tenaja
you may need to download d3dx9_42.dll

also you need to have the nvidia cg tool kit to compile the program Fred posted a link for it for windows
https://developer.nvidia.com/cg-toolkit-download

linux people
sudo apt-get install nvidia-cg-toolkit
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: [PB5.00 b7] Hovercraft race (terrain + physics)

Post by Comtois »

Tenaja wrote: I get an error on Win7-64, using the either the 64-bit or the x86 compiler:
The program can't start because d3dx9_42.dll is missing from your computer. Try reinstalling the program to fix this problem.
you need to install the latest Directx9
http://www.microsoft.com/en-us/download ... aspx?id=35
Please correct my english
http://purebasic.developpez.com/
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: [PB5.00 b7] Hovercraft race (terrain + physics)

Post by Comtois »

idle wrote: also you need to have the nvidia cg tool kit to compile the program Fred posted a link for it for windows
https://developer.nvidia.com/cg-toolkit-download
It is not necessary under Windows for this game, unless you choose the opengl subsystem.
Please correct my english
http://purebasic.developpez.com/
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Re: [PB5.00 b7] Hovercraft race (terrain + physics)

Post by DarkDragon »

Well done. I played it for quite a while although I knew it has no ending.
bye,
Daniel
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: [PB5.00 b7] Hovercraft race (terrain + physics)

Post by applePi »

does not run in 5.10 or 5.11b1 ,
after changing :
LightColor to SetLightColor
CameraLocate to MoveCamera
EntityLocate to MoveEntity
NodeLocate to MoveNode

it shows the first scene for 1 second then exit with error:
Image
. i have tried it in v5.0 and was great
Kelebrindae
Enthusiast
Enthusiast
Posts: 151
Joined: Tue Apr 01, 2008 3:23 pm

Re: [PB5.00 b7] Hovercraft race (terrain + physics)

Post by Kelebrindae »

Big update!

I added a lot of stuff: Split-screen multiplayer, bonus items, two game modes, music, GFX options, keys redefinition, a neat menu, an "auto-update" feature, etc..

Grab it here: http://keleb.free.fr/codecorner/downloa ... Racers.zip
(19.6 Mo, source included)

A few warnings:
- When you change the resolution, the program will crash at the next game start. Same bug with fullscreen / windowed mode, and maybe with the "terrain detail" setting;
- If the game runs slowly / choppy (press F12 for FPS display), please set the "shadow detail" to "Low": it will desactivate the trees' shadows (they're a bit costly, and the "distance" parameter in "WorldShadow" doesn't work AFAIK).
- You can fall over the edge of the terrain, which is lame. (Fixed in the next version?)
- There's too much medias for the menus alone, which is lame too. (Fixed in the next version?)
- The source code is a mess.

Have fun nevertheless! (I hope)
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: [PB5.00 b7] Hovercraft race (terrain + physics)

Post by applePi »

gorgeous game and demonstration, thank you very much, i run it on windows xp, old cpu, geforce 210 card 1MB, 3GB general ram, my experience is as follows:
in a windows mode inside 800x600. i have used the defaults with shadows, and it was very smooth, realistic terrain with rocks ,grass, water,with amusing effects: glow ball, fire, mines explosions. the cars run in gravity, slow uphills and accelerate downhills, they are affected on obstacles. i have followed the cars when they go and when they return until the "winner team tatu" cup , in a Dos race game i remember there are girl who kiss the winner i can't remember the game name. there are many items i need to explore. i fall once from the terrain area.
i give you Kelebrindae 96.99 % mark.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: [PB5.00 b7] Hovercraft race (terrain + physics)

Post by applePi »

i have experimented more, there are amusing effect when we change the gravity to -1
after line 2201 insert WorldGravity(-1) , the cars seems as if they are on the moon, they jump too high, but sometimes the scene flicker when the cars are in the air.
Image
a great resources of info , material files: i like the material bonusGlow with rosy color .
Kelebrindae
Enthusiast
Enthusiast
Posts: 151
Joined: Tue Apr 01, 2008 3:23 pm

Re: [PB5.00 b7] Hovercraft race (terrain + physics)

Post by Kelebrindae »

@applePi:
Thanks for the kind review ! :D
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: [PB5.00 b7] Hovercraft race (terrain + physics)

Post by davido »

Kelebrindae:

Thanks for sharing - very nice demo. :D

Works fine with debugger on PB5.11 final.
Gives same error as Tenaja got if debugger is switched off.


PB511 64bit final, Windows 7 64bit.
DE AA EB
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Hovercraft race (terrain + physics)

Post by applePi »

for the new users to see the game since it contains many goodies, the game is still run okay in PB 5.31 , the only small corrections needed using search and replace of the PB IDE:
replace:
AddBillboard(#PB_Any,
with
AddBillboard(

replace:
AddBillboard(1,
with
AddBillboard(

replace:
DrawText(0,0,Str(Engine3DFrameRate(#PB_Engine3D_Current))+ " FPS")
with
DrawText(0,0,Str(Engine3DStatus(#PB_Engine3D_CurrentFPS ))+ " FPS")

about 5 corrections only.
tested using PB 5.31 on windows xp 32bit
Num3
PureBasic Expert
PureBasic Expert
Posts: 2812
Joined: Fri Apr 25, 2003 4:51 pm
Location: Portugal, Lisbon
Contact:

Re: Hovercraft race (terrain + physics)

Post by Num3 »

Very nice!!!
Post Reply