OK, well, I just pruned the FPS sample. Maybe it could be simpler than this, but it works perfectly. See below.
Now I wonder why there isn't a rectangle prefab. There really should be a CreateBox(#Mesh, Width, Height, Depth). CreateCube() can only be a size, but doesn't have dimensions. I want to create a wall, but it would be stupid to load a mesh for something that simple.
Code: Select all
Global ScreenWidth, ScreenHeight
IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"
#PlayerSpeed = 80
#CameraSpeed = 10
Structure Vector3
x.f
y.f
z.f
EndStructure
Structure s_Key
Up.i
Down.i
Left.i
Right.i
EndStructure
Structure s_Entity
EntityBody.i
BodyOffsetY.f
elapsedTime.f
Fov.f
Key.s_Key
MainNode.i
CameraNode.i
ForwardNode.i
StrafeNode.i
EndStructure
Macro GetNodePosition(Position, Node)
Position\x = NodeX(Node)
Position\y = NodeY(Node)
Position\z = NodeZ(Node)
EndMacro
Macro SubVector3(V, V1, V2)
V\x = V1\x - V2\x
V\y = V1\y - V2\y
V\z = V1\z - V2\z
EndMacro
Declare HandleEntity(*Entity.s_Entity)
Define Robot.s_Entity
If InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()
If Screen3DRequester()
;- Guy Body
CreateCapsule(0, 2.0, 1.0)
CreateEntity(0, MeshID(0), #PB_Material_None, 10, 4, 10)
HideEntity(0, 1)
;- Ground
CreatePlane(1, 300, 300, 1, 1, 0, 0)
CreateEntity(1, MeshID(1), #PB_Material_None, 0, -50, 200)
CreatePlane(2, 400, 400, 1, 1, 0, 0)
CreateEntity(2, MeshID(2), #PB_Material_None)
CreateCube(3, 20)
CreateEntity(3, MeshID(3), #PB_Material_None, 15, 4, 15)
;Body
CreateEntityBody(0, #PB_Entity_CapsuleBody, 0.45, 0, 0)
CreateEntityBody(1, #PB_Entity_StaticBody)
CreateEntityBody(2, #PB_Entity_StaticBody)
CreateEntityBody(3, #PB_Entity_BoxBody, 3, 1, 3)
With Robot
\Fov = 50
\EntityBody = 0
\BodyOffsetY = 43
\Key\Down = #PB_Key_S ;Down
\Key\Left = #PB_Key_A ;Left
\Key\Right = #PB_Key_D;Right
\Key\Up = #PB_Key_W ;Up
\MainNode = CreateNode(#PB_Any) ; Entity position
\CameraNode = CreateNode(#PB_Any, 0, 80, 0) ; Camera position
\ForwardNode= CreateNode(#PB_Any, 0, 0, -1) ; Direction normalized
\StrafeNode = CreateNode(#PB_Any, -1, 0, 0) ; Direction normalized
AttachNodeObject(\MainNode , NodeID(\CameraNode))
AttachNodeObject(\MainNode , NodeID(\ForwardNode))
AttachNodeObject(\MainNode , NodeID(\StrafeNode))
EndWith
;- Camera
CreateCamera(0, 0, 0, 100, 100)
CameraRange(0, 0.08, 5000)
AttachNodeObject(Robot\CameraNode, CameraID(0))
CameraLookAt(0, NodeX(Robot\ForwardNode) * 100, NodeY(Robot\CameraNode), NodeZ(Robot\ForwardNode) * 100)
;- Light
CreateLight(0, RGB(255, 255, 255), 200, 100, 200, #PB_Light_Point)
;- Fog
Fog(RGB(127, 127, 127), 128, 10, 2000)
;- *** Main loop ***
Repeat
Screen3DEvents()
If Engine3DStatus(#PB_Engine3D_CurrentFPS)
Robot\elapsedTime = 40/Engine3DStatus(#PB_Engine3D_CurrentFPS)
EndIf
HandleEntity(@Robot)
RenderWorld(60)
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
EndIf
Else
MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
End
Procedure HandleEntity(*Entity.s_Entity)
Protected.Vector3 Forward, Strafe, PosMain, PosDir, PosStrafe
Protected.f Speed, Speed2
Protected.f MouseX, MouseY
Static Rot.Vector3, Trans.Vector3
With *Entity
GetNodePosition(PosMain, \MainNode)
GetNodePosition(PosDir, \ForwardNode)
GetNodePosition(PosStrafe, \StrafeNode)
SubVector3(Forward, PosDir, PosMain)
SubVector3(Strafe, PosStrafe, PosMain)
Speed = #PlayerSpeed * \elapsedTime
Speed2 = Speed * 0.5
If ExamineMouse()
MouseX = -(MouseDeltaX()/200) * \Fov * \elapsedTime
MouseY = -(MouseDeltaY()/200) * \Fov * \elapsedTime
Rot\z = 0
Rot\y + MouseX
If NodePitch(\CameraNode) < 80 And MouseY > 0
Rot\x + MouseY
ElseIf NodePitch(\CameraNode) > -80 And MouseY < 0
Rot\x + MouseY
EndIf
If MouseButton(#PB_MouseButton_Right)
If \Fov > 20
\Fov - 2 * \elapsedTime
EndIf
Else
If \Fov < 50
\Fov + 2 * \elapsedTime
EndIf
EndIf
EndIf
If ExamineKeyboard()
Rot\x * 0.30
Rot\y * 0.30
Rot\z * 0.30
Trans\x * 0.80
Trans\y = -8
Trans\z * 0.80
If KeyboardPushed(\Key\Up)
Trans\x = Forward\x * Speed
Trans\z = Forward\z * Speed
ElseIf KeyboardPushed(\Key\Down)
Trans\x = Forward\x * -Speed2
Trans\z = Forward\z * -Speed2
EndIf
If KeyboardPushed(\Key\Left)
Trans\x = Strafe\x * Speed
Trans\z = Strafe\z * Speed
ElseIf KeyboardPushed(\Key\Right)
Trans\x = Strafe\x * -Speed
Trans\z = Strafe\z * -Speed
EndIf
MoveEntity(\EntityBody, Trans\x, Trans\y, Trans\z)
EndIf
CameraFOV(0, \Fov)
RotateEntity(\EntityBody, 0, Rot\y, 0, #PB_Relative)
RotateNode(\CameraNode , Rot\x, 0, 0, #PB_Relative)
MoveNode(\MainNode, EntityX(\EntityBody), EntityY(\EntityBody) - \BodyOffsetY, EntityZ(\EntityBody), #PB_Absolute)
RotateNode(\MainNode, 0, EntityYaw(\EntityBody), 0)
EndWith
EndProcedure