Sunteți pe pagina 1din 16

UNIVERSITATEA DIN BUCUREŞTI

FACULTATEA MATEMATICĂ-INFORMATICĂ
SPECIALIZAREA TEHNOLOGIA INFORMAŢIEI

MEDII DE PROGRAMARE VIZUALĂ


- TETRIS -

CONDUCĂTOR ŞTIINŢIFIC: STUDENT:

Bucureşti
2012
Cuprins

1. Introducere ……………………………………………………………. 3
1.1 Medii de Programare Vizuală ………………………………….3
1.2 Microsoft Visual Studio ………………………………………..3
2. Tetris – Microsoft Visual Studio 2010 …………………………………4
2.1 Conceptul de bază ……………………………………………...5
2.2 Traducerea conceptului în program ……………………………6
2.3 TetrisCell …………………………………………………….....7
2.4 TetrisBoard ……………………………………………………..7
2.5 TetrisBlock ……………………………………………………..7
2.6 Crearea de Game Board ………………………………………..8
2.7 Creare Blocks …………………………………………………..8
2.8 Rotirea Blocurilor ………………………………………………9
2.9 Efectuarea Blocks Fall ………………………………………....12
2.10 Controlarea Blocks Fall din tastatură ………………………...13
2.11 Fixarea blocurilor şi eliminarea liniilor complete …………....13
2.12 Scorul ………………………………………………………...14
2.13 Întreruperea jocului …………………………………………..15
2.14 Sfârşitul jocului ………………………………………………15
3. Codul aplicaţiei Tetris …………………………………………………16

2
1. Introducere

1.1 Medii de Programare Vizuală

Programarea vizuală se bazează pe aplicaţii care permit folosirea expresiilor


“vizuale” ( imagini, desene, animaţii sau icoane ) în procesul de programare.
Aceste expresii virtuale pot fi folosite ca interfeţe grafice pentru limbaje de
programare textuală. Ele pot fi folosite pentru a forma sintaxa de limbaje de
programare vizuală noi care conduc la noi paradigme de programare, cum ar
fi de demonstraţie sau acestea pot fi folosite în prezentări grafice a
comportamentului sau structura unui program.

1.2 Microsoft Visual Studio

Microsoft Visual Studio este un IDE (integrated development environment )


puternic care asigură cod de calitate pe parcursul ciclului al aplicaţiei, de la
proiectare la implementare.
Visual Studio include un editor de cod de sprijin “IntelliSense”, precum şi
refacerea de cod. Depanatorul integrat funcţionează atât ca o sursă de
debugger cat şi ca un debugger la nivel de maşină. Alte unelte built-in includ
un designer de formulare pentru construirea de aplicaţii GUI, web designer,
designer de clase şi designer de baze de date.

3
2. Tetris – Microsoft Visual Studio 2010

Tetris este un puzzle electronic în care utilizatorul manipulează


“tetrominoes” pentru a forma linii complete. Conţine mai multe nivele, iar
acestea se modifică în funcţie de punctajul obţinut.

4
2.1 Conceptul de bază

Există 7 tipuri diferite de forme de bază în jocul nostru. Le voi numi I J L O


S T Z pentru simplitate pentru a se potrivi cel mai apropiat alfabetului
englez. Deoarece jocul are posibilitatea de a roti forme, acest lucru se face
de 28 de ori (de exemplu de 7 × 4), în total. A se vedea diagrama de mai jos:

Imaginea de mai sus arată cele 7 forme de bază, precum şi alte variante
fiecare dintre ele rotite in sensul acelor de ceasornic.

Observăm că toate formele sunt concepute din 4 celule. De asemenea,


observăm că, exceptând I şi O, toate celelalte se pot potrivi într-o grila de 3
× 3. Deci, putem lua celula 2 × 2 ca centru şi rotim forma în sensul acelor de
ceasornic sau anti-sensul acelor de ceasornic. Am marcat celula centru, cu o
mică gaură în imaginea de mai sus. Imaginaţi-vă că se poate roti în jurul
valorii de bloc marcate. I şi O sunt forme excepţii, în sensul că nu putem
determina o celulă centru fix pentru ele. Forma O rotita, va rămâne aceeasi,
aşa că nu trebuie să ne facem griji despre asta. Am desemnat 2 × 2 celule ca
centrul său. Pentru I-forma, vom lua celula 2 × 2, astfel centrul său, din

