Nouvelle version du code, j'ai ajouté une petite animation des briques touchées. va falloir gérer l'angle de la balle , qu'il puisse changer selon la frappe de la raquette...
Code : Tout sélectionner
; Comtois le 14/02/2005
; Version PB 3.92
;-Constantes
;/ Ecran
#ScreenWidth = 640
#ScreenHeight = 400
#ScreenDepth = 32
Enumeration
#Raquette
#Balle
#BriqueJaune
#BriqueVerte
#BriqueRouge
#BriqueBrune
#BriqueLilas
#BriqueOrange
#BriqueBleue
#BriqueViolette
#FondBleu
EndEnumeration
;-Structures
Structure Commun
Type.l
x.l
y.l
Largeur.l
Hauteur.l
EndStructure
Structure Terrain Extends Commun
NbTileX.l
NbTileY.l
MinX.l
MaxX.l
MinY.l
MaxY.l
EndStructure
Structure Balle Extends Commun
DirX.l
DirY.l
AncienX.l
AncienY.l
EndStructure
Structure Raquette Extends Commun
DirX.l
AncienX.l
EndStructure
Structure Brique Extends Commun
Temps.l
Duree.l
DirX.l
DirY.l
EndStructure
;{- Variables
Global Balle.Balle
Global Raquette.Raquette
Global Terrain.Terrain
NewList Brique.Commun()
NewList BriqueTouchee.Brique()
;}
;{- Initialisation
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitSprite3D()=0
MessageRequester( "Erreur" , "Impossible d'initialiser DirectX 7 Ou plus" , 0 )
End
ElseIf OpenScreen( #ScreenWidth , #ScreenHeight , #ScreenDepth , "M3D_Matrix3D" ) = 0
MessageRequester( "Erreur" , "Impossible d'ouvrir l'écran " , 0 )
End
EndIf
;}
UsePNGImageDecoder()
;-Sprites
LoadSprite(#Raquette,"raquette.png")
LoadSprite(#Balle,"balle.png")
For i=0 To 7
Read Fichier$
LoadSprite(#BriqueJaune+i,Fichier$+".png")
Next i
LoadSprite(#FondBleu,"FondBleu.png")
;-Procédures
Procedure Erreur(Message$)
MessageRequester( "Erreur" , Message$ , 0 )
End
EndProcedure
Procedure AfficheJeu()
For v=0 To Terrain\NbTileY-1
For u=0 To Terrain\NbTileX-1
DisplaySprite(Terrain\Type,Terrain\MinX+u*Terrain\Largeur,Terrain\MinY+v*Terrain\Hauteur)
Next u
Next v
ForEach Brique()
DisplaySprite(Brique()\Type,Brique()\x,Brique()\y)
Next
ForEach BriqueTouchee()
If ElapsedMilliseconds()-BriqueTouchee()\Temps<BriqueTouchee()\Duree
Intensite=255-(ElapsedMilliseconds()-BriqueTouchee()\Temps)/10
DisplayTranslucideSprite(BriqueTouchee()\Type,BriqueTouchee()\x,BriqueTouchee()\y,Intensite)
Else
DeleteElement(BriqueTouchee())
EndIf
Next
DisplayTransparentSprite(Raquette\Type,Raquette\x,Raquette\y)
DisplayTransparentSprite(Balle\Type,Balle\x,Balle\y)
EndProcedure
Procedure GestionTouches()
If ExamineKeyboard()
If KeyboardPushed(#PB_Key_Left)
Raquette\DirX=-4
ElseIf KeyboardPushed(#PB_Key_Right)
Raquette\DirX=4
Else
Raquette\DirX=0
EndIf
EndIf
EndProcedure
Procedure AddTerrain()
Terrain\Type=#FondBleu
Terrain\Largeur=SpriteWidth(#FondBleu)
Terrain\Hauteur=SpriteHeight(#FondBleu)
Terrain\NbTileX=12
Terrain\NbTileY=8
Terrain\MinX=90
Terrain\MaxX=Terrain\MinX+Terrain\NbTileX*Terrain\Largeur
Terrain\MinY=100
Terrain\MaxY=Terrain\MinY+Terrain\NbTileY*Terrain\Hauteur
EndProcedure
Procedure AddRaquette()
Raquette\Type=#Raquette
Raquette\DirX=4
Raquette\Largeur=SpriteWidth(#Raquette)
Raquette\Hauteur=SpriteHeight(#Raquette)
Raquette\x=(Terrain\MinX+Terrain\MaxX+Raquette\Largeur)/2
Raquette\y=Terrain\MaxY-2*Raquette\Hauteur
EndProcedure
Procedure AddBrique()
If OpenFile(0,"Niveau1.txt")
v=0
While Eof(0)=0
Ligne$=ReadString()
For u=1 To Len(Ligne$)
Brique=Val(Mid(Ligne$,u,1))
If Brique>=#BriqueJaune And Brique<=#BriqueViolette
AddElement(Brique())
Brique()\Type=Brique
Brique()\x=Terrain\MinX+u*29
Brique()\y=Terrain\MinY+v*14
Brique()\Largeur=SpriteWidth(Brique)
Brique()\Hauteur=SpriteHeight(Brique)
EndIf
Next u
v+1
Wend
CloseFile(0)
Else
Erreur("Impossible d'ouvrir le fichier 'Niveau1.txt'")
EndIf
EndProcedure
Procedure AddBriqueTouchee(Brique,x,y,dx,dy)
AddElement(BriqueTouchee())
BriqueTouchee()\Temps=ElapsedMilliseconds()
BriqueTouchee()\Duree=2550
BriqueTouchee()\Type=Brique
BriqueTouchee()\x=x
BriqueTouchee()\y=y
BriqueTouchee()\Largeur=SpriteWidth(Brique)
BriqueTouchee()\Hauteur=SpriteHeight(Brique)
BriqueTouchee()\DirX=dx
BriqueTouchee()\DirY=dy
EndProcedure
Procedure AddBalle()
Balle\Type=#Balle
Balle\Largeur=SpriteWidth(#Balle)
Balle\Hauteur=SpriteHeight(#Balle)
Balle\x=Raquette\x+(Raquette\Largeur-Balle\Largeur)/2
Balle\y=Raquette\y-Balle\Hauteur
Balle\DirX=3
Balle\DirY=-2
EndProcedure
Procedure CalculDeplacement()
;/Raquette
Raquette\AncienX=Raquette\x
Raquette\x+Raquette\DirX
;/Balle
Balle\AncienX=Balle\x
Balle\AncienY=Balle\y
Balle\x+Balle\DirX
Balle\y+Balle\DirY
ForEach BriqueTouchee()
BriqueTouchee()\x+BriqueTouchee()\DirX
BriqueTouchee()\y+BriqueTouchee()\DirY
Next
EndProcedure
Procedure Test()
ClearScreen(0,0,0)
DisplaySprite(Brique()\Type,Brique()\x,Brique()\y)
DisplayTransparentSprite(Raquette\Type,Raquette\x,Raquette\y)
DisplayTransparentSprite(Balle\Type,Balle\x,Balle\y)
FlipBuffers()
Delay(5000)
EndProcedure
Procedure ReplaceBalleRaquette()
;La balle se déplace sur une pente a=dy/dx
;S'il y a un impact avec la raquette y=Raquette\y-Balle\Hauteur
;et la position de la balle au moment de l'impact est x=y/a soit x=(dx/dy)*y
BalleY=Raquette\y-Balle\AncienY-Balle\Hauteur
BalleX=(Balle\DirX*BalleY/Balle\DirY)
;/
CheminBalle=Balle\AncienX-Balle\x
CheminRaquette=Raquette\x-Raquette\AncienX
Distance=Balle\AncienX-BalleX
Pourcentage=Abs(Distance/CheminBalle)
RaquetteX=Raquette\x+(Pourcentage*CheminRaquette)
EndProcedure
Procedure ReplaceBalle()
;On sait que la balle est en collision avec une brique.
;Maintenant il faut tester avec quel côté de la brique la balle est en collision
;Ensuite il faut inverser le sens de déplacement selon le côté touché
;Et replacer la balle au contact de la brique (la balle ne pénètre pas les briques)
DepartX=Balle\AncienX
ArriveeX=Balle\x
DepartY=Balle\AncienY
ArriveeY=Balle\y
Memx=Balle\DirX
MEmy=Balle\DirY
;/Si la balle monte
If Balle\DirY<0
;/Pour chaque coordonnée entre departY et arriveeY
For CourantY=DepartY To ArriveeY Step -1
;/Si la balle va vers la gauche
If Balle\DirX<0
;/Pour chaque coordonnée entre departX et arriveeX
For CourantX=DepartX To ArriveeX Step -1
;/Test collision
If SpritePixelCollision(Brique()\Type,Brique()\x,Brique()\y,Balle\Type,CourantX,CourantY)
;/La Balle touche La brique par en dessous ?
If CourantY=Brique()\y+Brique()\Hauteur-1
;/Inverse le sens
Balle\DirY*-1
;/Replace la balle
Balle\y=CourantY+1
EndIf
;/La balle touche la brique sur le côté droit ?
If CourantX=Brique()\x+Brique()\Largeur-1
;/Inverse le sens
Balle\DirX*-1
;/Replace la balle
Balle\x=CourantX+1
EndIf
;/Supprime la brique
AddBriqueTouchee(Brique()\Type,Brique()\x,Brique()\y,Memx,MEmy)
DeleteElement(Brique())
Break 2
EndIf
Next CourantX
;/Sinon si la balle va vers la droite
Else
;/Pour chaque coordonnée entre departX et arriveeX
For CourantX=DepartX To ArriveeX
;/Test collision
If SpritePixelCollision(Brique()\Type,Brique()\x,Brique()\y,Balle\Type,CourantX,CourantY)
;/La Balle touche La brique par en dessous ?
If CourantY=Brique()\y+Brique()\Hauteur-1
;/Inverse le sens
Balle\DirY*-1
;/Replace la balle
Balle\y=CourantY+1
EndIf
;/La balle touche la brique sur le côté gauche ?
If CourantX+Balle\Largeur-1=Brique()\x
;/Inverse le sens
Balle\DirX*-1
;/Replace la balle
Balle\x=CourantX-1
EndIf
;/Supprime la brique
AddBriqueTouchee(Brique()\Type,Brique()\x,Brique()\y,Memx,MEmy)
DeleteElement(Brique())
Break 2
EndIf
Next CourantX
EndIf
Next CourantY
Else
;/Pour chaque coordonnée entre departY et arriveeY
For CourantY=DepartY To ArriveeY
;/Si la balle va vers la gauche
If Balle\DirX<0
;/Pour chaque coordonnée entre departX et arriveeX
For CourantX=DepartX To ArriveeX Step -1
;/Test collision
If SpritePixelCollision(Brique()\Type,Brique()\x,Brique()\y,Balle\Type,CourantX,CourantY)
;/La Balle touche La brique par au dessus ?
If CourantY+Balle\Hauteur-1=Brique()\y
;/Inverse le sens
Balle\DirY*-1
;/Replace la balle
Balle\y=CourantY-1
EndIf
;/La balle touche la brique sur le côté droit ?
If CourantX=Brique()\x+Brique()\Largeur-1
;/Inverse le sens
Balle\DirX*-1
;/Replace la balle
Balle\x=CourantX+1
EndIf
;/Supprime la brique
AddBriqueTouchee(Brique()\Type,Brique()\x,Brique()\y,Memx,MEmy)
DeleteElement(Brique())
Break 2
EndIf
Next CourantX
;/Sinon si la balle va vers la droite
Else
;/Pour chaque coordonnée entre departX et arriveeX
For CourantX=DepartX To ArriveeX
;/Test collision
If SpritePixelCollision(Brique()\Type,Brique()\x,Brique()\y,Balle\Type,CourantX,CourantY)
;/La Balle touche La brique par en dessous ?
If CourantY+Balle\Hauteur-1=Brique()\y
;/Inverse le sens
Balle\DirY*-1
;/Replace la balle
Balle\y=CourantY-1
EndIf
;/La balle touche la brique sur le côté gauche ?
If CourantX+Balle\Largeur-1=Brique()\x
;/Inverse le sens
Balle\DirX*-1
;/Replace la balle
Balle\x=CourantX-1
EndIf
;/Supprime la brique
AddBriqueTouchee(Brique()\Type,Brique()\x,Brique()\y,Memx,MEmy)
DeleteElement(Brique())
Break 2
EndIf
Next CourantX
EndIf
Next CourantY
EndIf
EndProcedure
Procedure Attente()
EndProcedure
Procedure Collisions()
;/Raquette / Murs
If Raquette\x<Terrain\MinX
Raquette\x=Terrain\MinX
ElseIf Raquette\x+Raquette\Largeur>Terrain\MaxX
Raquette\x=Terrain\MaxX-Raquette\Largeur
EndIf
;/Raquette / Balle
If SpritePixelCollision(Raquette\Type,Raquette\x,Raquette\y,Balle\Type,Balle\x,Balle\y)
ReplaceBalleRaquette()
Balle\y=Raquette\y-Balle\Hauteur
Balle\DirY*-1
EndIf
;/Balle/Murs
If Balle\x<Terrain\MinX
Balle\x=Terrain\MinX
Balle\DirX*-1
ElseIf Balle\x+Balle\Largeur>Terrain\MaxX
Balle\x=Terrain\MaxX-Balle\Largeur
Balle\DirX*-1
EndIf
If Balle\y<Terrain\MinY
Balle\y=Terrain\MinY
Balle\DirY*-1
ElseIf Balle\y+Balle\Hauteur>Terrain\MaxY
Balle\x=Raquette\x+(Raquette\Largeur-Balle\Largeur)/2
Balle\y=Raquette\y-Balle\Hauteur
Balle\DirY*-1
EndIf
;/Balle / Briques
ForEach Brique()
If SpritePixelCollision(Brique()\Type,Brique()\x,Brique()\y,Balle\Type,Balle\x,Balle\y)
ReplaceBalle()
Break
EndIf
Next
;/Briquestouchées /murs
ForEach BriqueTouchee()
If BriqueTouchee()\x<Terrain\MinX
BriqueTouchee()\x=Terrain\MinX
BriqueTouchee()\DirX*-1
ElseIf BriqueTouchee()\x+BriqueTouchee()\Largeur>Terrain\MaxX
BriqueTouchee()\x=Terrain\MaxX-BriqueTouchee()\Largeur
BriqueTouchee()\DirX*-1
EndIf
If BriqueTouchee()\y<Terrain\MinY
BriqueTouchee()\y=Terrain\MinY
BriqueTouchee()\DirY*-1
ElseIf BriqueTouchee()\y+BriqueTouchee()\Hauteur>Terrain\MaxY
BriqueTouchee()\y=Terrain\MaxY-BriqueTouchee()\Hauteur
BriqueTouchee()\DirY*-1
EndIf
Next
EndProcedure
;- Boucle Principale
AddTerrain()
AddRaquette()
AddBalle()
AddBrique()
Attente()
Repeat
ClearScreen(20,20,20)
GestionTouches()
CalculDeplacement()
Collisions()
AfficheJeu()
If ExamineKeyboard()
EndIf
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
DataSection
Data.s "BriqueJaune"
Data.s "BriqueVerte"
Data.s "BriqueRouge"
Data.s "BriqueBrune"
Data.s "BriqueLilas"
Data.s "BriqueOrange"
Data.s "BriqueBleue"
Data.s "BriqueViolette"
EndDataSection