exemple avec une sphère , comme l'entité et le body ont leur repère au centre \BodyOffsetY = 0
Et comme la sphère a un rayon de 30 j'ai placé le rayon dans OnGround() entre -29 et -31, histoire d'être à cheval sur la périphérie de la sphère.
Code : Tout sélectionner
Global ScreenWidth, ScreenHeight
#PlayerSpeed = 80
#CameraSpeed = 10
Structure Vector3
x.f
y.f
z.f
EndStructure
Structure s_Key
Up.i
Down.i
Left.i
Right.i
Jump.i
EndStructure
Structure s_Entity
EntityBody.i
BodyOffsetY.f
elapsedTime.f
Fov.f
Key.s_Key
MainNode.i
CameraNode.i
HandNode.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
Declare HandleEntity(*Entity.s_Entity)
Declare OnGround(*Entity.s_Entity)
Define Robot.s_Entity
If InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()
;If Screen3DRequester()
ExamineDesktops()
OpenScreen(DesktopWidth(0), DesktopHeight(0), DesktopDepth(0), "char")
;- AddArchive
Add3DArchive("Data/" , #PB_3DArchive_FileSystem)
Add3DArchive("Data/Desert.zip", #PB_3DArchive_Zip)
Parse3DScripts()
;- Robot Body
CreateSphere(0,30)
CreateEntity(0, MeshID(0), #PB_Material_None, 0, 60, 0)
HideEntity(0, 1)
LoadMesh (1, "sol.mesh")
CreateEntity(1, MeshID(1), #PB_Material_None, 0, 0, 0)
;Body
EntityPhysicBody(0, #PB_Entity_SphereBody, 0.45, 0, 0)
EntityPhysicBody(1, #PB_Entity_StaticBody)
With Robot
\Fov = 50
\EntityBody = 0
\BodyOffsetY = 0
\Key\Down = #PB_Key_Down
\Key\Left = #PB_Key_Left
\Key\Right = #PB_Key_Right
\Key\Up = #PB_Key_Up
\Key\Jump = #PB_Key_Space
\MainNode = CreateNode(#PB_Any) ; Entity position
\CameraNode = CreateNode(#PB_Any, 0, 60, 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) , #PB_Node_Node)
AttachNodeObject(\MainNode , NodeID(\ForwardNode), #PB_Node_Node)
AttachNodeObject(\MainNode , NodeID(\StrafeNode) , #PB_Node_Node)
EndWith
;- Camera
CreateCamera(0, 0, 0, 100, 100)
CameraBackColor(0, $56778)
CameraRange(0, 0.08, 10000)
AttachNodeObject(Robot\CameraNode, CameraID(0), #PB_Node_Camera)
CameraLookAt(0, NodeX(Robot\ForwardNode) * 100, NodeY(Robot\CameraNode), NodeZ(Robot\ForwardNode) * 100)
;- Skybox
SkyBox("desert07.jpg")
;- *** Main loop ***
Repeat
If Engine3DFrameRate(#PB_Engine3D_Current)
Robot\elapsedTime = 40/Engine3DFrameRate(#PB_Engine3D_Current)
EndIf
HandleEntity(@Robot)
RenderWorld(60)
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
Else
MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
End
Procedure OnGround(*Entity.s_Entity)
ProcedureReturn RayCollide(NodeX(*Entity\MainNode), NodeY(*Entity\MainNode)-29, NodeZ(*Entity\MainNode), NodeX(*Entity\MainNode), NodeY(*Entity\MainNode)-31, NodeZ(*Entity\MainNode))
EndProcedure
Procedure HandleEntity(*Entity.s_Entity)
Protected.Vector3 Forward, Strafe, PosMain, PosDir, PosStrafe
Protected.f Speed, Speed2, SpeedShoot, x, y
Protected.f MouseX, MouseY
Static Jump.f, MemJump.i, Rot.Vector3, Trans.Vector3, Clic
With *Entity
GetNodePosition(PosMain, \MainNode)
GetNodePosition(PosDir, \ForwardNode)
GetNodePosition(PosStrafe, \StrafeNode)
SubVector3(Forward, PosDir, PosMain)
SubVector3(Strafe, PosStrafe, PosMain)
Speed = #PlayerSpeed * \elapsedTime
Speed2 = Speed / 2
SpeedShoot = Speed * 9
If ExamineKeyboard()
If KeyboardPushed(\Key\Jump) And OnGround(*Entity)
Jump = 30
MemJump = 1
EndIf
Rot\x * 0.30
Rot\y * 0.30
Rot\z * 0.30
Trans\x * 0.80
Trans\y = Jump
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)
If OnGround(*Entity)
Jump = 0
ElseIf MemJump
Jump + 30
If Jump > 60
MemJump = 0
EndIf
Else
Jump - 4 * \elapsedTime
EndIf
EndIf
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
CameraFOV(0, \Fov)
RotateEntity(\EntityBody, 0, Rot\y, 0, #PB_Relative)
RotateNode(\CameraNode , Rot\x, 0, 0, #PB_Relative)
NodeLocate(\MainNode, EntityX(\EntityBody), EntityY(\EntityBody) - \BodyOffsetY, EntityZ(\EntityBody))
RotateNode(\MainNode, 0, EntityYaw(\EntityBody), 0)
EndWith
EndProcedure