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)