J'ai trouvé un sujet dans lequel des utilisateurs ont fixé certains bugs des démos 3D de purebasic.
Je pense que l'exemple de ThirdPersonn.pb est vraiment meilleur tel que donné dans ce sujet :
La démo fonctionne vraiment bien mieux, le personnage arrête ses animations lorsque l'on arrête d'appuyer sur les flèches, etc..
Bref, je pense qu'il serait judicieux de remplacer l'exemple thirdpersonn.pb par le code qu'ils ont corrigé.
Voici une copie (à placer dans le même dossier que celui où se trouve thirdpersonn.pb). je me suis permis de changer 2 ou 3 bricoles (ajout d'une light sans ombre et worldshadows en additive, modification du saut pour que ce soit un peu plus réaliste) :
Code : Tout sélectionner
;
; ------------------------------------------------------------
;
; PureBasic - Third Person
;
; (c) 2011 - Fantaisie Software
;
; ------------------------------------------------------------
;
IncludeFile "Screen3DRequester.pb"
#PlayerSpeed = 60
#CameraSpeed = 10
Structure Vector3
x.f
y.f
z.f
EndStructure
Structure s_Key
Up.i
Down.i
Left.i
Right.i
StrafeLeft.i
StrafeRight.i
Jump.i
EndStructure
Structure s_Entity
Entity.i
EntityBody.i
BodyOffsetY.f
elapsedTime.f
Key.s_Key
MainNode.i
SightNode.i
CameraNode.i
ForwardNode.i
StrafeNode.i
EndStructure
Structure s_Camera
Camera.i
Tightness.f
CameraNode.i
TargetNode.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 CameraTrack(*Camera.s_Camera, *Entity.s_Entity)
Declare OnGround(*Entity.s_Entity)
Declare MakeColimacon(PX.f, PY.f, PZ.f, Length.i, Height.i, Width.i, Stair.i)
Declare MakeStair(PX.f, PY.f, PZ.f, Length.i, Height.i, Width.i, Stair.i)
Declare AddObjects()
Define Robot.s_Entity
Define Camera.s_Camera
If InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()
If Screen3DRequester()
KeyboardMode(#PB_Keyboard_International)
Add3DArchive("../Data/Textures" , #PB_3DArchive_FileSystem)
Add3DArchive("../Data/Models" , #PB_3DArchive_FileSystem)
Add3DArchive("../Data/Scripts" , #PB_3DArchive_FileSystem)
Add3DArchive("../Data/GUI" , #PB_3DArchive_FileSystem)
Add3DArchive("../Data/Packs/desert.zip", #PB_3DArchive_Zip)
Parse3DScripts()
WorldShadows(#PB_Shadow_Additive, 50)
;Texture
CreateTexture(1, 256, 256)
StartDrawing(TextureOutput(1))
Box(0, 0, 256, 256, $002255)
DrawingMode(#PB_2DDrawing_Outlined)
Box(0, 0, 256, 256, $FFFFFF)
Box(10, 10, 236, 236, $FFFF)
StopDrawing()
;Material
CreateMaterial(0, LoadTexture(0, "r2skin.jpg"))
CreateMaterial(1, TextureID(1))
CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
CreateMaterial(3, LoadTexture(3, "Wood.jpg"))
GetScriptMaterial(4, "Scene/GroundBlend")
;Robot
LoadMesh (0, "robot.mesh")
CreateEntity (0, MeshID(0), #PB_Material_None);
AnimateEntity(0, "Stop") ;AnimateEntity(0, "Idle")
;Robot Body
CreateEntity(1, MeshID(0), #PB_Material_None, 0, 26, 0)
HideEntity(1, 1)
;Ground
CreatePlane(2, 5000, 5000, 100, 100, 100, 100)
CreateEntity(2, MeshID(2), MaterialID(1), 0, 0, 0)
;Body
EntityPhysicBody(1, #PB_Entity_CapsuleBody, 1, 0, 0)
EntityPhysicBody(2, #PB_Entity_StaticBody)
;Add some statics and dynamics objects
CreateCube(3, 1)
AddObjects()
;Add some stairs
MakeColimacon(120, 0, 120, 130, 7, 48, 15)
MakeStair(360, 0, 220, 130, 11, 48, 15)
;-Light
CreateLight(0,RGB(155,155,155),700,500,0)
CreateLight(1,RGB(235, 175, 123),100,50,500)
DisableLightShadows(1, 1)
AmbientColor(RGB(85,85,85))
; Skybox
SkyBox("desert07.jpg")
;
With Robot
\Entity = 0
\EntityBody = 1
\BodyOffsetY = 43
\Key\Down = #PB_Key_Down
\Key\Left = #PB_Key_Left
\Key\Right = #PB_Key_Right
\Key\Up = #PB_Key_Up
\Key\StrafeLeft = #PB_Key_X
\Key\StrafeRight = #PB_Key_C
\Key\Jump = #PB_Key_Space
\MainNode = CreateNode(#PB_Any) ; Entity position
\SightNode = CreateNode(#PB_Any, 120, 20, 0) ; For cameraLookAt
\CameraNode = CreateNode(#PB_Any, -140, 100, 0) ; Camera position
\ForwardNode = CreateNode(#PB_Any, 1, 0, 0) ; Direction normalized
\StrafeNode = CreateNode(#PB_Any, 0, 0, -1) ; Direction normalized
AttachNodeObject(\MainNode, NodeID(\SightNode) , #PB_Node_Node)
AttachNodeObject(\MainNode, NodeID(\CameraNode) , #PB_Node_Node)
AttachNodeObject(\MainNode, NodeID(\ForwardNode), #PB_Node_Node)
AttachNodeObject(\MainNode, NodeID(\StrafeNode) , #PB_Node_Node)
AttachNodeObject(\MainNode, EntityID(\Entity) , #PB_Node_Entity)
EndWith
;-Camera
CreateCamera(0, 0, 0, 100, 100)
With Camera
\Camera = 0
\Tightness = 0.035
; Camera use 2 nodes
\CameraNode = CreateNode(#PB_Any, -3000, 700, 0) ; Camera position
\TargetNode = CreateNode(#PB_Any) ; For cameraLookAt
AttachNodeObject(\CameraNode, CameraID(\Camera), #PB_Node_Camera)
EndWith
;-Main loop
If ExamineMouse()
MouseDeltaX()
MouseDeltaY()
EndIf
Repeat
Screen3DEvents()
If Engine3DFrameRate(#PB_Engine3D_Current)
Robot\elapsedTime = 40/Engine3DFrameRate(#PB_Engine3D_Current)
EndIf
HandleEntity(@Robot)
CameraTrack(@Camera, @Robot)
RenderWorld(50)
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
EndIf
Else
MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
End
Procedure OnGround(*Entity.s_Entity)
With *Entity
ProcedureReturn RayCollide(NodeX(\MainNode), NodeY(\MainNode)+3, NodeZ(\MainNode), NodeX(\MainNode), NodeY(\MainNode), NodeZ(\MainNode))
EndWith
EndProcedure
Procedure IsStair(*Entity.s_Entity)
Protected.f x, y, z
With *Entity
x = (NodeX(\ForwardNode) - NodeX(\MainNode))*30
y = (NodeY(\ForwardNode) - NodeY(\MainNode))*30
z = (NodeZ(\ForwardNode) - NodeZ(\MainNode))*30
;CreateLine3D(20, NodeX(\MainNode), NodeY(\MainNode)+20, NodeZ(\MainNode), $FFFF, NodeX(\MainNode)+V\x, NodeY(\MainNode)+V\y+20, NodeZ(\MainNode)+V\z, $FFFF)
Ray1 = RayCollide(NodeX(\MainNode), NodeY(\MainNode)+10, NodeZ(\MainNode), NodeX(\MainNode)+x, NodeY(\MainNode)+y+10, NodeZ(\MainNode)+z)
Ray2 = RayCollide(NodeX(\MainNode), NodeY(\MainNode)+20, NodeZ(\MainNode), NodeX(\MainNode)+x, NodeY(\MainNode)+y+20, NodeZ(\MainNode)+z)
If Ray1 And Ray2=0
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndWith
EndProcedure
Procedure HandleEntity(*Entity.s_Entity)
Protected.Vector3 Forward, Strafe, PosMain, PosDir, PosStrafe
Protected.f Speed, Speed2, x, y, MouseX, MouseY, Action.s
Static Jump.f, MemJump.i, Rot.Vector3, Trans.Vector3, Clic, LastAction.s
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
If ExamineKeyboard()
If KeyboardReleased(#PB_Key_F5)
WorldDebug(#PB_World_DebugBody)
ElseIf KeyboardReleased(#PB_Key_F6)
WorldDebug(#PB_World_DebugEntity)
ElseIf KeyboardReleased(#PB_Key_F7)
WorldDebug(#PB_World_DebugNone)
EndIf
If KeyboardPushed(\Key\Jump) And OnGround(*Entity)
Jump = 4
MemJump = 1
EndIf
Rot\x * 0.30
Rot\y * 0.30
Rot\z * 0.30
Trans\x * 0.20
Trans\y = Jump
Trans\z * 0.20
Action = "Stop" ;Action = "Idle"
If KeyboardPushed(\Key\Up)
Trans\x + Forward\x * Speed
Trans\z + Forward\z * Speed
Action = "Walk"
ElseIf KeyboardPushed(\Key\Down)
Trans\x + Forward\x * -Speed2
Trans\z + Forward\z * -Speed2
Action = "Walk"
EndIf
If KeyboardPushed(\Key\Left)
Rot\y + 2 * \elapsedTime
If Action <> "Walk"
action="Idle"
EndIf
ElseIf KeyboardPushed(\Key\Right)
Rot\y - 2 * \elapsedTime
If Action <> "Walk"
action="Idle"
EndIf
EndIf
If KeyboardPushed(\Key\StrafeLeft)
Trans\x + Strafe\x * Speed2
Trans\z + Strafe\z * Speed2
Action = "Walk"
ElseIf KeyboardPushed(\Key\StrafeRight)
Trans\x + Strafe\x * -Speed2
Trans\z + Strafe\z * -Speed2
Action = "Walk"
EndIf
If Action <> LastAction
LastAction = Action
AnimateEntity(0, Action)
EndIf
If OnGround(*Entity)
Jump = 0
ElseIf MemJump
Jump + 20
If Jump > 80
MemJump = 0
EndIf
Else
Jump - 9 * \elapsedTime
EndIf
If IsStair(*Entity) And Jump = 0 And ( Abs(Trans\x)>=Speed / 2 Or Abs(Trans\z)>=Speed / 2)
Jump = 22 ; Or more
EndIf
EndIf
MoveEntity (\EntityBody, Trans\x, Trans\y, Trans\z)
RotateEntity(\EntityBody, 0, Rot\y, 0, #PB_Relative)
NodeLocate(\MainNode, EntityX(\EntityBody), EntityY(\EntityBody)-\BodyOffsetY, EntityZ(\EntityBody))
RotateNode(\MainNode, 0, EntityYaw(\EntityBody), 0)
EndWith
EndProcedure
Procedure CameraTrack(*Camera.s_Camera, *Entity.s_Entity)
Protected CameraPosition.Vector3, TargetPosition.Vector3, Temp.Vector3
Protected V1.Vector3, V2.Vector3, x.f, y.f, z.f
GetNodePosition(CameraPosition, *Entity\CameraNode)
GetNodePosition(TargetPosition, *Entity\SightNode)
x = NodeX(*Camera\CameraNode)
y = NodeY(*Camera\CameraNode)
z = NodeZ(*Camera\CameraNode)
x = (CameraPosition\x - x) * *Camera\Tightness
y = (CameraPosition\y - y) * *Camera\Tightness
z = (CameraPosition\z - z) * *Camera\Tightness
MoveNode(*Camera\CameraNode, x, y, z)
x = NodeX(*Camera\TargetNode)
y = NodeY(*Camera\TargetNode)
z = NodeZ(*Camera\TargetNode)
x = (TargetPosition\x - x) * *Camera\Tightness
y = (TargetPosition\y - y) * *Camera\Tightness
z = (TargetPosition\z - z) * *Camera\Tightness
MoveNode(*Camera\TargetNode, x, y, z)
CameraLookAt(*Camera\Camera, NodeX(*Camera\TargetNode), NodeY(*Camera\TargetNode), NodeZ(*Camera\TargetNode))
EndProcedure
Procedure MakeColimacon(PX.f, PY.f, PZ.f, Length.i, Height.i, Width.i, Stair.i)
Protected.f Angle
Protected.i a, Ent
For a = 1 To Stair
Ent = CreateEntity(#PB_Any, MeshID(3), MaterialID(2))
ScaleEntity(Ent, Length, Height, Width)
EntityLocate(Ent, PX + Cos(Radian(Angle)) * Width * 5, PY + (a-1) * Height * 4, PZ -Sin(Radian(Angle)) * Width * 5)
RotateEntity(Ent, 0, Angle, 0)
EntityPhysicBody(Ent, #PB_Entity_StaticBody)
Angle = Mod(Angle + 30, 360)
Next
EndProcedure
Procedure MakeStair(PX.f, PY.f, PZ.f, Length.i, Height.i, Width.i, Stair.i)
Protected.i a, Ent, Nb
Protected.f Size, Delta, H
For a = 1 To Stair
Ent = CreateEntity(#PB_Any, MeshID(3), MaterialID(2))
ScaleEntity(Ent, Length, Height, Width)
EntityLocate(Ent, PX, PY + (a-1) * Height, PZ + (a-1) * Width * 0.8)
EntityPhysicBody(Ent, #PB_Entity_StaticBody)
Next a
;Add a plateform
Ent = CreateEntity(#PB_Any, MeshID(3), MaterialID(2))
ScaleEntity(Ent, Length*5, Height, Width*5)
EntityLocate(Ent, PX, PY + (a-1) * Height, PZ + (a-1) * Width)
EntityPhysicBody(Ent, #PB_Entity_StaticBody)
;Add Pyramid
Nb = 7
Delta = 0.01
Size = 20
H = EntityY(Ent) + Height/2
For j = 0 To Nb
For i= 0 To Nb-j
Ent = CreateEntity(#PB_Any, MeshID(3), MaterialID(4))
ScaleEntity(Ent, Size, Size, Size)
EntityPhysicBody(Ent, #PB_Entity_BoxBody, 0.5)
EntityLocate(Ent, 340 + j * ((Size) / 2) + i * Size, H + ((Size) / 2) + (j * (Size)), 890)
Next
Next
EndProcedure
Procedure AddObjects()
Protected Size.Vector3
Protected.f x, z
Protected.i Ent, i
For i = 0 To 100
If Random(1)
Size\x = Random(60) + 30
Size\y = Random(60) + 30
Size\z = Random(60) + 30
Volume.f = Size\x * Size\y * Size\z
Ent=CreateEntity(#PB_Any, MeshID(3), MaterialID(3), Random(5000)-2600, 100, Random(5000)-2500)
RotateEntity(Ent, 0, Random(360), 0)
ScaleEntity(ent, Size\x, Size\y, Size\z)
EntityPhysicBody(Ent, #PB_Entity_BoxBody, (Volume / 7000), 0, 2)
Else
Size\x = Random( 60) + 30
Size\y = Random(160) + 30
Size\z = Random( 60) + 30
Repeat
x = Random(5000)-2500
Until x < -400 Or x > 400
Repeat
z = Random(5000)-2500
Until z < -400 Or z > 400
Ent=CreateEntity(#PB_Any, MeshID(3), MaterialID(2), x, Size\y/2 + Random(90) , z)
RotateEntity(Ent, 0, Random(360), 0)
ScaleEntity(Ent, Size\x, Size\y, Size\z)
EntityPhysicBody(Ent, #PB_Entity_StaticBody)
EndIf
Next
EndProcedure
. Ca permettra de créer/charger/modifier/enregistrer des niveaux de jeux, mais on devra faire tout le reste du code quand même
fais plutôt ça pour Fred, c'est lui qu'il faut remercier (et G-rom et tmyke pour la 3D aussi grandement
).