Partager via


Small Basic: Exemple - Tetris (fr-FR)

Voici un simple jeu de Tetris écrit en Microsoft Small Basic.

Le code original n'était plus compatible avec les versions actuelles de Small Basic, il a été corrigé et cette version traduite se base sur ce code plus récent. Si vous voulez récupérer le code original, visiter l'article original pour les liens.

Vous pouvez importer le code avec les commentaires en français : RCC554.

Voici une capture d'écran:

Code Source:

GraphicsWindow.KeyDown = HandleKey
GraphicsWindow.BackgroundColor = GraphicsWindow.GetColorFromRGB( 253,  252, 251 )
 
While "True"
  BOXES = 4      ' nombre de blocs par pièce
  BWIDTH = 25    ' largeur de bloc en pixels
  XOFFSET = 40   ' Offset X en pixels où démarre le tableau par rapport à l'écran
  YOFFSET = 40   ' Offset Y en pixels où démarre le tableau par rapport à l'écran
  CWIDTH = 10    ' Largeur de la zone de dessin en nombre de blocs
  CHEIGHT = 20   ' Hauteur de la zone de dessin en nombre de blocs
  STARTDELAY = 800
  ENDDELAY = 175
  PREVIEW_xpos = 13
  PREVIEW_ypos = 2
  
  GraphicsWindow.Clear()
  GraphicsWindow.Title = "Small Basic Tetris"
  GraphicsWindow.Height = 580
  GraphicsWindow.Width = 700
  GraphicsWindow.Show()
 
  SetupTemplates()
  SetupCanvas()
  MainLoop()
  
  GraphicsWindow.ShowMessage( "Perdu !",  "Small Basic Tetris" )
EndWhile
 
Sub MainLoop
  template = Text.Append("template", Math.GetRandomNumber(7))
 
  CreatePiece() ' in: template ret: h
  nextPiece = h
 
  end = 0
  sessionDelay = STARTDELAY
  While end =  0
    If sessionDelay > ENDDELAY Then
      sessionDelay = sessionDelay - 1
    EndIf
    
    delay = sessionDelay
 
    thisPiece = nextPiece
 
    template = Text.Append("template", Math.GetRandomNumber(7))
 
 
    CreatePiece() ' in: template ret: h
    nextPiece = h
    DrawPreviewPiece()
    
    h = thisPiece    
    
    ypos = 0
    done = 0
    xpos = 3  ' toujours faire apparître à la colonne 3
    CheckStop() ' in: ypos, xpos, h ret: done
    If done =  1 Then
      ypos = ypos  - 1
      MovePiece()  'in: ypos, xpos, h
      end = 1
    EndIf
    
    yposdelta = 0
    While done =  0 Or yposdelta > 0
      MovePiece()  'in: ypos, xpos, h
      
      'Pause, mais on l'abrège si le délai est défini à 0 quand une pièce est tombée
      delayIndex = delay      
      While delayIndex > 0 And  delay > 0
        Program.Delay(10)
        delayIndex = delayIndex - 10
      EndWhile  
 
      If yposdelta > 0 Then
        yposdelta = yposdelta - 1  ' utilisée pour créer 'freespin', lorsque la pièce est pivotée
      Else
        ypos = ypos  + 1            ' sinon on descend la pièce.
      EndIf
      
      ' Détermine si la pièce va s'arrêter de tomber.
      CheckStop() ' in: ypos, xpos, h ret: done 
    EndWhile
  EndWhile
