collision3d avec création d'escaliers

Généralités sur la programmation 3D
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

si , ici

http://perso.wanadoo.fr/comtois/sources/colimacon.zip

touches [F1]/[F2]/[F3] pour changer de vue
touche espace pour sauter et le curseur pour se déplacer.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Une version pour la lib Ogre 1.0.3 beta , avec les ombres
Il y a un bug , il y a des ombres fantômes qui ne devraient pas apparaitre .
Est-ce la lib purebasic ou Ogre ?

Code : Tout sélectionner

; **********************************************************
; * Comtois : 30/10/05 : DémoCollision for Ogre 1.0.3 Beta *
; **********************************************************

; [F1]/[F2]/[F3] => Changement Vue Caméra
; [F4] => Nombre d'images / seconde et positions du perso
; [PAgeUp]/[PageDown] => Lcve / Baisse la caméra
; [Fin] => Position par défaut de la caméra
; [Espace] => Saut du perso


;-Initialisation
#ScreenWidth = 800 : #ScreenHeight = 600 : #ScreenDepth =32
If InitEngine3D() = 0
   MessageRequester( "Erreur" , "Impossible d'initialiser la 3D , vérifiez la présence de engine3D.dll" , 0 )
   End
ElseIf InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 Or InitSound() = 0
   MessageRequester( "Erreur" , "Impossible d'initialiser DirectX 7 Ou plus" , 0 )
   End
