Here's expanded and formatted version with comments Enjoy!
SeedRnd Millisecs()
Global World[ 21, 23 ] ' Game field, stretched right for the shorter way to make glass bottom
Global Figure[ 7, 4, 4, 4 ] ' Stored tetris figures ( 7 pieces, 4x4 matrix, up to 4 phases)
Global Phases[ 7 ] ' Quantity of phases for figure ( 1, 2 or 4 )
For S$ = Eachin "ABEF,AEFJEFBC,IEFBABFG,BFJNEFGH,AEFGCBFJEFGKIJFB,EFGCBFJKIEFGABFJ,EFBGBFGJEFGJBEFJ".Split(",")
' There's all phases of figures stored in the sting, using 4 letters per phase, comma separates figure string chunks
' Every letter means a quadratic piece of figure in certain position, corresponding to following matrix:
' ABCD
' EFGH
' IJKL
' MNOP
Phases[ M ] = Len( S ) / 4 - 1 ' ( Quantity of phases - 1 ) can be calculated by dividing string chunk by 4 and subtracting 1
For I = 0 To Phases[ M ] ' These cycles fills the Figure matrices
For J = 0 To 3
A = S[ I * 4 + J ] - 65 ' This number converts symbol to number in range from 0 to 15
Figure[ M, I, A & 3, A Shr 2 ] = 1 ' 1 means filled square, 0 (by default) means empty
Next
Next
M :+ 1 ' Incrementing figures counter
Next
Graphics 800, 600
Y = 19 ' current y-coordinate of figure, set to 19 to make initialization of new one
Repeat
Cls
For I = 0 To 20
' Making glass boundaries
World[ 1, I ] = 1 ' left wall (it is shifted from the edge to prevent error
' when figure matrix is situated partly outside of the game field)
World[ 12, I ] = 1 ' right wall
World[ I, 20 ] = 1 ' bottom
' Drawing game field
For J = 1 To 12
If World[ J, I ] Then DrawRect J * 8, I * 8, 8, 8
Next
Next
' Drawing current figure
For I = 0 To 3
For J = 0 To 3
If Figure[ N, R, I, J ] Then DrawRect ( X + I ) * 8, ( Y + J ) * 8, 8, 8
Next
Next
Flip
' This is cool controller handing method, that I borrowed from old Speccy magazines
' If KEY_RIGHT is pressed then new value of X will be less than old by 1
' If KEY_LEFT is pressed then new value of X will be more than old by 1
A = X + KeyHit( KEY_RIGHT ) - KeyHit( KEY_LEFT )
B = Y + KeyDown( KEY_DOWN )
' Phase is "cycling" with (phases quantity - 1) = %0, %1 or %11 - by using logical operator AND
Q = ( R + KeyHit( KEY_W ) - KeyHit( KEY_Q ) ) & Phases[ N ]
' If new-positioned figure is not colliding with game field then it will be moved
IF CheckPosition( A, B, N, Q ) = 0 Then
X = A
Y = B
R = Q
End If
M = Millisecs()
If M > T Then
T = M + 999 ' figure will be moved down every second
' Checking if figure collides with game field when moved down (if true then "finalize" it)
If CheckPosition( X, Y + 1, N, R ) Then
If Y = 0 Then End ' end of game because glass is filled to the top
For I = 0 To 3 ' Transferring figure from its matrix to the game field (by filling corresponding squares)
For J = 0 To 3
If Figure[ N, R, I, J ] Then World[ X + I, Y + J ] = 1
Next
Next
' This mechanism will check filled rows and also moving down upper stuff if there's any
D = 0 ' Current steps to shift game field contents by
For I = 19 To 0 Step -1
Q = 0
For J = 2 To 11
If World[ J, I ] Then Q :+ 1
World[ J, I + D ] = World[ J, I ]
Next
IF Q > 9 Then D :+ 1 ' If there's 10 squares in a row then shift steps will be incremented by 1
Next
' Initializing new random figure on the top of the glass
X = 5
Y = - 1
N = Rand( 0, 6 )
EndIf
Y :+ 1 ' Moving figure down
End If
Until KeyHit( KEY_ESCAPE )
' This function checks collisions of game field and figure N with phase R in ( X, Y ) coords
Function CheckPosition( X, Y, N, R )
For I = 0 To 3
For J = 0 To 3
' Returns 1 if any filled figure square is placed on filled square of game field
If Figure[ N, R, I, J ] * World[ I + X, J + Y ] Then Return 1
Next
Next
' Returns 0 if there's no collision
EndFunction
|