5
moment ce următoarele două rotaţii sunt nesemnificative. Acest lucru face ca
de 2 × 2 celule ca o alegere ideală pentru centrul de toate formele.

Vom observa formele S şi Z . Nu avem nevoie de toate acestea. Unele dintre


ele sunt duplicate. Dar totuşi le vom păstra, astfel încât să putem obţine chiar
blocuri care se încadrează.

2.2 Traducerea conceptului în program

Pentru a putea traduce conceptual in program, am creat 3 clase.

1. TetrisBoard: Clasa TetrisBoard reprezintă toate celulele


din joc. Este o grila de 2 dimensiuni de celule, la fel ca o foaie de calcul.
Putem numi o pânză sau loc de joaca pentru joc.
2. TetrisCell: Un TetrisCell reprezintă fiecare celulă din
TetrisBoard. Deci, orice efect în acest joc se face în cele din urmă din
TetrisCells.
3. TetrisBlock: Un TetrisBlock reprezinta un grup de celule
(TetrisCells), care formează un bloc semnificativ pentru noi. Fiecare dintre
formele din diagrama de mai sus este un bloc.

Diagrama de mai jos arata cateva exemple din fiecare clasa.

6
2.3 TetrisCell

Un TetrisCell moşteneşte de la o etichetă toate proprietatile. Din moment ce


o etichetă are tot ceea ce ne dorim pentru acest joc, o vom folosit cu câteva
proprietăţi suplimentare de care aveam nevoie.

Un TetrisCell ştie locaţia sa (rând, coloană), în Tabla de Joc. Ea stie ce


culoare este (HighlightColor) şi dacă se afiseaza sau se ascunde
(evidenţiată). Se stie, de asemenea, dacă acesta este gol sau ocupat
(IsEmpty). În cele din urmă, ea ştie cum să se retraga atunci când i se spune
să facă acest lucru (Refresh method).

2.4 TetrisBoard

Un TetrisBoard nu este nimic mai mult decât o colecţie (în fapt, matrice 2D)
din TetrisCells aranjate în rânduri şi coloane, cu câteva proprietăţi
suplimentare.

Un TetrisBoard ştie ce recipient (mamă) se află în, informaţii despre fiecare


TetrisCell pe care o detine, dimensiunea lor, culoarea si stilul de frontieră. El
ştie câte rânduri şi coloane are.

Aceasta dispune de metode pentru a determina dacă oricare dintre rânduri pe


care le are este complet ocupat sau nu (metoda IsRowComplete) şi
modalităţi de a elimina orice rând atunci când a spus să facă acest lucru
(metoda RemoveRow). Atunci când un rând este eliminat, în rândurile de
mai sus se încadrează în jos sub greutate.

2.5 TetrisBlock

Un TetrisBlock reprezinta un grup de TetrisCells, care formează un bloc


semnificativ. Aceasta este inima jocului nostru. Cea mai mare a parte a
jocului se află în această clasă.

Un TetrisBlock ştie celulele care formeaza blocul (Cells property). Ea stie ce


forma este (Shape property), şi care TetrisBoard se anexează la (ParentBoard
property).

Un TetrisBlock dispune de metode pentru a şti dacă este posibil să se mute în


altă locaţie de pe bord (metoda CanMove) şi, de asemenea, cum să se mute,
dacă este posibil (metoda Move). Ea are, de asemenea modalitate de a şti
dacă se poate roti (metoda CanRotate) şi rotiţi în sine, dacă se poate (metoda

7
Rotate). Ea stie cum sa se picteze atunci când este nevoie (Refresh and
RefreshBackGround methods).

2.6 Crearea de Game Board

Aceasta este partea cea mai uşoară. Am apelat la doar o matrice 2 de


dimensiuni TetrisCells şi apoi să le-am aranjat în rânduri şi coloane. (Ca o
foaie de calcul). Noi numim acest lucru prin numele GameBoard în
programul nostru.

Această parte a programului creează GameBoard.

GameBoard = New TetrisBoard(GameBox)


With GameBoard
.Rows = 20
.Columns = 10
.CellSize = New Size(20, 20)
.Style = BorderStyle.FixedSingle
.SetupBoard()
End With

2.7 Creare Blocks