EndSub
 
 
Sub HandleKey
  ' Arrêt du jeu
  If GraphicsWindow.LastKey = "Escape"  Then
    Program.End()
  EndIf
 
  ' Déplace la pièce vers la gauche
  If GraphicsWindow.LastKey = "Left"  Then
    moveDirection = -1
    ValidateMove()  ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 ou -1 ou 2 si le mouvement est invalide, sinon 0
    If invalidMove = 0 Then
      xpos = xpos  + moveDirection
    EndIf
    MovePiece()  'in: ypos, xpos, h
  EndIf
  
  ' Déplace la pièce à droite
  If GraphicsWindow.LastKey = "Right"  Then
    moveDirection = 1
    ValidateMove()  ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 ou -1 ou 2 si le mouvement est invalide, sinon 0
    If invalidMove = 0 Then
      xpos = xpos  + moveDirection
    EndIf
    MovePiece()  'in: ypos, xpos, h
  EndIf
  
  ' Déplace la pièce vers le bas
  If GraphicsWindow.LastKey = "Down"  Or GraphicsWindow.LastKey = "Space"  Then
    delay = 0
  EndIf
  
  ' Pivote la pièce
  If GraphicsWindow.LastKey = "Up"  Then
    basetemplate = Array.GetValue(h, -1)  ' Array.GetValue(h, -1) = nom du modèle
    template = "temptemplate"
    rotation = "CW"
    CopyPiece()  'in basetemplate, template, rotation
 
    Array.SetValue(h, -1, template)  ' Array.GetValue(h, -1) = nom du modèle
    moveDirection = 0
    ValidateMove()  ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 ou -1 ou 2 si le mouvement est invalide, sinon 0
    
    ' Détermine si la pièce peut se déplacer, et par conséquent elle sera pivotée.
    xposbk = xpos
    yposdelta = 0
    While yposdelta = 0 And  Math.Abs(xposbk - xpos) < 3  ' déplace 3 fois seulement
      
      ' si la rotation fonctionne, coppie le modèle dans "rotatedtemplate" et l'utilise à partir de maintenant
      If invalidMove = 0 Then
        basetemplate = template
        template = "rotatedtemplate"
        Array.SetValue(h, -1, template)  ' Array.GetValue(h, -1) = nom du modèle
        rotation = "COPY"
        CopyPiece()  'in basetemplate, template, rotation
        yposdelta = 1  ' Ne pas déplacer vers le bas si il y a une rotation
        MovePiece()  'in: ypos, xpos, h
      ElseIf invalidMove = 2 Then
        ' Ne supporte les pièces qui bougent lorsqu'elles touchent une autre pièce à droite ou a gauche.
        xpos = 99  ' sortie de la boucle
      Else
        ' si la pièce pivotée ne peut pas être placée, déplace à gauche ou à droite et réessayer.
        xpos = xpos  - invalidMove
        ValidateMove()  ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 ou -1 ou 2 si le mouvement est invalide, sinon 0
      EndIf
    EndWhile
        
    If invalidMove <> 0 Then
      xpos = xposbk
      Array.SetValue(h, -1, basetemplate) ' Array.GetValue(h, -1) = nom du modèle
      template = ""
    EndIf      
  EndIf
EndSub
 
 
Sub DrawPreviewPiece
  xpos = PREVIEW_xpos
  ypos = PREVIEW_ypos
  h = nextPiece
 
  XOFFSETBK = XOFFSET
  YOFFSETBK = YOFFSET
  XOFFSET = XOFFSET  + Array.GetValue(Array.GetValue(h, -1), "pviewx")  ' Array.GetValue(h, -1) = nom du modèle
  YOFFSET = YOFFSET  + Array.GetValue(Array.GetValue(h, -1), "pviewy")  ' Array.GetValue(h, -1) = nom du modèle
  MovePiece()  'in: ypos, xpos, h
 
  XOFFSET = XOFFSETBK
  YOFFSET = YOFFSETBK
  
