Page 1 sur 4

[2D] Kanoid 1.60 : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 11:12
par falsam
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.

Image

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).

:arrow: 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
:arrow: Télécharger Kanoid Update (Source seul 7 Ko)

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

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 11:23
par GallyHC
Bonjour,

Bon petit code (encore quelque bug, que tu as je penses déjà vu). En tout cas cela n'est vraiment pas mal du tout, reste a le finir et ce sera un futur grand casse brique.

Cordialement,
GallyHC

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 11:29
par falsam
GallyHC a écrit :Bon petit code
Merci Gally :)
GallyHC a écrit :encore quelque bug, que tu as je penses déjà vu
Vu oui ..... mais ou dans ce code ? :mrgreen:

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 11:35
par GallyHC
En gros la balle a ricoché sur la raquette plusieurs fois jusqu'à allé en dehors de celle-ci et perdre une vie. Après c’est plus dans les mouvements de la balle (sauf erreur de ma part) ou par moment elle ricoche avec un angle non normale (d’après moi, toujours sauf erreur de ma part).

Cordialement,
GallyHC

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 11:45
par falsam
La raquette est divisé en 4 parties.
Chaque partie engendre une vitesse horizontale différente

-Cotes gauche de la raquette :
-Extrémité gauche de la raquette
-Cotes droit de la raquette
-Extrémité droit de la raquette.

Lorsque la balle rebondi sur une extrémité de la raquette, la vitesse horizontal de la balle est augmenté.

Code : Tout sélectionner

      If BallX + BallR >= RacquetX And BallX + BallR < RacquetX + RacquetW/3
        ;Extemité gauche de la raquette 
        If Glue = #False
          SpeedV * -1
          SpeedH = 4
        Else
          SpeedV = 0
          SpeedH = 0
        EndIf
        
      ElseIf BallX + BallR >= RacquetX And BallX + BallR =< RacquetX + RacquetW/2
        ;Moitié gauche de la raquette
        If Glue = #False
          SpeedV * -1
          SpeedH = 1 
        Else
          SpeedV = 0
          SpeedH = 0
        EndIf       
        
      ElseIf BallX - BallR <= RacquetX + RacquetW And BallX - BallR > RacquetX + RacquetW - RacquetW/3
        ;Extrémité droite de la raquette
        If Glue = #False
          SpeedV * -1
          SpeedH = -4
        Else
          SpeedV = 0
          SpeedH = 0
        EndIf
                   
      ElseIf BallX - BallR <= RacquetX + RacquetW And BallX + BallR > RacquetX + RacquetW/2        
        ;Moitié Droite de la raquette
        If Glue = #False
          SpeedV * -1
          SpeedH = -1
        Else
          SpeedV = 0
          SpeedH = 0
        EndIf
        
      Else
        ;Ooops loupé !!  
        SpeedV = 0
        SpeedH = 0
        
        Life-1
        Message = "Ooooops : Life -"
        SetDefault()
      EndIf        
    EndIf

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 11:53
par falsam
Les niveaux sont décrits dans la procédure NewStage()N'hésitez pas à poster vos niveaux. je j'ajouterais au code.

Si vous créez un niveau, n'oubliez pas d'incrémenter la variable MaxStage dans la procédure Game_Start().
Pour tester directement votre niveau, modifier dans la procédure Game_Start() NewStage(1) par NewStage(VotreNumeroDeNiveau)

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 12:10
par falsam
Quand la raquette se retrouvait à l’extrémité droite du jeu, la balle partait toute seule très lentement. Ce bug est corrigé et le code est mis à jour. Un de moins.

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 12:42
par Mindphazer
Rhâ
Le compilateur Mac ne connaît pas les constantes #VK_N, #VK_PAUSE et #VK_ESCAPE

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 12:52
par falsam
Mindphazer a écrit :Rhâ
Le compilateur Mac ne connaît pas les constantes #VK_N, #VK_PAUSE et #VK_ESCAPE
Voila le genre de truc qui m'escagace. Je pensais que c'était une solution cross-platform.

Ajoute dans l'énumération

Code : Tout sélectionner

  #VK_N = 78
  #VK_PAUSE = 19
  #VK_ESCAPE = 27
J’espère que le canvas apparaît correctement sous OSx sans trace de rémanence.

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 13:15
par Mindphazer
Fonctionne mieux !
Pas de problème d'affichage du canvas sous OS X
Les mêmes problèmes de ralentissements de la balle (à croire qu'il y a des pièges cachés ou la balle s'englue !!) que tu évoques dans ton post.

Mais sinon, bien sympa.
Une -nouvelle- démonstration de tout ce qu'on peu faire avec le canvas....

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 13:21
par falsam
Mindphazer a écrit :Fonctionne mieux !
Pas de problème d'affichage du canvas sous OS X
Les mêmes problèmes de ralentissements de la balle (à croire qu'il y a des pièges cachés ou la balle s'englue !!) que tu évoques dans ton post.

Mais sinon, bien sympa.
Une -nouvelle- démonstration de tout ce qu'on peu faire avec le canvas....
Merci pour ce retour. Je suis à la recherche des traces de glue :p

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 13:40
par Le Soldat Inconnu
Sympa :)

Je trouve juste dommage qu'on ne voit pas la balle tomber sous la raquette, histoire de bien voir qu'on a raté la balle, ce qui arrive souvent (du moins pour moi :D )

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 13:44
par falsam
Le Soldat Inconnu a écrit :Sympa :)
Je trouve juste dommage qu'on ne voit pas la balle tomber sous la raquette, histoire de bien voir qu'on a raté la balle, ce qui arrive souvent (du moins pour moi :D )
Ajouter dans mes trucs à faire (Todo List). Merci :)

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : lun. 08/oct./2012 17:23
par Ar-S
Merci et bravo Falsam.
ça me donne envie de me remettre à mon casse brique. En Canvas plutôt qu'en Screen pourquoi pas. :P

----edit----

lors de l'option Glue, la balle se recentre sur la raquette, il faudrait qu'elle se colle à l'endroit ou elle se pose et qu'elle reparte dans l'ange qu'elle était partie pour prendre si elle ne c'était pas collée.

Re: [2D] Kanoid : Un casse brique dans un CanvasGadget

Publié : mar. 09/oct./2012 8:01
par djes
Héhéhé :)