If you use moveEntity() it will not fall.Alexi wrote:For thrid-person Perspective the Camera has to avoid Objects. A simple and effective way would be a invisible Sphere Body, but if the mass is set to zero, the body can't move. If mass is given the Camera falls down of course.![]()
ThirdPerson.pb example with fews change :
Code: Select all
;
; ------------------------------------------------------------
;
; 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
CameraBody.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 AddObjects()
Define Robot.s_Entity
Define Camera.s_Camera
Define.f TimeSinceLastFrame = 0
If InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()
If Screen3DRequester()
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_Modulative, 3000, RGB(150, 150, 150))
;Texture
CreateTexture(1, 256, 256)
StartDrawing(TextureOutput(1))
Box(0, 0, 256, 256, RGB(0, 34, 85))
DrawingMode(#PB_2DDrawing_Outlined)
Box(0, 0, 256, 256, RGB(255, 255, 255))
Box(10, 10, 236, 236, RGB(0, 255, 255))
StopDrawing()
;Material
CreateMaterial(0, LoadTexture(0, "r2skin.jpg"))
CreateMaterial(1, TextureID(1))
MaterialFilteringMode(1, 2)
CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
CreateMaterial(3, LoadTexture(3, "Wood.jpg"))
GetScriptMaterial(4, "Scene/GroundBlend")
MaterialFilteringMode(1, #PB_Material_Anisotropic, 8)
;Robot
LoadMesh (0, "robot.mesh")
CreateEntity (0, MeshID(0), #PB_Material_None);
StartEntityAnimation(0, "Walk")
;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()
;-Light
CreateLight(0,RGB(155,155,155),700,500,0)
AmbientColor(RGB(85,85,85))
;- Fog
Fog(RGB(210, 210, 210), 1, 0, 10000)
; 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))
AttachNodeObject(\MainNode, NodeID(\CameraNode))
AttachNodeObject(\MainNode, NodeID(\ForwardNode))
AttachNodeObject(\MainNode, NodeID(\StrafeNode))
AttachNodeObject(\MainNode, EntityID(\Entity))
EndWith
;-Camera
CreateCamera(0, 0, 0, 100, 100)
Sphere = CreateSphere(#PB_Any, 10)
With Camera
\Camera = 0
\Tightness = 0.5
; Camera use 2 nodes
\CameraNode = CreateNode(#PB_Any, -30, 70, 0) ; Camera position
\TargetNode = CreateNode(#PB_Any) ; For cameraLookAt
\CameraBody = 20
CreateEntity(20, MeshID(Sphere), #PB_Material_None, -30, 70, 0)
EntityPhysicBody(20, #PB_Entity_SphereBody, 0.5, 0, 1)
HideEntity(\CameraBody, #True)
AttachEntityObject(\CameraBody, "",CameraID(\Camera))
EndWith
;-Main loop
;
Repeat
Screen3DEvents()
Robot\elapsedTime = TimeSinceLastFrame * 40
HandleEntity(@Robot)
CameraTrack(@Camera, @Robot)
TimeSinceLastFrame = RenderWorld(50) / 1000
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)+x, NodeY(\MainNode)+y+20, NodeZ(\MainNode)+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>-1 And Ray2=-1
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
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
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)>-1
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
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)
Rot\y + 2 * \elapsedTime
ElseIf KeyboardPushed(\Key\Right)
Rot\y - 2 * \elapsedTime
EndIf
If KeyboardPushed(\Key\StrafeLeft)
Trans\x + Strafe\x * Speed2
Trans\z + Strafe\z * Speed2
ElseIf KeyboardPushed(\Key\StrafeRight)
Trans\x + Strafe\x * -Speed2
Trans\z + Strafe\z * -Speed2
EndIf
If OnGround(*Entity) > -1
Jump = 0
ElseIf MemJump
Jump + 20
If Jump > 80
MemJump = 0
EndIf
Else
Jump - 9
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)
MoveNode(\MainNode, EntityX(\EntityBody), EntityY(\EntityBody)-\BodyOffsetY, EntityZ(\EntityBody), #PB_Absolute)
RotateNode(\MainNode, 0, EntityYaw(\EntityBody), 0)
EndWith
EndProcedure
Procedure CameraTrack(*Camera.s_Camera, *Entity.s_Entity)
Protected.Vector3 CameraPosition, TargetPosition
Protected.f x, y, z
GetNodePosition(CameraPosition, *Entity\CameraNode)
GetNodePosition(TargetPosition, *Entity\SightNode)
x = EntityX(*Camera\CameraBody)
y = EntityY(*Camera\CameraBody)
z = EntityZ(*Camera\CameraBody)
x = (CameraPosition\x - x) * *Camera\Tightness
y = (CameraPosition\y - y) * *Camera\Tightness
z = (CameraPosition\z - z) * *Camera\Tightness
MoveEntity(*Camera\CameraBody, 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 AddObjects()
Protected Size.Vector3
Protected.f x, z
Protected.i Ent, i
Ent=CreateEntity(#PB_Any, MeshID(3), MaterialID(2), -400, 100, 0)
ScaleEntity(Ent, 5, 200, 800)
EntityPhysicBody(Ent, #PB_Entity_StaticBody)
Ent=CreateEntity(#PB_Any, MeshID(3), MaterialID(2), 400, 100, 0)
ScaleEntity(Ent, 5, 200, 800)
EntityPhysicBody(Ent, #PB_Entity_StaticBody)
Ent=CreateEntity(#PB_Any, MeshID(3), MaterialID(2), 0, 100, -400)
ScaleEntity(Ent, 800, 200, 5)
EntityPhysicBody(Ent, #PB_Entity_StaticBody)
Ent=CreateEntity(#PB_Any, MeshID(3), MaterialID(2), 0, 100, 400)
ScaleEntity(Ent, 800, 200, 5)
EntityPhysicBody(Ent, #PB_Entity_StaticBody)
EndProcedure 