[2D] Kanoid 1.60 : Un casse brique dans un CanvasGadget
Publié : lun. 08/oct./2012 11:12
Mise à jour du 13 Octobre
Kanoid (Contraction de canvasnoid) est un jeu d’arcade de type casse-briques.
Le jeu consiste à contrôler une raquette positionnée au bas de l'écran de gauche à droite avec la souris afin de faire rebondir une balle sur les rebords pour détruire des briques.
On passe au niveau suivant (3 dans cette version) lorsque toutes les briques sont détruites ou bien quand les briques les plus basses atteignent le bas de l'écran.

Les briques possèdent de 1 à 4 vies matérialisées par un nombre affiché sur chaque brique.
Une fois détruite une brique peut libérer un bonus ou un malus.
-Augmentation / diminution de la taille de la raquette.
-Augmentation / diminution de la taille de la balle.
-Augmentation / diminution de la vitesse de la balle
-Augmentation / diminution du nombre de vie.
-Activation / Désactivation de la Glue sur la raquette.
-Activation / Désactivation du mode tir.
Deux observateurs sont présents pour juger de votre combativité.
Le premier mémorise les rebonds. Apres dix rebonds sans toucher une brique, il en fait part au deuxième observateur et change la vitesse horizontale et verticale des balles.
Ce deuxième observateur vous donne encore dix rebonds pour détruire les briques. Chaque brique touchée vous donne un rebond de plus. Si vous ne parvenez pas à détruire les briques dans la limite des rebonds qui vous est encore accordée, le niveau est abandonné et passe au suivant.
Souris et touches de raccourcis.
La souris pour déplacer la raquette.
Clic gauche Libère la balle ou mode tir.
Clic droit Inverse la trajectoire horizontale de la balle.
Esc Quitte le jeu.
Pause Jeu en pause.
C Clip / Unclip la souris
N Nouvelle partie.
Le code n'est pas totalement débugger. je corrige au fur et à mesure.
La réception de la balle sur la raquette est encore mal géré.
N'hésitez pas à poster des modifications. J'ajusterais le code en conséquence.
J'aurais pu utiliser les sprites
mais j'avais envie de titiller le canvas.
Vous pouvez télécharger la version sonorisée de kanoid (Version 1.60) et vous trouverez le source du code non sonorisé ci-dessous (Version 1.20).
Télécharger Kanoid (Source + sons 3,8 Mo)
Si vous avez déjà le dossier kanoid, vous pouvez télécharger le source seul
Télécharger Kanoid Update (Source seul 7 Ko)
Kanoid (Contraction de canvasnoid) est un jeu d’arcade de type casse-briques.
Le jeu consiste à contrôler une raquette positionnée au bas de l'écran de gauche à droite avec la souris afin de faire rebondir une balle sur les rebords pour détruire des briques.
On passe au niveau suivant (3 dans cette version) lorsque toutes les briques sont détruites ou bien quand les briques les plus basses atteignent le bas de l'écran.
Les briques possèdent de 1 à 4 vies matérialisées par un nombre affiché sur chaque brique.
Une fois détruite une brique peut libérer un bonus ou un malus.
-Augmentation / diminution de la taille de la raquette.
-Augmentation / diminution de la taille de la balle.
-Augmentation / diminution de la vitesse de la balle
-Augmentation / diminution du nombre de vie.
-Activation / Désactivation de la Glue sur la raquette.
-Activation / Désactivation du mode tir.
Deux observateurs sont présents pour juger de votre combativité.
Le premier mémorise les rebonds. Apres dix rebonds sans toucher une brique, il en fait part au deuxième observateur et change la vitesse horizontale et verticale des balles.
Ce deuxième observateur vous donne encore dix rebonds pour détruire les briques. Chaque brique touchée vous donne un rebond de plus. Si vous ne parvenez pas à détruire les briques dans la limite des rebonds qui vous est encore accordée, le niveau est abandonné et passe au suivant.
Souris et touches de raccourcis.
La souris pour déplacer la raquette.
Clic gauche Libère la balle ou mode tir.
Clic droit Inverse la trajectoire horizontale de la balle.
Esc Quitte le jeu.
Pause Jeu en pause.
C Clip / Unclip la souris
N Nouvelle partie.
Le code n'est pas totalement débugger. je corrige au fur et à mesure.
La réception de la balle sur la raquette est encore mal géré.
N'hésitez pas à poster des modifications. J'ajusterais le code en conséquence.
J'aurais pu utiliser les sprites

