Comme je ne bosse plus dessus depuis un moment , autant la mettre ici.
Code : Tout sélectionner
; ****************************
; ** Comtois **
; ** 06/11/04 **
; ****************************
; ** DemoPlateforme - Forum **
; ****************************
;Ajout des lumières le 06/11/04
;-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 , "Demo PlateForme" ) = 0
MessageRequester( "Erreur" , "Impossible d'ouvrir l'écran " , 0 )
End
EndIf
SetFrameRate(0)
; JPEG pour les Textures
UseJPEGImageDecoder()
;-Declare procedures
Declare MakeBoxCollision( No.l , x.f , y.f , z.f , longueur.f , Hauteur.f , Largeur.f , AngleX.f , Type.l )
Declare.f Cosd( Angle.f )
Declare.f Sind( Angle.f )
Declare.f WrapValue( Angle.f )
Declare Decompresse(Fichier$)
Declare PrepareNiveau()
Declare OpenCamera(No.l)
Declare CloseCamera(No.l)
Declare AffScore()
;- Constantes
Enumeration 1
#BoxHorizontaleX
#BoxVerticaleY
#BoxHorizontaleZ
#BoxBonus
#BoxTombe
#BoxAction
#BoxInterrupteurV
#BoxInterrupteurH
EndEnumeration
;-Structures
Structure BoxCollision
No.l ; Si le type est 1 alors ce Numéro correspond obligatoirement à l'entity , sinon ça peut être 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 ( ça devrait être Y , j'ai encore rien compris à ça :)
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
EndStructure
Structure Camera
AngleX.f
AngleY.f
CameraVue.l
CameraDist.f
CameraHaut.f
LookAtY.f
EndStructure
Structure Parametres
AngleX.f ;
AngleY.f ;
AngleZ.f ;
Param1.f ; Paramètre 1 , différent selon le type d'animation (voir détails dans les procédures d'animation)
Param2.f ; Paramètre 2 , différent selon le type d'animation (voir détails dans les procédures d'animation)
Param3.f ; Paramètre 3 , différent selon le type d'animation (voir détails dans les procédures d'animation)
Param4.f ; Paramètre 4 , différent selon le type d'animation (voir détails dans les procédures d'animation)
Param5.f ; Paramètre 5 , différent selon le type d'animation (voir détails dans les procédures d'animation)
Vitesse.f ; vitesse de déplacement de l'entity
Mini.f ; Position mini de l'entity
Maxi.f ; Position maxi de l'entity
Duree.l ; durée avant qu'une dalle tombe ou un truc explose ou disparaisse ou etc...
Tps.l ; Temps en cours
NoCollision.l ; No de l'objet en collision >>> pour corriger la position du perso s'il est posé sur cette entity
CollisionX.f ; Valeur de GetcollisionX >>> seulement si l'entity n'est pas en contact avec autre chose !
CollisionZ.f ; Valeur de GetcollisionZ
EndStructure
NewList BoxCollision.BoxCollision()
NewList BoxHorizontaleX.l() ; valable pour les plaques qui se déplacent sur l'axe des X
NewList BoxVerticaleY.l() ; valable pour les plaques qui se déplacent sur l'axe des Y ( ascenseur )
NewList BoxHorizontaleZ.l() ; valable pour les plaques qui se déplacent sur l'axe des Z
NewList BoxInterrupteurH.l();
NewList BoxInterrupteurV.l();
NewList BoxAction.l();
NewList BoxBonus.l() ;
NewList BoxSauve.l() ; pas encore géré => quand on perd on revient à la position de cette entity ( dernière )
Global Camera.Camera
Camera\CameraVue = 2
;- 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 , Compteur.l ,IndexBoxCollision.l
Global CompteurBonus.l
;-Mesh
CreateMesh(0) ;Cube
SetMeshData(0,#PB_Mesh_Vertices , ?CubePoints , 16)
SetMeshData(0,#PB_Mesh_Triangles , ?CubeTriangles , 12)
SetMeshData(0,#PB_Mesh_UVCoordinates, ?CubeTextures , 16)
SetMeshData(0,#PB_Mesh_Normals , ?CubeNormales , 16)
CreateMesh(1) ;Plain
SetMeshData(1,#PB_Mesh_Vertices , ?PlainPoints , 4)
SetMeshData(1,#PB_Mesh_Triangles , ?PlainTriangles , 4)
SetMeshData(1,#PB_Mesh_UVCoordinates, ?PlainTextures , 4)
SetMeshData(1,#PB_Mesh_Normals , ?PlainNormales , 4)
;- Textures
NbTexture=28
For a = 1 To NbTexture
CreateTexture(a,128,128)
StartDrawing(TextureOutput(a))
Box(0,0,128,128,RGB(255,255,255))
Box(1,1,126,126,RGB(80+Random(170),50+Random(200),255-Random(200)))
StopDrawing()
Next a
CreateTexture(NbTexture+1,128,128)
StartDrawing(TextureOutput(NbTexture+1))
Box(0,0,128,128,RGB(170,170,250))
StopDrawing()
;- Matière
For a = 1 To NbTexture
CreateMaterial(a, TextureID( a ))
MaterialFilteringMode( a , #PB_Material_Trilinear )
Next a
MaterialBlendingMode(1,#PB_Material_Add | #PB_Material_Color)
MaterialBlendingMode(2,#PB_Material_Add | #PB_Material_Color)
CreateMaterial(NbTexture+1, TextureID( NbTexture+1 ))
MaterialFilteringMode(NbTexture+1 , #PB_Material_Trilinear )
MaterialBlendingMode(NbTexture+1,#PB_Material_Add | #PB_Material_Color)
;-Lumières
CreateLight(0,RGB(255,255,255))
LightLocate(0 , 250 , 800 ,250)
CreateLight(1,RGB(55,55,255))
LightLocate(1 , 500 , 800 ,500)
;-Entity
PrepareNiveau()
;-Skydome
;Add3DArchive("Textures\Skybox.zip", #PB_3DArchive_Zip)
;SkyBox("Stevecube.jpg")
;- Camera
CreateCamera(0, 0, 0 , 100 , 100)
CameraLocate(0,0,0,20)
AmbientColor(RGB(95,95,95))
;- Procédures
Procedure PrepareNiveau()
;Normalement c'est un fichier qui est lu ici ,
;j'ai mis les données du fichier dans les datas pour que le code puisse fonctionner avec un seul fichier
Restore Niveau1
Read t$ : Compteur.l = Val(t$) ; Nombre d'entitys paramétrées
Read t$ : NoMax.l = Val(t$) ; No de la dernière entity utilisée
Dim entity.Parametres(Compteur)
For a = 1 To Compteur
; lecture des paramètres issus du tableau Excel
Read t$ : No.l = Val(t$)
Read t$ : NoMesh.l = Val(t$)
Read t$ : NoMaterial.l = Val(t$)
Read t$ : PX.f = ValF(t$)
Read t$ : PY.f = ValF(t$)
Read t$ : PZ.f = ValF(t$)
Read t$ : SX.f = ValF(t$)
Read t$ : SY.f = ValF(t$)
Read t$ : SZ.f = ValF(t$)
Read t$ : AX.f = ValF(t$)
Read t$ : AY.f = ValF(t$)
Read t$ : AZ.f = ValF(t$)
Read t$ : Anime.l = Val(t$)
Read t$ : Vitesse.f = ValF(t$)
Read t$ : Mini.f = ValF(t$)
Read t$ : Maxi.f = ValF(t$)
Read t$ : Duree.l = Val(t$)
If No >= 0
CreateEntity(No , MeshID(NoMesh),MaterialID(NoMaterial))
ScaleEntity(No , SX , SY , SZ )
EntityLocate(No , PX , PY , PZ )
entity(No)\AngleX = AX
RotateEntity(No , AX , AY , AZ )
entity(No)\Vitesse = Vitesse
entity(No)\Mini = Mini
entity(No)\Maxi = Maxi
entity(No)\Duree = Duree
entity(No)\Tps = GetTickCount_()
EndIf
; Gestion des animations , on peut en ajouter autant que l'on veut , il suffit de créer la procédure qui va bien
Select Anime
Case #BoxHorizontaleX
AddElement(BoxHorizontaleX())
BoxHorizontaleX() = No
Case #BoxVerticaleY
AddElement(BoxVerticaleY())
BoxVerticaleY() = No
Case #BoxHorizontaleZ
AddElement(BoxHorizontaleZ())
BoxHorizontaleZ() = No
Case #BoxBonus
AddElement(BoxBonus())
BoxBonus() = No
Case #BoxAction
AddElement(BoxAction())
BoxAction() = No
Case #BoxInterrupteurV
AddElement(BoxInterrupteurV())
BoxInterrupteurV() = No
Case #BoxInterrupteurH
AddElement(BoxInterrupteurH())
BoxInterrupteurH() = No
EndSelect
; Il s'agit d'une Box sans entity associée
If No = -1
TypeBox = 0
NoMax + 1
NoBox = NoMax
Else
NoBox = No
If Anime > 0 Or Anime = -1
TypeBox = 1
Else
TypeBox = 0
EndIf
EndIf
If Anime <> -2
MakeBoxCollision( NoBox , PX , PY , PZ , SX , SY , SZ , AX , TypeBox )
EndIf
Next a
Compteur = NoMax
EndProcedure
Procedure.f WrapValue( Angle.f )
;Permet de toujours avoir un angle compris entre 0° et 360°
While Angle < 0
Angle + 360
Wend
While Angle - 360 >= 0
Angle - 360
Wend
ProcedureReturn Angle
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 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 )
; simplifier tout ça
If Angle1 > 180
ecart2.f = 360 - Angle1
Else
ecart2.f = Angle1
EndIf
If Angle2 > 180
ecart1.f = 360 - Angle2
Else
ecart1.f = Angle2
EndIf
If Abs( WrapValue( Angle2 ) - WrapValue( Angle1 ) ) > 180
If Angle2 < Angle1
Delta.f = ( ecart1 + ecart2 )
Else
Delta.f = ( ecart1 + ecart2 ) * -1
EndIf
Else
Delta.f = WrapValue( Angle2 ) - WrapValue( Angle1 )
EndIf
ProcedureReturn Delta
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 DelBoxCollision(No.l)
ForEach BoxCollision()
If BoxCollision()\No = No
DeleteElement(BoxCollision())
Break
EndIf
Next
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
ResetList( BoxCollision() )
While NextElement( 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
Wend
; 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
; J'en ai peut-être trop fait là ? => A voir si ça peut se simplifier
CondX = (BoxMinX >= MinX2 And BoxMinX <= MaxX2) Or (BoxMaxX >= MinX2 And BoxMaxX <= MaxX2) Or (BoxMinX < MinX2 And BoxMaxX >= MinX2 ) Or (BoxMinX <= MaxX2 And BoxMaxX > MaxX2 )
CondY = (BoxMinY >= MinY2 And BoxMinY <= MaxY2) Or (BoxMaxY >= MinY2 And BoxMaxY <= MaxY2) Or (BoxMinY < MinY2 And BoxMaxY >= MinY2 ) Or (BoxMinY <= MaxY2 And BoxMaxY > MaxY2 )
CondZ = (BoxMinZ >= MinZ2 And BoxMinZ <= MaxZ2) Or (BoxMaxZ >= MinZ2 And BoxMaxZ <= MaxZ2) Or (BoxMinZ < MinZ2 And BoxMaxZ >= MinZ2 ) Or (BoxMinZ <= MaxZ2 And BoxMaxZ > MaxZ2 )
;Utilisé pour les collisions glissantes
GetCollisionX = 0
GetCollisionY = 0
GetCollisionZ = 0
If CondY And CondX And CondZ
;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 GereBoxHorizontaleX()
ForEach BoxHorizontaleX()
No = BoxHorizontaleX()
MoveEntity(No , entity(No)\Vitesse , 0 , 0 )
If EntityX(No) > entity(No)\Maxi Or EntityX(No) < entity(No)\Mini
entity(No)\Vitesse * -1
EndIf
If entity(0)\NoCollision = No
If entity(0)\CollisionX = 0 And entity(0)\CollisionZ = 0
MoveEntity(0 , entity(No)\Vitesse , 0 , 0)
EndIf
EndIf
Next
EndProcedure
Procedure GereBoxVerticaleY()
ForEach BoxVerticaleY()
No = BoxVerticaleY()
MoveEntity(No , 0 , entity(No)\Vitesse , 0 )
If EntityY(No) > entity(No)\Maxi Or EntityY(No) < entity(No)\Mini
entity(No)\Vitesse * -1
EndIf
If entity(0)\NoCollision = No
If entity(0)\CollisionX = 0 And entity(0)\CollisionZ = 0
MoveEntity(0 , 0 , entity(No)\Vitesse , 0)
EndIf
EndIf
Next
EndProcedure
Procedure GereBoxHorizontaleZ()
ForEach BoxHorizontaleZ()
No = BoxHorizontaleZ()
MoveEntity(No , 0 , 0 , entity(No)\Vitesse )
If EntityZ(No) > entity(No)\Maxi Or EntityZ(No) < entity(No)\Mini
entity(No)\Vitesse * -1
EndIf
If entity(0)\NoCollision = No
If entity(0)\CollisionX = 0 And entity(0)\CollisionZ = 0
MoveEntity(0 , 0 , 0 , entity(No)\Vitesse )
EndIf
EndIf
Next
EndProcedure
Procedure GereBoxBonus()
;Param1 = Vitesse de rotation de l'entity
;Param2 = Nombre de points ramassés
;Param3 = Durée de vie de l'entity
; Param3 = 0 => Vie infinie tant que l'entity n'est Pas touchée
; Param3 > 0 => Temps exprimé en seconde
ForEach BoxBonus()
; No = No de l'entity
No = BoxBonus()
; Petite animation de l'entity , y'a mieux , mais faudra s'en contenter :)
RotateEntity(No , entity(No)\Vitesse , 0 , 0 )
; durée de vie écoulée
FinDeVie = (GetTickCount_()-entity(No)\Tps)/1000 > entity(No)\Duree And entity(No)\Duree > 0
; Si l'entity est touchée ou si sa durée de vie est écoulée
If entity(No)\NoCollision Or FinDeVie
; quand l'entity est hors de vue
If EntityY(No)> EntityY(0) + 40 Or entity(0)\NoCollision = No
; efface l'entity
FreeEntity(No)
; compteur Bonus seulement si pas FinDeVie
If entity(No)\Maxi = 1 Or entity(0)\NoCollision = No : CompteurBonus + entity(No)\Mini : EndIf
; Supprime l'entity de la liste
DeleteElement(BoxBonus())
; Ainsi que de la liste BoxCollision
DelBoxCollision(No)
; et initialise l'entity en collision avec le joueur
entity(0)\NoCollision = 0
; et on sort
Break
Else
; on évacue par le haut en tournant un peu
RotateEntity(No,2,2,2)
MoveEntity(No,0,1,0)
; c'est juste pour valider la condition (durée de vie écoulée ) car on est plus en collision
If ~ FinDeVie : entity(No)\Maxi = 1 : entity(No)\Duree = 1 : EndIf
Break
EndIf
Break
EndIf
Next
EndProcedure
Procedure GereBoxInterrupteurH()
; quand l'interrupteur a servi , on peut le supprimer de la boxCollision ( il doit être enfoncé ! )
ForEach BoxInterrupteurH()
No = BoxInterrupteurH()
If entity(No)\NoCollision
MoveEntity(No , entity(No)\Vitesse , 0 , 0 )
If EntityX(No) > entity(No)\Maxi
entity(entity(No)\Duree)\Duree = 1
FreeEntity(No)
DeleteElement(BoxInterrupteurH())
DelBoxCollision(No)
Break
EndIf
EndIf
Next
EndProcedure
Procedure GereBoxInterrupteurV()
; quand l'interrupteur a servi , on peut le supprimer de la boxCollision ( il doit être enfoncé ! )
ForEach BoxInterrupteurV()
No = BoxInterrupteurV()
If entity(0)\NoCollision = No
MoveEntity(No , 0 , entity(No)\Vitesse , 0 )
If EntityY(No) < entity(No)\Mini
entity(entity(No)\Duree)\Duree = 1
FreeEntity(No)
DeleteElement(BoxInterrupteurV())
DelBoxCollision(No)
Break
EndIf
EndIf
Next
EndProcedure
Procedure GereBoxAction()
; quand l'interrupteur a servi , on peut le supprimer de la boxCollision ( il doit être enfoncé ! )
ForEach BoxAction()
No = BoxAction()
If entity(No)\Duree
OpenCamera(No)
Repeat
ClearScreen(0,0,0)
MoveEntity(No , 0 , entity(No)\Vitesse , 0 )
RenderWorld()
FlipBuffers()
Until EntityY(No) < entity(No)\Mini
CloseCamera(No)
FreeCamera(1)
FreeEntity(No)
DeleteElement(BoxAction())
DelBoxCollision(No)
Break
EndIf
Next
EndProcedure
Procedure OpenCamera(No.l)
For a = 50 To 0 Step -1
ClearScreen(0,0,0)
CreateCamera(1,a,a,100-a*2,100-a*2)
CamX.f = NewXValue(EntityX(No) , entity(No)\AngleX + 90 , 90 )
CamZ.f = NewZValue(EntityZ(No) , entity(No)\AngleX + 90 , 90 )
CameraLocate(1 , CamX , EntityY(No) + 28 , CamZ)
CameraLookAt(1 , EntityX(No), EntityY(No) ,EntityZ(No))
RenderWorld()
AffScore()
FlipBuffers()
Next a
EndProcedure
Procedure CloseCamera(No.l)
For a = 0 To 50
ClearScreen(0,0,0)
CreateCamera(1,a,a,100-a*2,100-a*2)
CamX.f = NewXValue(EntityX(No) , entity(No)\AngleX + 90 , 90 )
CamZ.f = NewZValue(EntityZ(No) , entity(No)\AngleX + 90 , 90 )
CameraLocate(1 , CamX , EntityY(No) + 28 , CamZ)
CameraLookAt(1 , EntityX(No), EntityY(No) ,EntityZ(No))
RenderWorld()
AffScore()
FlipBuffers()
Next a
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 )
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 )
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 )
EndIf
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))
EndProcedure
Procedure AffScore()
StartDrawing(ScreenOutput())
FontID = LoadFont(0, "Comics", 64 ,#PB_Font_Bold )
DrawingFont(FontID)
FrontColor(240,210,0)
DrawingMode(1)
Texte$ = Str(CompteurBonus)
Locate(#ScreenWidth-TextLength(Texte$),0)
DrawText(Texte$)
StopDrawing()
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
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 KeyboardPushed(#PB_Key_LeftControl) And Attraction = 0 And AutoriseSaut
; Attraction = 1.6 : DecAttraction = 0.01
;EndIf
If KeyboardReleased(#PB_Key_F4) : AfficheAide = 1 - AfficheAide : EndIf
EndIf
; gestions des entitys selon le type d'animation
GereBoxHorizontaleX()
GereBoxVerticaleY()
GereBoxHorizontaleZ()
GereBoxBonus()
GereBoxInterrupteurH()
GereBoxInterrupteurV()
GereBoxAction()
; 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 après
PosY0 = EntityY(0)
PosX0 = EntityX(0)
PosZ0 = EntityZ(0)
; Gestion de l'attraction
Attraction - DecAttraction
; Test des collisions
entity(0)\CollisionX = 0
entity(0)\CollisionZ = 0
; quand on est plus sur une dalle , on ne corrige plus sa position
If OldPosY <> PosY0 : entity(0)\NoCollision = -1 : EndIf
ResetList(BoxCollision())
While NextElement(BoxCollision())
NoBox = BoxCollision()\No
IndexBoxCollision = ListIndex(BoxCollision())
If EntityCollision( 0 , NoBox ) > 0
; la box est touchée par le joueur
If NoBox <> 0 : entity(NoBox)\NoCollision = 1 : EndIf
; permet de déplacer le perso s'il se trouve sur une box mouvante verticale ou horizontale
If GetCollisionX <> 0 : entity(0)\CollisionX = GetCollisionX : EndIf
If GetCollisionZ <> 0 : entity(0)\CollisionZ = GetCollisionZ : EndIf
; 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
;Pas = 0
Attraction = 0
AutoriseSaut = 1
; permet de déplacer le perso s'il se trouve sur une box mouvante verticale ou horizontale
entity(0)\NoCollision = NoBox
EndIf
EndIf
Else
; la box n'est pas touchée par le joueur
If NoBox <> 0 : entity(NoBox)\NoCollision = 0 : 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
AffScore()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
;-Datas du Cube et du Plain
DataSection
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 -0.5,0,-0.5
; Data.f -0.5,0,0.5
; Data.f 0.5,0,0.5
; Data.f 0.5,0,-0.5
; Data.f -0.5,0,-0.5
; Data.f -0.5,0,0.5
; Data.f 0.5,0,0.5
; Data.f 0.5,0,-0.5
Data.f -5,0,-5
Data.f -5,0,5
Data.f 5,0,5
Data.f 5,0,-5
Data.f -5,0,-5
Data.f -5,0,5
Data.f 5,0,5
Data.f 5,0,-5
Data.f 0,-5,0
Data.f 0,-5,0
Data.f 0,-5,0
Data.f 0,-5,0
Data.f 0,5,0
Data.f 0,5,0
Data.f 0,5,0
Data.f 0,5,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
PlainPoints:
Data.f -0.5, 0, -0.5
Data.f 0.5 , 0, -0.5
Data.f 0.5 , 0, 0.5
Data.f -0.5, 0, 0.5
PlainTriangles:
Data.w 0, 1, 2
Data.w 0, 2, 3
Data.w 2, 1, 0
Data.w 3, 2, 0
PlainTextures:
Data.f 0, 0
Data.f 1, 0
Data.f 1, 1
Data.f 0, 1
PlainNormales:
Data.f -5,0,-5
Data.f -5,0,5
Data.f 5,0,5
Data.f 5,0,-5
Niveau1:
Data.s "48","47","0","0","25","200","9","200","8","8","8","0","0","0","-1","0","0","0","0","1"
Data.s "0","27","512","0","512","1024","10","1024","0","0","0","0","0","0","0","0","2","0","29","512"
Data.s "37","3","1024","64","6","0","0","0","0","0","0","0","0","3","0","29","1021","37","512","1024"
Data.s "64","6","90","0","0","0","0","0","0","0","4","0","29","512","37","1021","1024","64","6","0"
Data.s "0","0","0","0","0","0","0","5","0","29","3","37","512","1024","64","6","90","0","0","0"
Data.s "0","0","0","0","6","0","18","256","37","256","64","64","64","0","0","0","0","0","0","0"
Data.s "0","7","0","29","224","8","256","20","4","4","0","0","0","8","0.2","224","234","22","8","0"
Data.s "5","512","37","256","64","64","64","0","0","0","0","0","0","0","0","9","0","29","512","79"
Data.s "256","10","20","10","0","0","0","7","-0.2","70","79","21","10","0","6","768","37","256","64","64"
Data.s "64","45","0","0","0","0","0","0","0","11","0","7","256","37","512","64","64","64","0","0"
Data.s "0","0","0","0","0","0","12","0","26","256","64","470","15","5","15","0","0","0","2","0.3"
Data.s "64","148","0","13","0","11","512","37","512","64","64","64","0","0","0","0","0","0","0","0"
Data.s "14","0","24","539","37","512","30","10","10","0","0","0","1","0.2","530","555","0","15","0","24"
Data.s "539","20","532","30","10","10","0","0","0","1","-0.2","530","555","0","16","0","24","539","54","490"
Data.s "30","10","10","0","0","0","1","-0.2","530","555","0","17","0","22","470","64","512","15","5","15"
Data.s "0","0","0","1","0.5","298","470","0","18","0","22","554","64","512","15","5","15","0","0","0"
Data.s "1","0.5","554","726","0","19","0","22","512","64","470","15","5","15","0","0","0","3","0.5","298"
Data.s "470","0","20","0","22","512","64","554","15","5","15","0","0","0","3","0.5","554","726","0","21"
Data.s "0","9","483","100","512","60","63","4","90","0","0","6","-0.2","32","94","0","22","0","9","512"
Data.s "100","483","63","63","4","0","0","0","6","-0.2","32","94","0","23","0","9","512","100","541","63"
Data.s "63","4","0","0","0","6","-0.2","32","94","0","24","0","28","768","37","512","64","64","64","0"
Data.s "0","0","0","0","0","0","0","25","0","10","256","37","768","64","64","64","45","0","0","0"
Data.s "0","0","0","0","26","0","8","512","37","768","64","64","64","0","0","0","0","0","0","0"
Data.s "0","27","0","12","768","37","768","64","64","64","45","0","0","0","0","0","0","0","28","0"
Data.s "23","256","128","370","15","5","185","0","0","0","0","0","0","0","0","29","0","24","240","135"
Data.s "350","30","10","10","0","0","0","1","-0.2","225","256","0","30","0","24","271","135","325","30","10"
Data.s "10","0","0","0","1","0.2","256","281","0","31","0","24","240","135","300","30","10","10","0","0"
Data.s "0","1","-0.2","225","256","0","32","0","23","256","148","270","15","5","15","0","0","0","0","0"
Data.s "0","0","0","33","0","23","256","158","245","15","5","15","0","0","0","0","0","0","0","0"
Data.s "34","0","23","256","168","220","15","5","15","0","0","0","0","0","0","0","0","35","0","23"
Data.s "300","168","220","15","5","15","0","0","0","0","0","0","0","0","36","0","23","380","168","220"
Data.s "40","5","20","0","0","0","0","0","0","0","0","37","0","28","256","164","245","6","6","6"
Data.s "0","0","0","4","1","10","0","0","38","0","28","256","174","220","6","6","6","0","0","0"
Data.s "4","1","10","0","0","39","0","28","300","174","220","6","6","6","0","0","0","4","1","10"
Data.s "0","0","40","0","29","380","173","220","10","10","10","0","0","0","7","-0.2","168","170","23","41"
Data.s "0","28","256","154","270","6","6","6","0","0","0","4","1","10","0","0","42","0","28","256"
Data.s "72","256","6","6","6","0","0","0","4","-1","10","0","0","43","0","28","256","72","512","6"
Data.s "6","6","0","0","0","4","-1","10","0","0","44","0","28","256","72","768","6","6","6","0"
Data.s "0","0","4","-1","10","0","0","45","0","28","768","72","256","6","6","6","0","0","0","4"
Data.s "-1","10","0","0","46","0","28","20","8","20","6","6","6","0","0","0","4","-1","10","0"
Data.s "0","47","0","28","100","8","1000","6","6","6","0","0","0","4","-1","10","0","0"
EndDataSection