collision3d avec création d'escaliers
Publié : dim. 07/nov./2004 16:33
c'est du réchauffé .
J'ai ajouté la lumière , ça ne fonctionnait pas avec l'ancienne Dll .
et j'en ai profité pour ajouter deux procédures pour construire des escaliers , droits , et en colimaçons.
j'utilise cette texture , elle peut être remplacée , ou simplement créée dans le prog .c'est le seul média externe.




et voila le nouveau code
J'ai ajouté la lumière , ça ne fonctionnait pas avec l'ancienne Dll .
et j'en ai profité pour ajouter deux procédures pour construire des escaliers , droits , et en colimaçons.
j'utilise cette texture , elle peut être remplacée , ou simplement créée dans le prog .c'est le seul média externe.
et voila le nouveau code
Code : Tout sélectionner
; *******************************************
; * Comtois : 10/11/04 : DémoCollisionV0.2 *
; *******************************************
; [F1]/[F2]/[F3] => Changement Vue Caméra
; [F4] => Nombre d'images / seconde et positions du perso
; [PAgeUp]/[PageDown] => Lève / 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
;-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 )
Declare.f Cosd( Angle.f )
Declare.f Sind( Angle.f )
Declare MakeColimacon(NoEntity.l,PX.f,PY.f,PZ.f,longueur.l,Hauteur.l,Largeur.l,Nbmarche.l)
Declare MakeEscalier(NoEntity.l,PX.f,PY.f,PZ.f,longueur.l,Hauteur.l,Largeur.l,Angle.f,Nbmarche.l)
Declare.f NewXValue( x.f , Angle.f , NbUnite.f )
Declare.f NewZValue( x.f , Angle.f , NbUnite.f )
;-Structures
Structure BoxCollision
No.l ; Si le type est 1 alors ce Numéro correspond obligatoirement à 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
;- 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
Global AngleVague.f,Vitesse.f
Vitesse.f = 1
;-Mesh
CreateMesh(0) ; Cube
SetMeshData(0, 0, ?CubePoints , 16)
SetMeshData(0, 1, ?CubeTriangles , 12)
SetMeshData(0, 2, ?CubeTextures , 16)
SetMeshData(0, 3, ?CubeNormales , 16)
M3D_CreateMeshMatrix(100,1000,1000,50,50,1)
M3D_CreateMeshMatrix(101,1000,1000,20,20,0)
;- Textures
LoadTexture(1,"Bois1.png")
LoadTexture(2,"swater03.png")
LoadTexture(3,"scave01.png")
LoadTexture(4,"sceram03.png")
;- Material
For a = 1 To 4
CreateMaterial(a, TextureID( a ))
Next a
MaterialBlendingMode(2,#PB_Material_Add)
;-Entity
Restore Entitys
For a = 0 To 3
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
CreateEntity(a , MeshID(0) ,MaterialID(materialID))
ScaleEntity(a , longueur , Hauteur , Largeur )
EntityLocate(a,x,y,z)
entity(a)\AngleX = AngleX
RotateEntity(a,entity(a)\AngleX,0,0)
If a<>1
MakeBoxCollision( a , EntityX(a) , EntityY(a) , EntityZ(a) , longueur, Hauteur , Largeur, entity(a)\AngleX , Type )
EndIf
Next a
FreeEntity(1)
h=7
MakeEscalier(5,300,5,200+14*10,14,h,36,90,10)
MakeEscalier(16,300+11,5+11*h,200-25,14,h,36,0,10)
MakeEscalier(43,300,5+10*h,200+11,36,h,36,90,1)
MakeColimacon(27,500,5,500,50,7,33,15)
;Eau
CreateEntity(100,MeshID(100),MaterialID(2))
EntityLocate(100,500,18,500)
;Fond
CreateEntity(101,MeshID(101),MaterialID(4))
EntityLocate(101,500,0,500)
M3D_PrepareMatrixTexture(100,2,50,50)
For zz=0 To 49
For xx=0 To 49
No = xx + 50 * zz
M3D_TextureFacette(100,xx,zz,No)
If (xx=0 Or xx=19) Or (zz=0 Or zz=19)
M3D_SetFacetteHeight(101,xx,zz,50)
EndIf
Next xx
Next zz
M3D_UpDateTexture(100)
M3D_UpDateTexture(101)
M3D_UpDateVertex(101)
;- Camera
CreateCamera(0, 0, 0 , 100 , 100)
CameraLocate(0,0,0,20)
AmbientColor(RGB(125,125,125))
Camera\CameraVue = 2
;-Lumières
CreateLight(0,RGB(255,255,255))
LightLocate(0 , 100, 500 ,500)
;- Procédures
Procedure vagues()
decaleX.f=19
decaleZ.f=17
Hauteur.f=4
AngleVague = WrapValue(AngleVague + Vitesse)
For z = 0 To 50
For x = 0 To 50
Sommet.f = Sind(AngleVague + (x * decaleX) + (z * decaleZ)) * Hauteur
M3D_SetVertexHeight(100,x,z,Sommet)
Next x
Next z
M3D_UpDateVertex(100)
EndProcedure
Procedure MakeEscalier(NoEntity.l,PX.f,PY.f,PZ.f,longueur.l,Hauteur.l,Largeur.l,Angle.f,Nbmarche.l)
For a = 1 To Nbmarche
CreateEntity(NoEntity , MeshID(0) ,MaterialID(1))
ScaleEntity(NoEntity , longueur , Hauteur , Largeur )
EntityLocate(NoEntity,NewXValue(PX,Angle, a * longueur),PY + (a-1) * Hauteur,NewZValue(PZ,Angle, a * longueur))
entity(NoEntity)\AngleX = Angle
RotateEntity(NoEntity,entity(NoEntity)\AngleX,0,0)
MakeBoxCollision( NoEntity , EntityX(NoEntity) , EntityY(NoEntity) , EntityZ(NoEntity) , longueur , Hauteur , Largeur , entity(NoEntity)\AngleX , 0 )
NoEntity + 1
Next a
EndProcedure
Procedure MakeColimacon(NoEntity.l,PX.f,PY.f,PZ.f,longueur.l,Hauteur.l,Largeur.l,Nbmarche.l)
Angle.f = 0
For a= 1 To Nbmarche
CreateEntity(NoEntity,MeshID(0),MaterialID(1))
ScaleEntity(NoEntity,longueur,Hauteur,Largeur)
EntityLocate(NoEntity,PX + Cosd(Angle) * Largeur,PY + (a-1) * Hauteur,PZ -Sind(Angle) * Largeur)
RotateEntity(NoEntity,Angle,0,0)
MakeBoxCollision( NoEntity , EntityX(NoEntity) , EntityY(NoEntity) , EntityZ(NoEntity) , longueur ,Hauteur, Largeur , Angle , 0)
Angle = WrapValue( Angle + 30 )
NoEntity + 1
Next a
;Colonne
h.f = (a-1) * Hauteur
CreateEntity( NoEntity ,MeshID(0) , MaterialID(1) )
longueur1=2 + Largeur / 2
Largeur1=2 + Largeur / 2
ScaleEntity( NoEntity ,longueur1 , h ,Largeur1 )
EntityLocate( NoEntity , PX , PY + (h-Hauteur) / 2 , PZ )
MakeBoxCollision( NoEntity , EntityX(NoEntity) , EntityY(NoEntity) , EntityZ(NoEntity) , longueur1 ,h,Largeur1, 0 , 0)
EndProcedure
Procedure.f Cosd( Angle.f )
;calcule le cos d'un angle en degré
a.f = Angle * 0.0174533
ProcedureReturn Cos( a )
EndProcedure
Procedure.f Sind( Angle.f )
;calcule le sin d'un angle en degré
a.f = Angle * 0.0174533
ProcedureReturn Sin( a )
EndProcedure
Procedure.f WrapValue(Angle.f)
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 )
;à utiliser conjointement avec NewZvalue pour calculer une position de <NbUnite> dans la direction <angle>
Valeur.f = x + Cosd( Angle ) * NbUnite
ProcedureReturn Valeur
EndProcedure
Procedure.f NewZValue( z.f , Angle.f , NbUnite.f )
;à 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 à 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 à 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 paramètres 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 à 45° à 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 considère 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égèrement 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 paramètres ( 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
ForEach BoxCollision()
If BoxCollision()\No = No1
; Mise à 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écupère 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 à 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écupère 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
Next
; Il manque au moins une box
If Trouve < 2
ProcedureReturn -1
EndIf
;****************************** Changement de repères ****************************************
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 repère
;
; 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 sûrement 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 repère 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()
;Ajouter collision à la caméra .
; 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
vagues()
;ScrollMaterial(3,Random(1)-1,Random(1)-1,#PB_Material_Animated)
If ExamineKeyboard()
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 KeyboardPushed(#PB_Key_Up)
Pas = CurveValue(Pas, 2 , 120)
ElseIf KeyboardPushed(#PB_Key_Down)
Pas = CurveValue(Pas, -2 , 120)
Else
Pas = CurveValue(Pas, 0 , 200)
EndIf
If KeyboardPushed(#PB_Key_Space) And Attraction = 0 And AutoriseSaut
Attraction = 1.6 : 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
If Attraction=0
M3D_MoveEntityXZ(100, 0 , entity(0)\AngleX ,Pas)
Debug "avec M3D"
Else
MoveEntity( 0 , Cosd( entity(0)\AngleX ) * Pas , Attraction, -Sind( entity(0)\AngleX ) * Pas )
Debug "sans M3D"
EndIf
; LE perso après
PosY0 = EntityY(0)
PosX0 = EntityX(0)
PosZ0 = EntityZ(0)
; Gestion de l'attraction
Attraction - DecAttraction
; Test des collisions
ForEach 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)
Next
; Repositionne le perso
EntityLocate(0,PosX0 ,PosY0 ,PosZ0 )
If EntityY(0)<M3D_GetGroundHeight(101,PosX0,PosZ0)+5
EntityLocate(0,PosX0 ,M3D_GetGroundHeight(101,PosX0,PosZ0)+5,PosZ0 )
Attraction = 0
AutoriseSaut = 1
EndIf
; 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 1,1 ; matérial
Data.f 15,10,15 ; 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,16,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,16,600,0 ; positions X,Y,Z et angle
CubePoints:
Data.f -0.5,-0.5,-0.5
Data.f -0.5,-0.5,0.5
Data.f 0.5,-0.5,0.5
Data.f 0.5,-0.5,-0.5
Data.f -0.5,0.5,-0.5
Data.f -0.5,0.5,0.5
Data.f 0.5,0.5,0.5
Data.f 0.5,0.5,-0.5
Data.f -0.5,-0.5,-0.5
Data.f -0.5,-0.5,0.5
Data.f 0.5,-0.5,0.5
Data.f 0.5,-0.5,-0.5
Data.f -0.5,0.5,-0.5
Data.f -0.5,0.5,0.5
Data.f 0.5,0.5,0.5
Data.f 0.5,0.5,-0.5
CubeNormales:
Data.f -1,0,-1
Data.f -1,0,1
Data.f 1,0,1
Data.f 1,0,-1
Data.f -1,0,-1
Data.f -1,0,1
Data.f 1,0,1
Data.f 1,0,-1
Data.f 0,-2,0
Data.f 0,-2,0
Data.f 0,-2,0
Data.f 0,-2,0
Data.f 0,2,0
Data.f 0,2,0
Data.f 0,2,0
Data.f 0,2,0
CubeTriangles:
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
CubeTextures:
;original
Data.f 0,1
Data.f 1,1
Data.f 0,1
Data.f 1,1
Data.f 0,0
Data.f 1,0
Data.f 0,0
Data.f 1,0
Data.f 0,0
Data.f 1,0
Data.f 1,1
Data.f 0,1
Data.f 0,0
Data.f 1,0
Data.f 1,1
Data.f 0,1
EndDataSection