EndSub
 
 
' création d'un modèle qui est un 'baseTemplate" pivoté
Sub CopyPiece  'in basetemplate, template, rotation 
  L = Array.GetValue(basetemplate, "dim")
  
  If rotation =  "CW" Then
    For i =  0 To BOXES -  1 ' x' = y y' = L - 1 - x
      v = Array.GetValue(basetemplate, i)
 
      'x = Math.Floor(v/10)
      'y = Math.Remainder(v, 10)
      
      ' nouveaux x et y
      x = (Math.Remainder(v, 10))
      y = (L - 1  - Math.Floor(v/10))
      Array.SetValue(template, i, x * 10  + y)
    EndFor
  ' "Count-Cockwise" n'est actuellement pas utilisé
  ElseIf rotation =  "CCW" Then
    For i =  0 To BOXES -  1 ' x' = L - 1 - y y' = x
      v = Array.GetValue(basetemplate, i)
      'x = Math.Floor(v/10)
      'y = Math.Remainder(v, 10)
 
      ' nouveaux x et y
      x = (L - 1  - Math.Remainder(v, 10))
      y = Math.Floor(v/10)
      Array.SetValue(template, i, x * 10  + y)
    EndFor
  ElseIf rotation =  "COPY" Then
    For i =  0 To BOXES -  1
      Array.SetValue(template, i, Array.GetValue(basetemplate, i))
    EndFor
  Else
    GraphicsWindow.ShowMessage("paramètre invalide", "Erreur")
    Program.End()
  EndIf
  
  ' Copy les propriétés restantes de baseTemplate vers template.
  Array.SetValue(template, "color",  Array.GetValue(basetemplate, "color"))
  Array.SetValue(template, "dim",  Array.GetValue(basetemplate, "dim"))
  Array.SetValue(template, "pviewx",  Array.GetValue(basetemplate, "pviewx"))
  Array.SetValue(template, "pviewy",  Array.GetValue(basetemplate, "pviewy"))
EndSub
  
  
Sub CreatePiece ' in: template ret: h
  ' Créé un nouveau 'pointeur', utilisé dans les tableaux de noms, qui va contenir la pièce
  hcount = hcount  + 1
  h = Text.Append("piece", hcount)
  
  Array.SetValue(h, -1, template)  ' Array.GetValue(h, -1) = nom du modèle
 
  GraphicsWindow.PenWidth = 1
  GraphicsWindow.PenColor = "Black"
  GraphicsWindow.BrushColor = Array.GetValue(template, "color")
  
  For i =  0 To BOXES -  1
    s = Shapes.AddRectangle(BWIDTH, BWIDTH)
    Shapes.Move(s, -BWIDTH, -BWIDTH) ' move off screen
    Array.SetValue(h, i, s)
  EndFor
EndSub
  
 
Sub MovePiece 'in: ypos, xpos, h. ypos/xpos is 0-19, correspondant au coin supérieur gauche de la pièce dans la zone de dessin. h retourné par CreatePiece
  For i =  0 To BOXES -  1
    v = Array.GetValue(Array.GetValue(h, -1), i)  ' Array.GetValue(h, -1) = nom du modèle
    x = Math.Floor(v/10)
    y = Math.Remainder(v, 10)
    
    ' Array.GetValue(h, i) = box for piece h.
    ' xpos/ypos = coin supérieur gauche de la forme. x/y est le bloc offset dans la forme.
    Shapes.Move(Array.GetValue(h, i), XOFFSET +  xpos * BWIDTH + x  * BWIDTH, YOFFSET +  ypos * BWIDTH + y  * BWIDTH)
  EndFor
EndSub
 
 
Sub ValidateMove ' in: ypos, xpos, h, moveDirection ret: invalidMove = 1 ou -1 ou 2 si le mouvement est invalide, sinon 0
  i = 0
  invalidMove = 0
  While i <  BOXES
    v = Array.GetValue(Array.GetValue(h, -1), i)  ' Array.GetValue(h, -1) = le nom du modèle
 
    'x/y est le bloc offset dans la forme.
    x = Math.Floor(v/10)
    y = Math.Remainder(v, 10)
    
    If (x + xpos +  moveDirection)  < 0 Then
      invalidMove = -1
      i = BOXES  ' force à sortir de la boucle
    EndIf
 
    If (x + xpos +  moveDirection)  >= CWIDTH Then
      invalidMove = 1
      i = BOXES  ' force à sortir de la boucle
    EndIf
 
    If Array.GetValue("c", (x + xpos +  moveDirection)  + (y + ypos) * CWIDTH) <> "." Then
      invalidMove = 2
      i = BOXES  ' force à sortir de la boucle
    EndIf
 
    i = i  + 1
  EndWhile