Vous pouvez télécharger la version sonorisée de kanoid (Version 1.60) et vous trouverez le source du code non sonorisé ci-dessous (Version 1.20).

Si vous avez déjà le dossier kanoid, vous pouvez télécharger le source seul

Code : Tout sélectionner
;Kanoid Version 1.20 - Falsam
;
EnableExplicit
Enumeration
#ScoreFont
#BrickFont
#BigFont
#BigFontOutLine
#NormalFont
#Mainform
#Grid
;Pour environnement OSX
#VK_C = 67
#VK_N = 78
#VK_PAUSE = 19
#VK_ESCAPE = 27
EndEnumeration
Structure DefBrick
Actif.b ;The brick is not destroyed
Col.i ;Position X
Lig.i ;Position Y
life.i ;Nombre de vie de la brique
Color.l ;Couleur : Depend du nombre de vie restant pour la brique concernée
BonusMalus.i ;Bonus ou Malus (Exemple: Ajout d'une vie, Augmentation de la vitesse de la balle)
Point.i ;Nombre de points ajouté au score quand la brique est détruite
Message.s ;Message affiché au moment de l'impact
BoomTime.i ;Durée de vie de l'explosion
EndStructure
Global NewList Brick.DefBrick()
Structure DefShoot
Actif.b ;Tir actif - Active fire
Col.i ;Position X
Lig.i ;Position Y
Color.l ;Couleur - Color
EndStructure
Global NewList Shoot.DefShoot()
Define.l Event, WEvent, MEvent, GEvent, TEvent
Global WindowStyle.i = #PB_Window_ScreenCentered|#PB_Window_SystemMenu
;Grid
Global GridW.i, GridH.i
;Raquette : Position X,Y, Largeur/hauteur de la raquette, Vitesse
Global RacquetX.i, RacquetY.i, RacquetW.i, RacquetH.i
;Balle :Position X,Y, Largeur et hauteur de la balle
Global BallX.i, BallY.i, BallR.i, SpeedH.i, SpeedV.i, MinSpeed.i, MaxSpeed.i
Global OldBallX.i, OldBallY.i, OldSpeedV.i, OldSpeedH.i
;Briques
Global BrickW.i, BrickH.i
;Affichage Score : Points obtenus et vie restante, Message
Global Score.i, Life.i, Message.s
;Compteurs : Nombre de briques restantes, maximum de scenes , Maximum Random
Global Brick.i, MaxStage.i, MaxRnd.i
;Indicateurs : Brique en mouvement vers le bas, Scene en cours, Glue, Balle inactive, Balle perdu, Shoot
Global BrickDown.b, Stage.i, Glue.b, Inactif.i, LostBall.i, Shoot.b
Procedure Open_MainForm()
OpenWindow(#Mainform, 0, 0, GridW, GridH, "Kanoid", WindowStyle)
CanvasGadget(#Grid, 0, 0, GridW, GridH, #PB_Canvas_Keyboard)
SetGadgetAttribute(#Grid, #PB_Canvas_Clip , 1)
SetGadgetData(#Grid, #True)
SetActiveGadget(#Grid)
EndProcedure
Procedure MessageBox(Message.s)
DrawingMode(#PB_2DDrawing_AlphaBlend) ;Fond - Background
RoundBox(50, 150, GridW-100, GridH-300, 8, 8, RGBA(245, 245, 245, 155))
DrawingMode(#PB_2DDrawing_Outlined) ;Contour - Outline
RoundBox(50, 150, GridW-100, GridH-300, 8, 8, RGB(254, 244, 253))
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(#BigFont))
DrawText((GridW-TextWidth(Message))/2, (GridH-TextHeight(Message))/2, Message, RGB(189, 19, 172))
EndProcedure
Procedure SetDefault()
RacquetW = 101
RacquetH = 10
BallR = 7
SpeedH = 0
SpeedV = 0
Inactif = 0
Glue = #False
Shoot = #False
LostBall = #False
EndProcedure
Procedure SetBrickColor(Life)
Select Life
Case 0,1
ProcedureReturn RGB(204, 205, 242)
Case 2
ProcedureReturn RGB(204, 120, 242)
Case 3
ProcedureReturn RGB(248, 120, 43)
Case 4
ProcedureReturn RGB(255, 199, 64)
EndSelect
EndProcedure
;Correction de la vitesse - Correction of the speed
Procedure SetSpeed(Value1.i, Value2.i)
Protected Result
If Value1 = 0 And Value2 = 0 ;La balle est stoppée -The ball is stopped
SpeedH = 0
SpeedV = 0
Result = #True
Else
If Abs(SpeedH + Value1) >= MinSpeed And Abs(SpeedH + Value1) <= MaxSpeed And Value1 <> 0
SpeedH + Value1
Result = #True
Else
Result = #False
EndIf
If Abs(SpeedV + Value2) >= MinSpeed And Abs(SpeedV + Value2) <= MaxSpeed And Value2 <> 0
SpeedV + Value2
Result = #True
Else
Result = #True
EndIf
;La vitesse ne peut pas etre nul - Speed can not be nil
If Abs(SpeedH) = 0
SpeedH = MinSpeed
EndIf
If Abs(SpeedV) = 0
SpeedV = MinSpeed
EndIf
EndIf
ProcedureReturn Result
EndProcedure
Procedure NewStage(Value.i)
Protected Lig.i, Col.i, N.i
ClearList(Brick())
Select Value
Case 1 ;Niveau 1 - level 1
For Lig = 80 To 200 Step 25
For Col = 50 To 700 Step 50
AddElement(Brick())
Brick()\Actif = #True
Brick()\Col = Col
Brick()\Lig = Lig
Brick()\life = Random(3)+1
Brick()\Color = SetBrickColor(Brick()\life)
Brick()\Point = Brick()\life * 100
Brick()\BonusMalus = Random(MaxRnd)
Next
Next
Case 2 ;Niveau 2 - level 2
N = 0
For Lig = 50 To 425 Step 25
For Col = 5 To N Step 50
AddElement(Brick())
Brick()\Actif = #True
Brick()\Col = Col
Brick()\Lig = Lig
Brick()\life = Random(3)+1
Brick()\Color = SetBrickColor(Brick()\life)
Brick()\Point = Brick()\life * 100
Brick()\BonusMalus = Random(MaxRnd)
Next
N+50
Next
Case 3 ;Niveau 3 - level 1
For Lig = 150 To 375 Step 25
If Lig = 150 Or Lig = 375
For Col = 80 To 700 Step 50
AddElement(Brick())
Brick()\Actif = #True
Brick()\Col = Col
Brick()\Lig = Lig
Brick()\life = 4
Brick()\Color = SetBrickColor(Brick()\life)
Brick()\Point = Brick()\life * 100
Brick()\BonusMalus = Random(MaxRnd)
Next
Else
Col=80
AddElement(Brick())
Brick()\Actif = #True
Brick()\Col = Col
Brick()\Lig = Lig
Brick()\life = 4
Brick()\Color = SetBrickColor(Brick()\life)
Brick()\Point = Brick()\life * 100
Brick()\BonusMalus = Random(MaxRnd)
Col=680
AddElement(Brick())
Brick()\Actif = #True
Brick()\Col = Col
Brick()\Lig = Lig
Brick()\life = 4
Brick()\Color = SetBrickColor(Brick()\life)
Brick()\Point = Brick()\life * 100
Brick()\BonusMalus = Random(MaxRnd)
EndIf
Next
For Lig = 175 To 355 Step 25
For Col = 130 To 630 Step 50
AddElement(Brick())
Brick()\Actif = #True
Brick()\Col = Col
Brick()\Lig = Lig
Brick()\life = 2
Brick()\Color = SetBrickColor(Brick()\life)
Brick()\Point = Brick()\life * 100
Brick()\BonusMalus = Random(MaxRnd)
Next
Next
EndSelect
;Ajout de la durée de vie des explosions - Adding life explosions
ForEach Brick()
Brick()\BoomTime = 255
Next
;Nombre de briques à détruire pour le niveau en cours - Number of bricks to destroy this level
Brick = ListSize(Brick())
;Initialisation raquette et ball - Initialization racket and ball
SetDefault()
EndProcedure
;Dans quelle sens renvoyer la balle (usage futur)
Procedure RacquetBallReturns(RacquetPosition.i, Glue.b)
;De quelle cotés de la raquette se trouve la balle
Select RacquetPosition
Case 1 ;Extreme gauche
Case 2 ;Gauche
Case 3 ;Extreme droite
Case 4 ;Droite
EndSelect
EndProcedure
;Bonus/malus généré - What bonus/malus is generated ?
Procedure BrickCollision()
If Brick()\life = 0
Brick()\Actif = #False
Score + Brick()\Point
Brick - 1
Select Brick()\BonusMalus
Case 0, 1
Case 2 ;Balle plus grande - Greater ball
If BallR < 10
BallR + 1
EndIf
Case 3;Balle plus petite - Smaller ball
If BallR >5
BallR-1
EndIf
Case 4 ;Vitesse verticale plus grande - Vertical velocity greater
SetSpeed(0, 1)
Case 5 ;Vitesse verticale plus petite- Vertical velocity smaller
SetSpeed(0, -1)
Case 6 ;Les briques commence à descendre - Bricks begins to descend
BrickDown = #True
Case 7 ;Les briques stoppent leurs progressions vers le bas - Bricks stopent their progressions
If BrickDown = #True
BrickDown = #False
EndIf
Case 8 ;Ajout d'une vie - Adding life
Life + 1
Glue = #False
Brick()\Message = "Life+1"
Case 9 ;Enléve une vie - Removes a life
If life >3 ;On laisse au moins trois vie - Allowed at least three life
Life -1
Brick()\Message = "Life-1"
EndIf
Case 10 ;Raquette plus petite - Smaller racket
If RacquetW > 100
RacquetW - 50
EndIf
Case 11 ;Raquette plus grande - Greater racket
If RacquetW < 401
RacquetW + 50
Glue = #False
EndIf
Case 12 ;Glue active
Glue = #True
Case 13 ;Glue inactive
If Glue = #True
Glue = #False
EndIf
Case 14 ;Tir actif - active shooting
Shoot = #True
Case 15 ;Tir desactivé - shooting deactived
If Shoot = #True
Shoot = #False
EndIf
EndSelect
EndIf
Inactif = 0
EndProcedure
Procedure RunShoot()
;Tir bord gauche de la raquette - Shooting left edge of the racket
AddElement(Shoot())
Shoot()\Actif = #True
Shoot()\Lig = RacquetY
Shoot()\Col = RacquetX
Shoot()\Color = RGB(Random(255),Random(255),Random(255))
;Tir bord droit de la raquette - Shooting right edge of the racket
AddElement(Shoot())
Shoot()\Actif = #True
Shoot()\Lig = RacquetY
Shoot()\Col = RacquetX+RacquetW
Shoot()\Color = RGB(Random(255),Random(255),Random(255))
EndProcedure
Procedure Game_Refresh()
If IsGadget(#Grid)
If SpeedH = 0 And SpeedV = 0
;La vitesse de la balle est nulle : Elle est positionnée sur la raquette
If Glue = #False
BallX = RacquetX + RacquetW/2
BallY = RacquetY - BallR
Else
BallX = RacquetX + OldBallX
BallY = RacquetY - BallR
EndIf
Else
;-La Balle en cours de déplacement
BallX = BallX-SpeedH
BallY = BallY-SpeedV
EndIf
;- Des tirs sont en cours
ForEach Shoot()
If Shoot()\Actif = #True
Shoot()\Lig - 2
If Shoot()\Lig < 40
Shoot()\Actif = #False
EndIf
ForEach Brick()
If Brick()\Actif = #True
If Shoot()\Col > Brick()\col And Shoot()\Col < Brick()\col+45
If Shoot()\lig > Brick()\Lig And Shoot()\Lig < Brick()\Lig + 25
Shoot()\Actif = #False
Brick()\life-1 ;La brique perd une vie
Brick()\Color = SetBrickColor(Brick()\life)
BrickCollision()
EndIf
EndIf
EndIf
Next
Else
DeleteElement(Shoot())
EndIf
Next
;-La balle atteint le cotes gauche ou droit du canvas
If BallX <= 0 Or BallX >= GridW
SpeedH * -1 ;Inversion de la direction de la balle
Inactif + 1 ;Aucune brique est touché
EndIf
;-La balle atteint le haut du canvas
If BallY <= 50
SpeedV * -1 ;Inversion de la direction de la balle
Inactif + 1 ;Aucune brique est touché
EndIf
;-La balle percute une brique
ForEach(Brick())
If Brick()\Actif = #True
If (BallX + BallR) >= Brick()\Col And (BallX - BallR) <= Brick()\Col+BrickW ; ? Balle entre les bords lateraux
If (BallY - BallR) <= Brick()\Lig + BrickH And (BallY + BallR) > Brick()\Lig ;? Balle entre les bord haut et bas
Brick()\life-1 ;La brique perd une vie
Brick()\Color = SetBrickColor(Brick()\life)
SpeedV * -1 ;Inversion de la direction de la balle
BrickCollision()
EndIf
EndIf
EndIf
Next
;-La balle atteint le bas du canvas
If (BallY + BallR) >= RacquetY And SpeedH <> 0
Inactif + 1 ;Aucune brique est touché
Message = ""
;Mémorisation des vitesses atteintes
OldSpeedH = SpeedH
OldSpeedV = SpeedV
;Si le malus BrickDown est actif, chaque brique descend de 5 pixels
If BrickDown = #True And LostBall = #False
ForEach(Brick())
If Brick()\Actif
Brick()\Lig = Brick()\Lig + 5
If Brick()\Lig > RacquetY - 25
Message = "The bricks have reached the bottom of the screen !"
Stage + 1
SetDefault()
NewStage(Stage)
EndIf
EndIf
Next
EndIf
;-La balle arrive sur la raquette
If (BallX + BallR) >= RacquetX And BallX < (RacquetX + RacquetW/3) And LostBall = #False
;Extemité gauche de la raquette
If Glue = #False
SpeedV * -1 ;Inversion de la direction de la balle
If SpeedH < 0
SpeedH * -1
EndIf
SetSpeed(2 , 0)
Else
SetSpeed(0, 0)
OldBallX = BallX - RacquetX
EndIf
ElseIf (BallX + BallR) >= RacquetX And BallX <= (RacquetX + RacquetW/2) And LostBall = #False
;Moitié gauche de la raquette
If Glue = #False
SpeedV * -1 ;Inversion de la direction de la balle
If SpeedH < 0
SpeedH * -1
EndIf
Else
SetSpeed(0, 0)
OldBallX = BallX - RacquetX
EndIf
ElseIf BallX > (RacquetX + RacquetW - RacquetW/3) And (BallX - BallR) <= (RacquetX + RacquetW) And LostBall = #False
;Extrémité droite de la raquette
If Glue = #False
SpeedV * -1 ;Inversion de la direction de la balle
If SpeedH > 0
SpeedH * -1
EndIf
SetSpeed(-2, 0)
Else
SetSpeed(0, 0)
OldBallX = BallX - RacquetX
EndIf
ElseIf BallX >=(RacquetX + RacquetW/2) And (BallX - BallR) <= (RacquetX + RacquetW) And LostBall = #False
;Moitié Droite de la raquette
If Glue = #False
SpeedV * -1 ;Inversion de la direction de la balle
If SpeedH > 0
SpeedH * -1
EndIf
Else
SetSpeed(0, 0)
OldBallX = BallX - RacquetX
EndIf
Else
;-La balle est perdu
LostBall = #True
SpeedV = 0 ;On evite le déplacement verticale
SpeedH = 1 ;La balle repart vers le cotes gauche
BallY = GridH - 2*BallR
If BallX = 0
SpeedH = 0
Life-1
Message = "Ooooops : Life - 1"
SetDefault()
EndIf
EndIf
EndIf ;End Grid actif
If Inactif > 10 And SpeedV <> 0
Glue = #False
Inactif = 0
SetSpeed(0, 1)
Message = "No broken bricks for a long time : Speed +"
EndIf
;-Mise à jour du canvas
StartDrawing(CanvasOutput(#Grid))
;-= Efface l'image précédente
Box(0, 0, GridW, GridH, RGB(128, 128, 128))
;-= Affichage de l'entete (Score, Message, Vie)
Box(0, 0, GridW, 40, RGB(241, 215, 221)) ;Fond du bandeau
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(#ScoreFont))
DrawText(10, 10, "Score : " + Str(Score), RGB(0,0,0))
DrawText(150, 10, Message, RGB(0,0,0))
DrawText(GridW-80, 10, "Life : " + Str(Life), RGB(0,0,0))
;-= Affichage des briques
ForEach Brick()
If Brick()\Actif = #True
DrawingMode(#PB_2DDrawing_Default)
RoundBox(Brick()\Col, Brick()\Lig, BrickW, BrickH, 5, 5, Brick()\Color)
DrawingMode(#PB_2DDrawing_Outlined)
RoundBox(Brick()\Col, Brick()\Lig, BrickW, BrickH, 5, 5, RGB(0, 0, 0))
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(#NormalFont))
DrawText(Brick()\Col+(45-TextWidth(Str(Brick()\life)))/2, Brick()\Lig+2, Str(Brick()\life), RGB(0, 0, 0))
Else
If Brick()\BoomTime > 0
Brick()\BoomTime - 1
Brick()\Lig + 1
DrawingMode(#PB_2DDrawing_AlphaBlend)
RoundBox(Brick()\Col, Brick()\Lig, BrickW, BrickH, 5, 5, RGBA(Red(Brick()\Color),Green(Brick()\Color),Blue(Brick()\Color),Brick()\BoomTime))
DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
DrawingFont(FontID(#NormalFont))
DrawText(Brick()\Col+(45-TextWidth(Brick()\Message))/2, Brick()\Lig, Brick()\Message, RGBA(0, 0, 0, Brick()\BoomTime))
Else
DeleteElement(Brick())
EndIf
EndIf
Next
;-= Affichage de la raquette
DrawingMode(#PB_2DDrawing_Default)
RoundBox(RacquetX, RacquetY, RacquetW, RacquetH, 4, 4, RGB(169, 169, 169))
DrawingMode(#PB_2DDrawing_Outlined)
RoundBox(RacquetX, RacquetY, RacquetW, RacquetH, 4, 4, RGB(0, 0, 0))
If Glue = #True ;Glue Actif
DrawingMode(#PB_2DDrawing_AlphaBlend)
RoundBox(RacquetX-5, RacquetY-5, RacquetW+10, RacquetH+5, 4, 4, RGBA(242, 161, 239, 155))
EndIf
;-= Affichage des canons
If Shoot = #True
DrawingMode(#PB_2DDrawing_Default)
Ellipse(RacquetX, RacquetY, 3, 15, RGB(151, 164, 155))
Ellipse(RacquetX+RacquetW, RacquetY, 3, 15, RGB(151, 164, 155))
EndIf
;-= Affichage des tirs
ForEach Shoot()
DrawingMode(#PB_2DDrawing_Default)
Circle(Shoot()\Col, Shoot()\Lig, 3, shoot()\Color)
Next
;-= Affichage de la balle
DrawingMode(#PB_2DDrawing_Default)
Circle(BallX, BallY, BallR, RGB(255, 140, 0))
DrawingMode(#PB_2DDrawing_Outlined)
Circle(BallX, BallY, BallR, RGB(0, 0, 0))
;Message
If Life = 0
;-Plus de vie
BallR = 0
MessageBox("Game Over !")
EndIf
;- Passage au niveau suivant
If Brick=0
Stage+1
NewStage(Stage)
Message = "Stage " + Str(Stage) +"/"+ Str(MaxStage)
EndIf
If Stage > MaxStage
;-Fin de la partie : C'est gagné
MessageBox("Winner")
EndIf
StopDrawing()
EndIf
EndProcedure
Procedure Game_Start()
;Fonts
LoadFont(#NormalFont, "Arial", 10)
LoadFont(#ScoreFont, "Arial", 12)
LoadFont(#BigFont, "Arial", 70)
LoadFont(#BigFontOutLine, "Arial", 75)
;Affichage fenetre & canvas
GridW = 800
GridH = 700
If Not IsWindow(#Mainform)
Open_MainForm()
EndIf
BrickW = 45
BrickH = 20
SetDefault()
;Positionnement de la raquette (Px)
RacquetX = (GridW-RacquetW)/2
RacquetY = GridH-50
;Score
Score = 0
Life = 3
;Bonus Malus
MaxRnd = 16
;Vitesse Minimum et maximum
MinSpeed = 1
MaxSpeed = 4
;Scene
Stage = 1
MaxStage =3
;Premiere scene
NewStage(1)
EndProcedure
Procedure Game_Stop()
End
EndProcedure
Game_start()
;-Boucle evenementielle
Repeat
Event = WaitWindowEvent(0)
WEvent = EventWindow()
MEvent = EventMenu()
GEvent = EventGadget()
TEvent = EventType()
Game_Refresh()
Select Event
Case #PB_Event_Gadget
Select GEvent
Case #Grid
Select TEvent
Case #PB_EventType_LeftButtonDown
If SpeedH = 0 And SpeedV = 0 And Life > 0 And Brick > 0
;La balle n'est pas encore lancé
If Glue = #True
;La colle est actif (Glue = #True)
SpeedH = -OldSpeedH
SpeedV = -OldSpeedV
Else
;La colle est pas active (Glue = #False)
SetSpeed(MinSpeed, MinSpeed+2)
If BallX > GridW/2
If SpeedH > 0
SpeedH * -1
EndIf
EndIf
EndIf
;Glue=#True
EndIf
If Shoot = #True And LostBall = #False
RunShoot()
EndIf
Case #PB_EventType_RightButtonDown
SpeedH * -1 ;Inverse le déplacement horizontale de la balle
Case #PB_EventType_MouseMove
;Cache le cursor
SetGadgetAttribute(#Grid, #PB_Canvas_Cursor, #PB_Cursor_Invisible)
;Récupération de la position horizontale (Cotes gauche) de la raquette
RacquetX = GetGadgetAttribute(#Grid, #PB_Canvas_MouseX)
If RacquetX + RacquetW > GridW
RacquetX = GridW-RacquetW
EndIf
Case #PB_EventType_KeyDown
Select GetGadgetAttribute(#Grid, #PB_Canvas_Key)
Case #VK_N ;Nouvelle partie
Game_Start()
Case #VK_C ; Clip/unclip mouse
If GetGadgetData(#Grid) = #False
SetGadgetAttribute(#Grid, #PB_Canvas_Clip , #True)
SetGadgetData(#Grid, #True)
Else
SetGadgetAttribute(#Grid, #PB_Canvas_Clip , #False)
SetGadgetData(#Grid, #False)
EndIf
Case #VK_PAUSE ;Partie en pause
SetSpeed(0,0)
Case #VK_ESCAPE ;Fin du jeu
Game_Stop()
EndSelect
EndSelect ;End TEvent
EndSelect ;End Gevent
Case #PB_Event_CloseWindow
Game_Stop()
EndSelect ;End Event
ForEver