La momentdat un bloc va fi activ în joc. (Acest lucru poate fi mai mult în


viitor, la nivel de jocuri mai mari, dar presupunem acum ca acesta să fie
unul). Acest lucru este reprezentat de numele FallingBlock în jocul nostru.

FallingBlock = New TetrisBlock(GameBoard)

Vom crea un bloc nou care se încadrează doar o singură dată. Pentru blocul 2
şi ulterior vrem să ”pice”, vom repoziţiona doar celula de centrul nostru de
bloc existente şi vom atribui o forma PreviewBlock. Şi PreviewBlock se
atribuie o formă nouă la întâmplare.

Private Sub DropNextFallingBlock()


FallingBlock.CenterCell = GameBoard.Cells(2,

8
GameBoard.Columns \ 2)
FallingBlock.Shape = PreviewBlock.Shape
PreviewBlock.Shape = GetRandomShape()
PreviewBlock.RefreshBackGround()
PreviewBlock.Refresh()
End Sub

2.8 Rotirea Blocurilor

Rotirea blocurilor cazatoare este interesant, dar şi complicat. Noi nu rotim de


fapt. În schimb, tot ceea ce facem este sa stabilim forma blocului următor, în
ordinea care este, de fapt, versiunea rotita a blocului anterior. Şi atunci când
este una din cele '4 cu sufixul '(de exemplu, I4, J4, L4, etc), am setat înapoi
la 1. (de exemplu, I1, J1, L1, etc), deoarece forma rotita de 4 ori va fi înapoi
în poziţia întâi.

Public Enum Shapes


I1 = 1
I2
I3
I4
J1
J2


T4
Z1
Z2
Z3
Z4
End Enum

Public Sub Rotate()


RefreshBackGround()
Shape = GetRotatedShape() ” This calls UpdateShape
automatically.
End Sub

9
Private Sub UpdateShape()
Cells = GetShapeCells(Shape, CenterCell)
Refresh()
End Sub

Private Function GetRotatedShape() As Shapes


Dim rotatedShape As Integer = If(Shape Mod 4 = 0, Shape
– 3, Shape + 1)
Return CType(rotatedShape, Shapes)
End Function

Private Function GetShapeCells(ByVal theShape As Shapes, ByV


al referenceCell As TetrisCell) AsTetrisCell()
Dim theCells() As TetrisCell
Select Case theShape
Case Shapes.I1, Shapes.I3
theCells = GetCells(referenceCell, -1, 0, 0, 0,
1, 0, 2, 0)
Case Shapes.I2, Shapes.I4
theCells = GetCells(referenceCell, 0, -1, 0, 0,
0, 1, 0, 2)
Case Shapes.J1
theCells = GetCells(referenceCell, -1, 0, 0, 0,
1, 0, 1, -1)
Case Shapes.J2
theCells = GetCells(referenceCell, 0, 1, 0, 0,
0, -1, -1, -1)
Case Shapes.J3
theCells = GetCells(referenceCell, 1, 0, 0, 0,
-1, 0, -1, 1)
Case Shapes.J4
theCells = GetCells(referenceCell, 0, -1, 0, 0,
0, 1, 1, 1)
Case Shapes.L1
theCells = GetCells(referenceCell, -1, 0, 0, 0,
1, 0, 1, 1)

10
Case Shapes.L2
theCells = GetCells(referenceCell, 0, 1, 0, 0,
0, -1, 1, -1)


End Select
Return theCells
End Function

Private Function GetCells(ByVal referenceCell As TetrisCell,


ByVal ParamArray relativeCoordinates()As Integer) As TetrisC
ell()
Dim theCells((relativeCoordinates.Count \ 2) –
1) As TetrisCell
Dim refRow As Integer = referenceCell.Row
Dim refCol As Integer = referenceCell.Column
For i As Integer = 0 To theCells.Count – 1
theCells(i) = ParentBoard.Cells(refRow +
relativeCoordinates(i * 2), refCol + relativeCoordinates(i *
2 + 1))
Next
Return theCells
End Function

Pentru a obţine acele coordonate ale celulelor în formă, vom lua doar celula
de referinţă (celulă centru), ca punct de 0,0 şi marca celelalte relative la
celulă.

Figura de mai jos prezintă un exemplu de a lua blocuri J-în formă de:

11
2.9 Efectuarea Blocks Fall

În capitolul anterior am discutat despre celula centrul blocului. Aici este