ElseIf OpenScreen( #ScreenWidth , #ScreenHeight , #ScreenDepth , "Démo PlateForme" ) = 0
   MessageRequester( "Erreur" , "Impossible d'ouvrir l'écran " , 0 )
   End
EndIf

#PB_Shadow_Modulative = 1 ; Black shadow (fast)
#PB_Shadow_Additive = 2   ; Additive translucent shadow (more expensive with severl lights)

WorldShadows(#PB_Shadow_Additive) ; Set the shadow mode for the world

; The data has to be organize in this order: Vertex, COlor, Normal, UVCoordinate (per vertex)
;
#PB_Mesh_Vertex       = 1 << 0
#PB_Mesh_Color        = 1 << 1
#PB_Mesh_Normal       = 1 << 2
#PB_Mesh_UVCoordinate = 1 << 3

; Additionnnal flag to specify the faces
;
#PB_Mesh_Face         = 1 << 4
#SQRT13 = 0.57735026    
;-Declare procedures
Declare MakeBoxCollision( No.l , x.f , y.f , Z.f , Longueur.f , Hauteur.f , Largeur.f , AngleX.f , Type.l )
Declare.f WrapValue( Angle.f )

;-Structures
Structure BoxCollision
   No.l      ; Si le type est 1 alors ce Numéro correspond obligatoirement r l'entity , sinon c'est un numéro différent des entitys existantes
   x.f       ; Position en X de la Box
   y.f       ; Position en Y de la Box
   Z.f       ; Position en Z de la Box
   AngleX.f  ; Angle de la Box sur le Plan XZ
   MinX.f    ; Dimension de la Box
   MinY.f    ; Dimension de la Box
   MinZ.f    ; Dimension de la Box
   MaxX.f    ; Dimension de la Box
   MaxY.f    ; Dimension de la Box
   MaxZ.f    ; Dimension de la Box
   Type.l    ; Type = 0 => Box Statique ; Type = 1 => Box Dynamique ( presque plus utile avec la nouvelle méthode )
EndStructure

Structure Camera
   AngleX.f
   AngleY.f
   CameraVue.l
   CameraDist.f
   CameraHaut.f
   LookAtY.f
EndStructure

Structure Parametres
   AngleX.f
   AngleY.f
   AngleZ.f
EndStructure

Dim entity.Parametres(100)

NewList BoxCollision.BoxCollision()
Global Camera.Camera
Camera\CameraVue = 1

;- Variables globales
Global GetCollisionX.f , GetCollisionY.f , GetCollisionZ.f
Global OldPosX.f , OldPosY.f , OldPosZ.f , Pas.f
Global PosX0.f , PosY0.f , PosZ0.f

;-Mesh
CreateMesh(0)
Flag = #PB_Mesh_Vertex | #PB_Mesh_Normal | #PB_Mesh_UVCoordinate  
SetMeshData(No,Flag         ,?CubeBuffer,16)
SetMeshData(No,#PB_Mesh_face,?IndexCube,12)

;- Textures
CreateTexture(1,128,128)
StartDrawing(TextureOutput(1))
  Box(0,0,128,128,RGB(255,255,255))
  Box(2,2,124,124,RGB(200,0,0))
StopDrawing()

CreateTexture(2,128,128)
StartDrawing(TextureOutput(2))
  Box(0,0,128,128,RGB(255,255,255))
  Box(2,2,124,124,RGB(0,0,200))
StopDrawing()

CreateTexture(3,128,128)
StartDrawing(TextureOutput(3))
  Box(0,0,128,128,RGB(255,255,255))
  Box(2,2,124,124,RGB(0,200,0))
  For a = 0 To 128 Step 4
   For b = 0 To 128 Step 4
      Circle(a,b,2,RGB(10,150,10))
   Next b
Next a
StopDrawing()

;- Material
For a = 1 To 3
   CreateMaterial(a, TextureID( a ))
Next a

;-Entity
Restore Entitys
For a = 0 To 20
   If a < 5
      Read MaterialId.l : Read Type.l
      Read Longueur.f : Read Hauteur.f : Read Largeur.f
      Read x.f : Read y.f : Read Z.f
      Read AngleX.f
   EndIf
   CreateEntity(a , MeshID(0) ,MaterialID(MaterialId))
   ScaleEntity(a , Longueur , Hauteur , Largeur )
   If a<5
      EntityLocate(a,x,y,Z)
   Else
      EntityLocate(a,x + a * 40,y + a * 20,Z)
   EndIf
   entity(a)\AngleX = AngleX
   RotateEntity(a,entity(a)\AngleX,0,0)
   MakeBoxCollision( a , EntityX(a) , EntityY(a) , EntityZ(a) , Longueur , Hauteur , Largeur , entity(a)\AngleX , Type )
Next a
;Le sol
EntityRenderMode(1, 0)

;- Camera
CreateCamera(0, 0, 0 , 100 , 100)
CameraLocate(0,0,0,20)
AmbientColor(RGB(115,115,115))

;-Light
CreateLight(0,RGB(255,255,255))
LightLocate(0, 500, 900, 500)

;- Procédures
Procedure.f Cosd( Angle.f )
   ;calcule le cos d'un angle en degré
    
   ProcedureReturn Cos(Angle * 0.0174533)
EndProcedure

Procedure.f Sind( Angle.f )
   ;calcule le sin d'un angle en degré
   ProcedureReturn Sin(Angle  * 0.0174533)
EndProcedure

Procedure.f WrapValue( Angle.f )
   ;Permet de toujours avoir un angle compris entre 0° et 360°
	Angle/360 
  	Angle-Int(Angle) 
  	If Angle<0 
    	ProcedureReturn (Angle+1)*360 
  	Else 
    	ProcedureReturn Angle*360 
  	EndIf 
EndProcedure

Procedure.f NewXValue( x.f , Angle.f , NbUnite.f )
   ;a utiliser conjointement avec NewZvalue pour calculer une position de <NbUnite> dans la direction <angle>
   ProcedureReturn x + Cosd( Angle ) * NbUnite
EndProcedure

Procedure.f NewZValue( Z.f , Angle.f , NbUnite.f )
   ;a utiliser conjointement avec NewXvalue pour calculer une position de <NbUnite> dans la direction <angle>
   Valeur.f = Z - Sind( Angle ) * NbUnite
   ProcedureReturn Valeur
EndProcedure

Procedure.f EcartAngle( angle1.f , angle2.f )
	Delta.f=Angle2-Angle1 
  	If Delta>180 
    	ProcedureReturn Delta-360 
  	ElseIf Delta<=-180 
    	ProcedureReturn Delta+360 
  	Else 
    	ProcedureReturn Delta 
  	EndIf  
EndProcedure

Procedure.f curveangle( Actuelle.f , Cible.f , P.f )
   ;Calcule un angle progressif allant de la valeur actuelle a la valeur cible
   Delta.f = EcartAngle( Actuelle , Cible )
   If P > 1000 : P = 1000 : EndIf
   Valeur.f = Actuelle + ( Delta * P / 1000 )
   ProcedureReturn WrapValue( Valeur )
EndProcedure

Procedure.f curvevalue( Actuelle.f , Cible.f , P.f )
   ;Calcule une valeur progressive allant de la valeur actuelle a la valeur cible
   Delta.f = Cible - Actuelle
   If P > 1000 : P = 1000 : EndIf
   Valeur.f = Actuelle + ( Delta * P / 1000 )
   ProcedureReturn Valeur
EndProcedure

Procedure MakeBoxCollision( No.l , x.f , y.f , Z.f , Longueur.f , Hauteur.f , Largeur.f , AngleX.f , Type.l )
   ; X , Y et Z => Coordonnées de la Box
   ; Longueur   => Longueur de la Box
   ; Hauteur    => Hauteur de la Box
   ; Largeur    => Largeur de la Box
   ; AngleX     => Angle de la Box sur le plan XZ ( je n'ai pas besoin des autres plans pour l'instant )
   ; Type = 0   => Box statique ( calculée une seule fois , exemple pour un mur , un décor quelconque )
   ; Type = 1   => Box dynamique ( calculée avant de tester une collision selon la position de l'entity )


   ; MinZ .........|..........
   ;      .        |         .
   ;      .        |         .
   ;    -----------0--------------
   ;      .        |         .
   ;      .        |         .
   ; MaxZ .........|..........
   ;
   ;    MinX               MaxX

   ; Les paramctres MinX.f , MinY.f , MinZ.f , MaxX.f , MaxY.f , MaxZ.f , correspondent aux dimensions de la box en prenant
   ; le centre de l'entity comme référence (0) .

   ; Exemple pour un mur de longueur x = 400 , hauteur y = 100 et largeur z = 30
   ; ensuite si on veut placer le mur r 45° r la position 1500,50,300
   ; EntityLocate(#Mur,1500,50,300)
   ; RotateEntity(#Mur,45,0,0)
   ; Entity(#Mur)\\AngleX = 45
   ; et on appelle la Procedure
   ; MakeBoxCollision( #Mur , EntityX(#Mur) , EntityY(#Mur) , EntityZ(#Mur) , 400 , 100 , 30 , Entity(#Mur)\\AngleX , 0 )

   ; Pour l'instant je considere que la Box est centré sur l'entity , si ça devait par la suite se révéler trop contraignant
   ; il sera toujours possible de modifier légerement cette procédure ainsi :
   ; Procedure MakeBoxCollision( No.l, X.f, Y.f, Z.f, MinX.f, MinY.f, MinZ.f, MaxX.f, MaxY.f, MaxZ.f, AngleX.f, Type.l )

   AddElement( BoxCollision() )
   BoxCollision()\No = No
   BoxCollision()\x = x
   BoxCollision()\y = y
   BoxCollision()\Z = Z
   BoxCollision()\MinX = -Longueur/2
   BoxCollision()\MinY = -Hauteur/2
   BoxCollision()\MinZ = -Largeur/2
   BoxCollision()\MaxX = Longueur/2
   BoxCollision()\MaxY = Hauteur/2
   BoxCollision()\MaxZ = Largeur/2
   BoxCollision()\AngleX = AngleX
   BoxCollision()\Type = Type

EndProcedure

Procedure.l EntityCollision( No1.l , No2.l )
   ; La procedure renvoit -1 en cas d'erreur de parametres ( Box inexistante , Box 1 et 2 identiques )
   ; La procedure renvoit 0 si aucune Collision
   ; La procedure renvoit 1 si la Box No1 est en Collision avec la Box No2

   If No1 = No2 :  ProcedureReturn -1 : EndIf

   ;************************************** Cherche Box *******************************************

   Trouve = 0
   ResetList( BoxCollision() )
   While NextElement( BoxCollision() )
      If BoxCollision()\No = No1

         ; Mise a Jour des caractériques de la Box
         If BoxCollision()\Type = 1
            BoxCollision()\x = EntityX(No1)
            BoxCollision()\y = EntityY(No1)
            BoxCollision()\Z = EntityZ(No1)
            BoxCollision()\AngleX = entity(No1)\AngleX
         EndIf

         ; On récupere les caractéristiques de la Box No1
         PosX1.f = BoxCollision()\x
         PosY1.f = BoxCollision()\y
         PosZ1.f = BoxCollision()\Z
         MinX1.f = BoxCollision()\MinX
         MinY1.f = BoxCollision()\MinY
         MinZ1.f = BoxCollision()\MinZ
         MaxX1.f = BoxCollision()\MaxX
         MaxY1.f = BoxCollision()\MaxY
         MaxZ1.f = BoxCollision()\MaxZ
         AngleX1.f = BoxCollision()\AngleX

         Trouve + 1

      ElseIf BoxCollision()\No = No2

         ; Mise a Jour des caractériques de la Box
         If BoxCollision()\Type = 1
            BoxCollision()\x = EntityX(No2)
            BoxCollision()\y = EntityY(No2)
            BoxCollision()\Z = EntityZ(No2)
            BoxCollision()\AngleX = entity(No2)\AngleX
         EndIf

         ; On récupere les caractéristiques de la Box No2
         PosX2.f = BoxCollision()\x
         PosY2.f = BoxCollision()\y
         PosZ2.f = BoxCollision()\Z
         MinX2.f = BoxCollision()\MinX
         MinY2.f = BoxCollision()\MinY
         MinZ2.f = BoxCollision()\MinZ
         MaxX2.f = BoxCollision()\MaxX
         MaxY2.f = BoxCollision()\MaxY
         MaxZ2.f = BoxCollision()\MaxZ
         AngleX2.f = BoxCollision()\AngleX

         Trouve + 1

      EndIf

      If Trouve = 2 : Break : EndIf

   Wend

   ; Il manque au moins une box
   If Trouve < 2
      ProcedureReturn -1
   EndIf

   ;****************************** Changement de reperes ****************************************
   CosA1.f = Cosd( AngleX1 )
   SinA1.f = -Sind( AngleX1 )
   CosA2.f = Cosd( AngleX2 )
   SinA2.f = Sind( AngleX2 )
   PosX.f  = PosX1 - PosX2
   PosY.f  = PosY1 - PosY2
   PosZ.f  = PosZ1 - PosZ2
   a1.f    = (CosA1 * CosA2 - SinA1 * SinA2)
   a2.f    = (SinA1 * CosA2 + CosA1 * SinA2)
   A3.f    = (PosX * CosA2 - PosZ * SinA2)
   A4.f    = (PosX * SinA2 + PosZ * CosA2)

   ; Calcul les 4 coins de la Box sur le plan XZ en tenant compte du changement de repcre
   ;
   ; MinX1/MinZ1(0)  ______    MaxX1/MinZ1(1)
   ;                 \     \
   ;                  \     \
   ;                   \     \
   ; MinX1/MaxZ1(3)     \_____\ MaxX1/MaxZ1(2)
   ;

   ; Et ensuite on détermine une Box qui englobe le tout ( pas précis , mais plus simple )
   ; BoxMinX/BoxMinZ.............BoxMaxX/BoxMinZ
   ;                . ______    .
   ;                . \     \   .
   ;                .  \     \  .
   ;                .   \     \ .
   ;                .    \_____\.
   ; BoxMinX/BoxMaxZ.............BoxMaxX/BoxMaxZ
   ;
   ;MinX1/MinZ1
   X0.f = MinX1 * a1 - MinZ1 * a2 + A3
   Z0.f = MinX1 * a2 + MinZ1 * a1 + A4

   BoxMinX.f = X0
   BoxMinZ.f = Z0
   BoxMaxX.f = X0
   BoxMaxZ.f = Z0

   ;MaxX1/MinZ1
   X1.f = MaxX1 * a1 - MinZ1 * a2 + A3
   Z1.f = MaxX1 * a2 + MinZ1 * a1 + A4

   If X1 < BoxMinX
      BoxMinX = X1
   ElseIf  X1 > BoxMaxX
      BoxMaxX = X1
   EndIf
   If Z1 < BoxMinZ
      BoxMinZ = Z1
   ElseIf  Z1 > BoxMaxZ
      BoxMaxZ = Z1
   EndIf

   ;MaxX1/MaxZ1
   X2.f = MaxX1 * a1 - MaxZ1 * a2 + A3
   Z2.f = MaxX1 * a2 + MaxZ1 * a1 + A4

   If X2 < BoxMinX
      BoxMinX = X2
   ElseIf  X2 > BoxMaxX
      BoxMaxX = X2
   EndIf
   If Z2 < BoxMinZ
      BoxMinZ = Z2
   ElseIf  Z2 > BoxMaxZ
      BoxMaxZ = Z2
   EndIf

   ;MinX1/MaxZ1
   X3.f = MinX1 * a1 - MaxZ1 * a2 + A3
   Z3.f = MinX1 * a2 + MaxZ1 * a1 + A4

   If X3 < BoxMinX
      BoxMinX = X3
   ElseIf  X3 > BoxMaxX
      BoxMaxX = X3
   EndIf
   If Z3 < BoxMinZ
      BoxMinZ = Z3
   ElseIf  Z3 > BoxMaxZ
      BoxMaxZ = Z3
   EndIf
   BoxMinY.f = MinY1 + PosY
   BoxMaxY.f = MaxY1 + PosY

   ;**************************** Test si Collision *************************************************
   ; BoxMinX/BoxMinZ.............BoxMaxX/BoxMinZ    MinX2/MinZ2.............MaxX2/MaxZ2
   ;                . ______    .                              .           .
   ;                . \     \   .                              .           .
   ;                .  \     \  .                              .           .
   ;                .   \     \ .                              .           .
   ;                .    \_____\.                              .           .
   ; BoxMinX/BoxMaxZ.............BoxMaxX/BoxMaxZ    MinX2/MaxZ2.............MaxX2/MaxZ2
   CondX = (BoxMaxX >= MinX2 And BoxMinX <= MaxX2)
   CondY = (BoxMaxY >= MinY2 And BoxMinY <= MaxY2)
   CondZ = (BoxMaxZ >= MinZ2 And BoxMinZ <= MaxZ2) 

   ;Utilisé pour les collisions glissantes
   GetCollisionX = 0
   GetCollisionY = 0
   GetCollisionZ = 0

   If CondY And CondX And CondZ
      ; il serait surement plus judicieux de ne faire ces calculs que s'ils sont demandés
      ; en effet , dans de nombreux cas , on a seulement besoin de savoir s'il y a une collision
      ; et pas forcément de calculer une collision glissante !
      ;Collision en X
      If BoxMinX < MaxX2 And BoxMinX > MinX2 And BoxMaxX > MaxX2
         GetCollisionXa.f =  BoxMinX - MaxX2
      ElseIf BoxMaxX < MaxX2 And BoxMaxX > MinX2 And BoxMinX < MinX2
         GetCollisionXa.f =  BoxMaxX - MinX2
      EndIf

      ; a voir pour traiter ça autrement ! > c'est pour éviter de tomber quand on s'approche trop du bord d'une box !
      If Abs(GetCollisionXa) > 3
         GetCollisionXa = 0
      EndIf

      ; Collision en Z
      If BoxMinZ < MaxZ2 And BoxMaxZ > MaxZ2 And BoxMaxZ > MaxZ2
         GetCollisionZa.f =  BoxMinZ - MaxZ2
      ElseIf BoxMaxZ < MaxZ2 And BoxMaxZ > MinZ2 And BoxMinZ < MinZ2
         GetCollisionZa.f =  BoxMaxZ - MinZ2
      EndIf

      ; A voir pour traiter ça autrement ! > c'est pour éviter de tomber quand on s'approche trop du bord d'une box !
      If Abs(GetCollisionZa) > 3
         GetCollisionZa = 0
      EndIf

      ;Collision en Y
      If BoxMinY < MaxY2 And BoxMinY > MinY2 And BoxMaxY > MaxY2 And GetCollisionXa = 0 And GetCollisionZa = 0
         GetCollisionY =  BoxMinY - MaxY2
      ElseIf BoxMaxY < MaxY2 And BoxMaxY> MinY2 And BoxMinY < MinY2 And OldPosY < PosY0
         GetCollisionY =  BoxMaxY - MinY2
      EndIf

      ;Changement de repcre des valeurs Collisions glissantes
      CosA2.f = Cosd( -AngleX2 )
      SinA2.f = Sind( -AngleX2 )
      GetCollisionX = GetCollisionXa * CosA2 - GetCollisionZa * SinA2
      GetCollisionZ = GetCollisionXa * SinA2 + GetCollisionZa * CosA2

      ProcedureReturn 1

   Else

      ProcedureReturn 0

   EndIf

EndProcedure

Procedure GestionCamera()

   ; Touches de la Caméra
   If KeyboardReleased(#PB_Key_F1) : camera\CameraVue = 1 : EndIf
   If KeyboardReleased(#PB_Key_F2) : camera\CameraVue = 2 : EndIf
   If KeyboardReleased(#PB_Key_F3) : camera\CameraVue = 3 : EndIf

   If KeyboardPushed(#PB_Key_PageUp)
      camera\AngleY + 0.1
   EndIf

   If KeyboardPushed(#PB_Key_PageDown)
      camera\AngleY - 0.1
   EndIf

   If KeyboardPushed(#PB_Key_End)
      camera\AngleY = curvevalue(camera\AngleY,0,20)
   EndIf

   If camera\CameraVue = 1

      camera\CameraDist = curvevalue(camera\CameraDist ,85 , 20)
      camera\CameraHaut = curvevalue(camera\CameraHaut ,25 , 20)
      camera\LookAtY = curvevalue(camera\LookAtY ,0 , 20)
      camera\AngleX = curveangle(camera\AngleX , entity(0)\AngleX , 20 )
      PosXCamera.f = curvevalue(CameraX(0) , newxvalue(EntityX(0) , camera\AngleX + 180 , camera\CameraDist) , 280)
      PosYCamera.f = curvevalue(CameraY(0) , EntityY(0) + camera\CameraHaut , 30)
      PosZCamera.f = curvevalue(CameraZ(0) , newzvalue(EntityZ(0) , camera\AngleX + 180 , camera\CameraDist) , 280)
      CameraLocate(0 , PosXCamera , PosYCamera , PosZCamera)
      CameraLookAt(0 , EntityX(0), EntityY(0) + camera\LookAtY + camera\AngleY  ,EntityZ(0))

   ElseIf camera\CameraVue = 2

      camera\CameraDist = curvevalue(camera\CameraDist ,45 , 20)
      camera\CameraHaut = curvevalue(camera\CameraHaut ,25 , 20)
      camera\LookAtY = curvevalue(camera\LookAtY , 8 , 20)
      camera\AngleX = curveangle(camera\AngleX , entity(0)\AngleX , 20 )
      PosXCamera.f = curvevalue(CameraX(0) , newxvalue(EntityX(0) , camera\AngleX + 180 , camera\CameraDist) , 280)
      PosYCamera.f = curvevalue(CameraY(0) , EntityY(0) + camera\CameraHaut , 30)
      PosZCamera.f = curvevalue(CameraZ(0) , newzvalue(EntityZ(0) , camera\AngleX + 180 , camera\CameraDist) , 280)
      CameraLocate(0 , PosXCamera , PosYCamera , PosZCamera)
      CameraLookAt(0 , EntityX(0), EntityY(0) + camera\LookAtY + camera\AngleY  ,EntityZ(0))

   ElseIf camera\CameraVue = 3

      camera\CameraDist = curvevalue(camera\CameraDist ,15 , 20)
      camera\CameraHaut = curvevalue(camera\CameraHaut ,95 , 20)
      camera\LookAtY = curvevalue(camera\LookAtY , 0 , 20)
      camera\AngleX = curveangle(camera\AngleX , entity(0)\AngleX , 20 )
      PosXCamera.f = curvevalue(CameraX(0) , newxvalue(EntityX(0) , camera\AngleX + 180 , camera\CameraDist) , 280)
      PosYCamera.f = curvevalue(CameraY(0) , EntityY(0) + camera\CameraHaut , 30)
      PosZCamera.f = curvevalue(CameraZ(0) , newzvalue(EntityZ(0) , camera\AngleX + 180 , camera\CameraDist) , 280)
      CameraLocate(0 , PosXCamera , PosYCamera , PosZCamera)
      CameraLookAt(0 , EntityX(0) , EntityY(0) + camera\LookAtY + camera\AngleY  , EntityZ(0))

   EndIf

EndProcedure

Procedure AffAide()
   StartDrawing(ScreenOutput())
   Locate(10,10)
   DrawText("Nombre d'images Minimum = " + StrF(Engine3DFrameRate(#PB_Engine3D_Minimum )) + " / Nombre d'images Maximum = " + StrF(Engine3DFrameRate(#PB_Engine3D_Maximum)))
   Locate(10,30)
   DrawText("Nombre d'images par seconde = " + StrF(Engine3DFrameRate(#PB_Engine3D_Current)))
   Locate(10,50)
   DrawText(StrF(EntityX(0)) + " / " + StrF(EntityY(0)) + " / " + StrF(EntityZ(0)))
   StopDrawing()
EndProcedure

;- Boucle principale

DecAttraction.f = 0.05
Attraction.f = 0
Pas.f = 0

Repeat

   ClearScreen(0, 0, 0)

   If ExamineKeyboard()

      ; Touches du joueur a mettre dans une procédure  et gérer un fichier préférence pour configurer les touches
      If KeyboardPushed(#PB_Key_Left)
         entity(0)\AngleX = wrapvalue( entity(0)\AngleX + 1 )
         RotateEntity(0,1 , 0, 0 )
      ElseIf KeyboardPushed(#PB_Key_Right)
         entity(0)\AngleX = wrapvalue( entity(0)\AngleX - 1 )
         RotateEntity(0, -1 , 0, 0 )
      EndIf
If attraction=0
	Vit=12
Else
	Vit=400
EndIf
      If KeyboardPushed(#PB_Key_Up)
         Pas = curvevalue(Pas, 2 , Vit)
      ElseIf KeyboardPushed(#PB_Key_Down)
         Pas = curvevalue(Pas, -2 , Vit)
      Else
         Pas = curvevalue(Pas, 0 , 200)
      EndIf

      If KeyboardPushed(#PB_Key_Space) And Attraction = 0 And  AutoriseSaut
         Attraction = 1.8 : DecAttraction = 0.05
      EndIf

      If KeyboardReleased(#PB_Key_F4) : AfficheAide = 1 - AfficheAide : EndIf

   EndIf


   ; LE perso avant
   OldPosY = EntityY(0)
   OldPosX = EntityX(0)
   OldPosZ = EntityZ(0)

   ; LE perso pendant
   MoveEntity( 0 , Cosd( entity(0)\AngleX ) * Pas , Attraction, -Sind( entity(0)\AngleX ) * Pas )

   ; LE perso apres
   PosY0 = EntityY(0)
   PosX0 = EntityX(0)
   PosZ0 = EntityZ(0)

   ; Gestion de l'attraction
   Attraction - DecAttraction

   ; Test des collisions

   ResetList(BoxCollision())
   While NextElement(BoxCollision())

      NoBox = BoxCollision()\No
      IndexBoxCollision = ListIndex(BoxCollision())

      If EntityCollision( 0 , NoBox ) > 0

         ; Collision glissante
         PosY0 - GetCollisionY
         PosX0 - GetCollisionX
         PosZ0 - GetCollisionZ

         If GetCollisionY <> 0
            If OldPosY < PosY0 And GetCollisionY > 0; pour ne pas rester coller sous une dalle quand on saute !!
               Attraction = -0.1
               AutoriseSaut = 0
            Else
               Attraction = 0
               AutoriseSaut = 1
            EndIf
         EndIf

      EndIf

      SelectElement(BoxCollision(), IndexBoxCollision)

   Wend

   ; Repositionne le perso
   EntityLocate(0,PosX0 ,PosY0 ,PosZ0 )

   ; Gestion de la caméra
   GestionCamera()

   RenderWorld()
   If AfficheAide : AffAide(): EndIf
   FlipBuffers()

Until KeyboardPushed(#PB_Key_Escape)


;-Datas du Cube

DataSection
Entitys:
; le perso
Data.l 2,1 ; matérial
Data.f 6,6,6 ; Dimension longueur , hauteur , largeur
Data.f 200,30,200,0 ; positions X,Y,Z et angle
; le sol
Data.l 3,0 ; matérial
Data.f 1000,8,1000 ; Dimension longueur , hauteur , largeur
Data.f 500,0,500,0 ; positions X,Y,Z et angle
; Un mur
Data.l 1,0 ; matérial
Data.f 100,25,10 ; Dimension longueur , hauteur , largeur
Data.f 400,17,400,45 ; positions X,Y,Z et angle
; Un autre mur
Data.l 1,0 ; matérial
Data.f 100,25,10 ; Dimension longueur , hauteur , largeur
Data.f 600,17,600,0 ; positions X,Y,Z et angle
; et un escalier
Data.l 1,0 ; matérial
Data.f 35,5,35 ; Dimension longueur , hauteur , largeur
Data.f 200,-80,700,0 ; positions X,Y,Z et angle


CubeBuffer: 
Data.f -0.5,-0.5,-0.5 
Data.f -1,0,-1 
Data.f 0,1 
Data.f -0.5,-0.5,0.5 
Data.f -1,0,1 
Data.f 1,1 
Data.f 0.5,-0.5,0.5 
Data.f 1,0,1 
Data.f 0,1 
Data.f 0.5,-0.5,-0.5 
Data.f 1,0,-1 
Data.f 1,1 
Data.f -0.5,0.5,-0.5 
Data.f -1,0,-1 
Data.f 0,0 
Data.f -0.5,0.5,0.5 
Data.f -1,0,1 
Data.f 1,0 
Data.f 0.5,0.5,0.5 
Data.f 1,0,1
Data.f 0,0 
Data.f 0.5,0.5,-0.5 
Data.f 1,0,-1 
Data.f 1,0 
Data.f -0.5,-0.5,-0.5 
Data.f 0,-1,0 
Data.f 0,0
Data.f -0.5,-0.5,0.5 
Data.f 0,-1,0 
Data.f 1,0 
Data.f 0.5,-0.5,0.5 
Data.f 0,-1,0 
Data.f 1,1 
Data.f 0.5,-0.5,-0.5 
Data.f 0,-1,0 
Data.f 0,1 
Data.f -0.5,0.5,-0.5 
Data.f 0,1,0 
Data.f 0,0
Data.f -0.5,0.5,0.5 
Data.f 0,1,0 
Data.f 1,0 
Data.f 0.5,0.5,0.5 
Data.f 0,1,0 
Data.f 1,1
Data.f 0.5,0.5,-0.5 
Data.f 0,1,0 
Data.f 0,1 

IndexCube: 
Data.w 0,4,7 
Data.w 0,7,3 
Data.w 1,5,4 
Data.w 1,4,0 
Data.w 2,6,5 
Data.w 2,5,1 
Data.w 3,7,6 
Data.w 3,6,2 
Data.w 9,8,11 
Data.w 9,11,10 
Data.w 12,13,14 
Data.w 12,14,15 
EndDataSection
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Répondre