EndSub
 
 
Sub CheckStop ' in: ypos, xpos, h ret: done
  done = 0
  i = 0
  While i <  BOXES
    v = Array.GetValue(Array.GetValue(h, -1), i)  ' Array.GetValue(h, -1) = nom du modèle
 
    'x/y est le bloc offset dans la forme.
    x = Math.Floor(v/10)
    y = Math.Remainder(v, 10)
    
    If y +  ypos > CHEIGHT Or Array.GetValue("c", (x + xpos)  + (y + ypos) * CWIDTH) <> "." Then
      done = 1
      i = BOXES  ' force à sortir de la boucle
    EndIf
 
    i = i  + 1
  EndWhile
 
  ' Si nous avons besoin d'arrêter la pièce, déplace les blocs 'pointeurs' dans la zone de dessin
  If done =  1 Then
    For i =  0 To BOXES -  1
      v = Array.GetValue(Array.GetValue(h, -1), i) ' Array.GetValue(h, -1) = le nom du modèle
      'x = Math.Floor(v/10)
      'y = Math.Remainder(v, 10) 
      Array.SetValue("c", (Math.Floor(v/10) + xpos) + (Math.Remainder(v, 10)  + ypos - 1) * CWIDTH,  Array.GetValue(h, i))
    EndFor
    
    ' 1 point pour chaque pièce correctement posée
    score = score  + 1
    PrintScore()
     
    ' Supprime les lignes complètes
    DeleteLines()
  EndIf