locul unde este utilizat. Aducem în jos centrul de celula, o linie jos (într-un
cronometru), si se lasa sa se aspire. Din clasa TetricBlock cunoaşte forma şi,
de asemenea, ştie cum să-l atragă.

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal


e As System.EventArgs) HandlesTimer1.Tick
If FallingBlock.CanMove(MoveDirection.Down) Then
FallingBlock.Move(MoveDirection.Down)
Else
” Do other stuff like …
” Fix block to base
” Remove completed rows
” Update Statistics
” Make the next block fall
” Check if game has ended
End If
End Sub

12
2.10 Controlarea Blocks Fall din tastatura

Tot ce trebuie să facem pentru acest lucru este să se ocupe de eveniment


formularul keydown. Dacă utilizatorul apasă stânga / dreapta / jos, ne muta
blocul în acest sens. Tasta Up este folosit pentru a roti blocul.

With FallingBlock
Select Case e.KeyCode
Case Keys.Left
If .CanMove(MoveDirection.Left) Then .Move(MoveD
irection.Left)
Case Keys.Right
If .CanMove(MoveDirection.Right) Then .Move(Move
Direction.Right)
Case Keys.Down
If .CanMove(MoveDirection.Down) Then .Move(MoveD
irection.Down)
Case Keys.Up
If .CanRotate Then .Rotate()
End Select
End With

2.11 Fixarea blocurilor si eliminarea liniilor complete

Atunci când un bloc a atins punctul în care nu poate merge în jos mai
departe, avem nevoie pentru a-l bloca acolo. Tot ce trebuie să facem pentru
aceste celule este de a stabili proprietatea IsEmpty la fals, astfel încât să nu
poate fi mutat. Pentru a elimina rânduri completate vom verifica dacă este
complet rând (pentru fiecare rând care intră sub bloc ocupat), şi, dacă este,
am eliminat.

” Fix block to base


For Each cell As TetrisCell In FallingBlock.Cells
cell.IsEmpty = False
Next

” Remove completed rows

13
Dim checkRows = From cell In FallingBlock.Cells _
Order By cell.Row _
Select cell.Row Distinct
Dim rowsRemoved As Integer = 0
For Each row In checkRows
If GameBoard.IsRowComplete(row) Then
GameBoard.RemoveRow(row)
rowsRemoved += 1
End If
Next

2.12 Scorul

Vom aplica un concept simplu aici. Am mai multe puncte de atribuit pentru
îndepărtarea mai multor rânduri într-un singur start.
Acesta este modul in care se poate obtine scorul:
Premiul 100 pentru o singura linie eliminate, 400 pentru doua linii
eliminate, 900 pentru trei linii şi 1600 pentru patru linii eliminate.
Pentru fiecare 10 linii eliminate, creşte viteza la 1.
Pentru fiecare 10 viteze, creşte nivelul la 1.

” Update Statistics
Score += Math.Pow(rowsRemoved, 2) * 100
Lines += rowsRemoved
Speed = 1 + Lines \ 10
If Speed Mod 10 = 0 Then Level += 1 : Speed = 1
Timer1.Interval = (10 – Speed) * 100
UpdateStatistics();

14
2.13 Intreruperea jocului

Pentru a întrerupe jocul ne oprim pur şi simplu “timerul” care este în scădere
de blocuri.

Private Sub TogglePauseGame()


If Status = GameStatus.Paused Then
Status = GameStatus.Running
MessageLabel.Visible = False
Timer1.Enabled = True
Else
Status = GameStatus.Paused
ShowMessage(String.Format("{0}{0}GAME PAUSED{0}{0}{0}{0}Click
here to resume.", vbCrLf))
End If
End Sub

Private Sub ShowMessage(ByVal message As String)


MessageLabel.Text = message
MessageLabel.Visible = True
Timer1.Enabled = False
End Sub

2.14 Sfarsitul jocului

Acest lucru este simplu. De îndată ce vom face blocul sa apara pe bord şi
vom descoperi că nu este posibil să-l mutaţi, ştim că jocul sa încheiat.

” Check if game has ended


If Not FallingBlock.CanMove(FallingBlock.CenterCell) Then EndGame();

15
3. Codul aplicatiei Tetris

Codul aplicatiei se afla in fisierele .txt .


TetrisBlock.txt
TetrisBoard.txt
TetrisCells.txt
TetrisGame.txt

16