1

I have recently been working on an exercise project to create my own Tetris in Excel using VBA. So far, the code works as follows:

  • Height and width of the area are set to 3 and 5 (to keep it simple for now).
  • The first block appears randomly in the top row.
  • It falls slowly down to the bottom of the area, randomly moving left or right.
  • When reaching the bottom or another block, it stops there, and a new block appears at the top.

However, Tetris doesn't make too much fun, if the directions are chosen randomly by the code, which is how I have implemented it thus far. Now, one of the random numbers 1, 2 or 3 is created and then used to choose one of three cases (marked in my code below).

Is there a way to replace the random number with a construct, that allows me to hit "LEFT ARROW" or "RIGHT ARROW" to move accordingly? I imagine you could build an If construct, which checks for inputs and acts accordingly.

Sub tetris()
Dim column As Byte, row As Byte, c As Byte, width As Byte, height As Byte
Range(Cells(1, 1), Cells(100, 100)).ClearFormats
beginning:
width = 3
height = 5
column = Rnd() * width + 0.5
If Cells(1, column).Interior.Color = vbRed Then
    GoTo gameover
Else
    Cells(1, column).Interior.Color = vbRed
End If
row = 1
Do While row < height
    Sleep 100
    Randomize
    c = Rnd() * 3 + 0.5''''''''''''''''''''''''''''''''''START OF THE CASE CONSTRUCT'''''''''''''''
    Select Case c
        Case 1 'LEFT
            If column > 1 Then
                If Cells(row, column - 1).Interior.Color <> vbRed Then
                    Cells(row, column).Interior.Color = xlNone
                    Cells(row, column - 1).Interior.Color = vbRed
                    column = left(column)
                ElseIf Cells(row + 1, column).Interior.Color <> vbRed Then
                    Cells(row, column).Interior.Color = xlNone
                    Cells(row + 1, column).Interior.Color = vbRed
                    row = row + 1
                Else
                    GoTo beginning
                End If
            ElseIf Cells(row + 1, column).Interior.Color <> vbRed Then
                Cells(row, column).Interior.Color = xlNone
                Cells(row + 1, column).Interior.Color = vbRed
                row = row + 1
            Else
                GoTo beginning
            End If
        Case 2 'RIGHT
            If Cells(row, column + 1).Interior.Color <> vbRed And column < width Then
            Cells(row, column).Interior.Color = xlNone
            Cells(row, column + 1).Interior.Color = vbRed
            column = right(column, width)
            ElseIf Cells(row + 1, column).Interior.Color <> vbRed Then
            Cells(row, column).Interior.Color = xlNone
            Cells(row + 1, column).Interior.Color = vbRed
            row = row + 1
            Else
            GoTo beginning
            End If
        Case 3
            If Cells(row + 1, column).Interior.Color = vbRed Then
            GoTo beginning
            Else
            Cells(row, column).Interior.Color = xlNone
            Cells(row + 1, column).Interior.Color = vbRed
            row = row + 1
            End If
    End Select
Loop
GoTo beginning
gameover:
MsgBox "Game Over"
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function left(column As Byte)
If column > 1 Then
    left = column - 1
Else
    left = column
End If
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function right(column As Byte, width As Byte)
If column < width Then
    right = column + 1
Else
    right = column
End If
End Function
scenography
  • 310
  • 2
  • 6
  • You can look into [keypress events](https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/keypress-event). But I'm not sure as the documentation is unclear whether this only works within a form control. – Plutian Dec 17 '19 at 13:08
  • Also, you may be able to adapt this discussion of the Windows API approach [Is there any event that fires when keys are pressed when editing a cell?](https://stackoverflow.com/questions/11153995/is-there-any-event-that-fires-when-keys-are-pressed-when-editing-a-cell) to your needs. – Ron Rosenfeld Dec 17 '19 at 13:16
  • Also look at this answer, [How to use GetAsyncKeyState](https://stackoverflow.com/questions/41955952/how-to-use-getasynckeystate-to-see-key-was-pressed-for-x-seconds), and this page, https://wellsr.com/vba/2017/excel/GetAsyncKeyState-vba-to-wait-until-a-key-is-pressed/. "You can use this feature . . . to control the logic of your macro using key presses." – scenography Dec 27 '19 at 18:49

0 Answers0