EndSub
 
 
Sub DeleteLines
  linesCleared = 0
  
  ' Boucle sur chaque ligne, en commençant par le bas
  For y =  CHEIGHT - 1 To 0 Step -1  
    
    ' Vérifie si la ligne entière est remplie
    x = CWIDTH
    While x =  CWIDTH
      x = 0
      While x <  CWIDTH
        piece = Array.GetValue("c", x +  y * CWIDTH)
        If piece =  "." Then
          x = CWIDTH
        EndIf
        x = x  + 1
      EndWhile
      
      ' si aucun des blocs n'est vide (c'est-à-dire "."), alors retire la ligne.
      If x =  CWIDTH Then
        
        ' Supprime la ligne
        For x1 =  0 To CWIDTH -  1
          Shapes.Remove(Array.GetValue("c", x1 +  y * CWIDTH))
        EndFor
        linesCleared = linesCleared + 1
        
        ' Déplace tout vers le bas.
        For y1 =  y To 1 Step -1
          For x1 =  0 To CWIDTH -  1
            piece = Array.GetValue("c", x1 +  (y1 - 1) * CWIDTH)
            Array.SetValue("c", x1 +  y1 * CWIDTH, piece)
            Shapes.Move(piece, Shapes.GetLeft(piece), Shapes.GetTop(piece) + BWIDTH)
          EndFor
        EndFor
      EndIf
    EndWhile
  EndFor
  
  If linesCleared > 0 Then
    score = score  + 100 * Math.Round(linesCleared * 2.15  - 1)
    PrintScore()
  EndIf
EndSub
 
Sub SetupCanvas
' GraphicsWindow.DrawResizedImage( Flickr.GetRandomPicture( "bricks" ), 0, 0, GraphicsWindow.Width, GraphicsWindow.Height)
 
  
  GraphicsWindow.BrushColor = GraphicsWindow.BackgroundColor
  GraphicsWindow.FillRectangle(XOFFSET, YOFFSET,  CWIDTH*BWIDTH, CHEIGHT*BWIDTH)
 
  Program.Delay(200)
  GraphicsWindow.PenWidth = 1
  GraphicsWindow.PenColor = "Pink"
  For x =  0 To CWIDTH-1
    For y =  0 To CHEIGHT-1
      Array.SetValue("c", x +  y * CWIDTH, ".")  ' "." indique que l'emplacement est libre
      GraphicsWindow.DrawRectangle(XOFFSET + x  * BWIDTH, YOFFSET +  y * BWIDTH, BWIDTH,  BWIDTH)
    EndFor
  EndFor
 
  GraphicsWindow.PenWidth = 4
  GraphicsWindow.PenColor = "Black"
  GraphicsWindow.DrawLine(XOFFSET, YOFFSET,  XOFFSET, YOFFSET + CHEIGHT*BWIDTH)
  GraphicsWindow.DrawLine(XOFFSET + CWIDTH*BWIDTH, YOFFSET,  XOFFSET + CWIDTH*BWIDTH, YOFFSET +  CHEIGHT*BWIDTH)
  GraphicsWindow.DrawLine(XOFFSET, YOFFSET +  CHEIGHT*BWIDTH, XOFFSET +  CWIDTH*BWIDTH, YOFFSET +  CHEIGHT*BWIDTH)
  
  GraphicsWindow.PenColor = "Lime"
  GraphicsWindow.DrawLine(XOFFSET - 4, YOFFSET,  XOFFSET - 4, YOFFSET +  CHEIGHT*BWIDTH + 6)
  GraphicsWindow.DrawLine(XOFFSET + CWIDTH*BWIDTH + 4, YOFFSET,  XOFFSET + CWIDTH*BWIDTH + 4, YOFFSET +  CHEIGHT*BWIDTH + 6)
  GraphicsWindow.DrawLine(XOFFSET - 4, YOFFSET +  CHEIGHT*BWIDTH + 4, XOFFSET +  CWIDTH*BWIDTH + 4, YOFFSET +  CHEIGHT*BWIDTH + 4)
  
  GraphicsWindow.PenColor = "Black"
  GraphicsWindow.BrushColor = "Pink"
  x = XOFFSET  + PREVIEW_xpos  * BWIDTH - BWIDTH
  y = YOFFSET  + PREVIEW_ypos  * BWIDTH - BWIDTH
  GraphicsWindow.FillRectangle(x, y, BWIDTH * 5, BWIDTH *  6)
  GraphicsWindow.DrawRectangle(x, y, BWIDTH * 5, BWIDTH *  6)
  
  GraphicsWindow.FillRectangle(x - 20, y +  190, 310, 170)
  GraphicsWindow.DrawRectangle(x - 20, y +  190, 310, 170)
  
  GraphicsWindow.BrushColor = "Black"
  GraphicsWindow.FontItalic = "False"
  GraphicsWindow.FontName = "Comic Sans MS"
  GraphicsWindow.FontSize = 16
  GraphicsWindow.DrawText(x, y +  200, "Touches de contrôle du jeu :")
  GraphicsWindow.DrawText(x + 25, y +  220, "Gauche = Déplace à gauche")
  GraphicsWindow.DrawText(x + 25, y +  240, "Droite = Déplace à droite")
  GraphicsWindow.DrawText(x + 25, y +  260, "Haut = Pivote la pièce")
  GraphicsWindow.DrawText(x + 25, y +  280, "Bas = Place la pièce")
  GraphicsWindow.DrawText(x, y +  320, "'Echap' pour arrêter le jeu")
 
  Program.Delay(200) ' Sans cette pause, le texte ci-dessus utilisera la taille de la police du score
 
  GraphicsWindow.BrushColor = "Black"
  GraphicsWindow.FontName = "Georgia"
  GraphicsWindow.FontItalic = "True"
  GraphicsWindow.FontSize = 36
  GraphicsWindow.DrawText(x - 20, y +  400, "Small Basic Tetris")
  Program.Delay(200) ' Sans cette pause, le texte ci-dessus utilisera la taille de la police du score
  GraphicsWindow.FontSize = 16
  GraphicsWindow.DrawText(x - 20, y +  440, "ver.0.1")
 
  Program.Delay(200) ' Sans cette pause, le texte ci-dessus utilisera la taille de la police du score
  score = 0
  PrintScore() 
EndSub
 
 
Sub PrintScore
  GraphicsWindow.PenWidth = 4
  GraphicsWindow.BrushColor = "Pink"
  GraphicsWindow.FillRectangle(500, 65,  153, 50)
  GraphicsWindow.BrushColor = "Black"
  GraphicsWindow.DrawRectangle(500, 65,  153, 50)
  GraphicsWindow.FontItalic = "False"
  GraphicsWindow.FontSize = 32
  GraphicsWindow.FontName = "Impact"
  GraphicsWindow.BrushColor = "Black"
  GraphicsWindow.DrawText(505, 70,  Text.Append(Text.GetSubText( "00000000", 0, 8 - Text.GetLength( score )  ), score))
EndSub
 
 
Sub SetupTemplates
  ' chaque pièce est constituée de 4 blocs.
  ' l'index de chaque entrée de la pièce représente le numéro du bloc (1-4)
  ' la valeur de chaque entrée représente les coordonnées du bloc dans la pièce basé sur zéro: les dizaine indiquent x, les unités indiquent y
 
  '_X_
  '_X_
  '_XX
 
  Array.SetValue("template1", 0, 10)
  Array.SetValue("template1", 1, 11)
  Array.SetValue("template1", 2, 12)
  Array.SetValue("template1", 3, 22)
  Array.SetValue("template1", "color",  "Yellow")
  Array.SetValue("template1", "dim",  3)
  Array.SetValue("template1", "pviewx",  -12)
  Array.SetValue("template1", "pviewy",  12)
 
 
  '_X_
  '_X_
  'XX_
  Array.SetValue("template2", 0, 10)
  Array.SetValue("template2", 1, 11)
  Array.SetValue("template2", 2, 12)
  Array.SetValue("template2", 3, 02)
  Array.SetValue("template2", "color",  "Magenta")
  Array.SetValue("template2", "dim",  3)
  Array.SetValue("template2", "pviewx",  12)
  Array.SetValue("template2", "pviewy",  12)
  
  
  '_X_
  'XXX
  '_
  Array.SetValue("template3", 0, 10)
  Array.SetValue("template3", 1, 01)
  Array.SetValue("template3", 2, 11)
  Array.SetValue("template3", 3, 21)
  Array.SetValue("template3", "color",  "Gray")
  Array.SetValue("template3", "dim",  3)
  Array.SetValue("template3", "pviewx",  0)
  Array.SetValue("template3", "pviewy",  25)
  
  
  'XX_
  'XX_
  '_
  Array.SetValue("template4", 0, 00)
  Array.SetValue("template4", 1, 10)
  Array.SetValue("template4", 2, 01)
  Array.SetValue("template4", 3, 11)
  Array.SetValue("template4", "color",  "Cyan")
  Array.SetValue("template4", "dim",  2)
  Array.SetValue("template4", "pviewx",  12)
  Array.SetValue("template4", "pviewy",  25)
  
  
  'XX_
  '_XX
  '_
  Array.SetValue("template5", 0, 00)
  Array.SetValue("template5", 1, 10)
  Array.SetValue("template5", 2, 11)
  Array.SetValue("template5", 3, 21)
  Array.SetValue("template5", "color",  "Green")
  Array.SetValue("template5", "dim",  3)
  Array.SetValue("template5", "pviewx",  0)
  Array.SetValue("template5", "pviewy",  25)
  
  
  '_XX
  'XX_
  '_
  Array.SetValue("template6", 0, 10)
  Array.SetValue("template6", 1, 20)
  Array.SetValue("template6", 2, 01)
  Array.SetValue("template6", 3, 11)
  Array.SetValue("template6", "color",  "Blue")
  Array.SetValue("template6", "dim",  3)
  Array.SetValue("template6", "pviewx",  0)
  Array.SetValue("template6", "pviewy",  25)
  
  
  '_X
  '_X
  '_X
  '_X
  Array.SetValue("template7", 0, 10)
  Array.SetValue("template7", 1, 11)
  Array.SetValue("template7", 2, 12)
  Array.SetValue("template7", 3, 13)
  Array.SetValue("template7", "color",  "Red")
  Array.SetValue("template7", "dim",  4)
  Array.SetValue("template7", "pviewx",  0)
  Array.SetValue("template7", "pviewy",  0)
    
EndSub
 

By Kenny Kasajian.

Autres Langues

Article original : Small Basic Sample: Tetris (en-US)