Monday, December 27, 2021

Excel Snake Game

Such a great game! In this post we learn to create the Snake game in Excel using VBA macros. There are many Excel versions of the Snake game on the internet. This one is probably one of the easiest way to do it, and hopefully a good example to help you learn VBA arrays while having fun with the movement of the snake in Excel.

Setting a Timer to Create the Movement

In order to achieve the continuous and smooth movement of the snake, we need to call a “moving” procedure (MoveSnake) every certain time interval, and that time interval should be in the range of milliseconds. We can do that using the SetTimer function of the Windows API library (user32.dll). We have already seen how to use that in previous posts (Excel Tron Game, Excel Circles Movement, Excel Falling Letters, and Excel Geometry Dash).



Here’s the timer declaration and related procedures used in Excel Snake Game (it is all in the module “Timer”). Note that the declaration is slightly different for Excel 32bit and 64bit.

 
  Option Explicit
  #If Win64 Then
    Public Declare PtrSafe Function SetTimer Lib "User32" ( _
        ByVal hwnd As LongLong, _
        ByVal nIDEvent As LongLong, _
        ByVal uElapse As LongLong, _
        ByVal lpTimerFunc As LongLong) As LongLong
    Public Declare PtrSafe Function KillTimer Lib "User32" ( _
        ByVal hwnd As LongLong, _
        ByVal nIDEvent As LongLong) As LongLong
    Public TimerID As LongLong
  #Else
    Public Declare PtrSafe Function SetTimer Lib "User32" ( _
        ByVal hwnd As Long, _
        ByVal nIDEvent As Long, _
        ByVal uElapse As Long, _
        ByVal lpTimerFunc As Long) As Long
    Public Declare PtrSafe Function KillTimer Lib "User32" ( _
        ByVal hwnd As Long, _
        ByVal nIDEvent As Long) As Long
    Public TimerID As Long
  #End If
 
  Sub StartTimer()
    If TimerID <> 0 Then
        KillTimer 0, TimerID
        TimerID = 0
    End If
    TimerID = SetTimer(0, 0, speed, AddressOf TimerEvent)
  End Sub
 
  Sub TimerEvent()
    On Error Resume Next
    Main.MoveSnake
    Exit Sub
  End Sub
 
  Sub StopTimer()
    KillTimer 0, TimerID
    TimerID = 0
  End Sub
 


SetTimer creates a timer that triggers an event after a certain number of milliseconds have elapsed (taken from the variable “speed”). It has been configured to call the TimerEvent procedure, which at the same time calls the MoveSnake procedure in the Main module of the Excel Snake Game VBA project. The timer continues triggering events between intervals until it is removed using KillTimer. That happens in the StopTimer subroutine, which is called when the snake hits the edge or its own body, or when pressing the Stop button.

 

Controlling the Movement with the Keyboard

We control the movement of the snake with the keyboard arrows. Excel Snake Game uses the VBA OnKey method of the Application object to capture the keystroke and call the respective procedures to move the snake in one particular direction (see the code in module “Keys”). We have used the same code for previous Excel games where movement is controlled with the keyboard (Excel Tron Game, Excel FallingLetters, Excel Geometry Dash).

 
  Application.OnKey "{LEFT}", "moveLeft"
  Application.OnKey "{UP}", "moveUp"
  Application.OnKey "{DOWN}", "moveDown"
  Application.OnKey "{RIGHT}", "moveRight"
 


The public variables rinc and cinc (which stands for row and column increment respectively) are used to determine the direction of the movement of the snake. They can have the value of +1, -1, or 0, but one must be 0 when the other has another value, thus allowing the movement in one of the four possible directions.

Then, in the MoveSnake procedure of the Excel Snake Game VBA project, the current row and column of the head increments with the value of rinc and cinc (see next).

 

Moving and Growing the Snake

In this Excel version of the game, the snake is shown by changing the interior color of each cell to green (and red for the head). The movement of the snake is achieved by changing the position of the head as per the row or column increment determined by the key pressed (explained earlier). The rest of the snake will advance the position taking the previous position in the array. This means, the cell after the head will take the head’s position, the following cell will take the cell after the head’s position, and so on. Note that we use a reverse loop starting from the tail to assign values to the array. The interior color of the last cell is changed to black.


 
  tail = UBound(r)
  For i = tail To 1 Step -1
      r(i) = r(i - 1)
      c(i) = c(i - 1)
  Next i
      
  Cells(r(tail), c(tail)).Interior.Color = vbBlack
  Cells(r(0), c(0)).Interior.Color = vbYellow
 

 

So, there are two arrays that determine the position of the snake, one for the row and other for the column. Each element in the array corresponds to a part of the snake (or a cell occupied with the snake), including the head. The head is always the 0 index of the array, i.e. r(0) for row, and c(0) for column.

When the snake eats the apple, the array is extended by one with ReDim. Thus, the snake enlarges its body by one element or cell. Here’s how we do that using the UBound function of the array.

  ReDim Preserve r(UBound(r) + 1)
  ReDim Preserve c(UBound(c) + 1)

 

Then, the score is updated and a new apple is placed in a random location of the board. The game ends when the snake hits the edge or its own body.


Download Excel Snake Game


No comments:

Post a Comment

Popular Posts