Fazendo um Jogo de Snake no Excel

Rafael Bini
5 min readJun 18, 2020

--

Neste tutorial iremos aprender como fazer o famoso “Jogo da Cobrinha” ou Snake.

Usaremos apenas o Excel e a linguagem VBA (Visual Basic for Applications) para fazer isso.

Se você ainda não sabe o que é VBA, veja esse artigo aqui antes de prosseguir.

Você pode baixar arquivo excel desse jogo aqui.

Montando o cenário

Para iniciar, iremos criar um cenário extremamente simples:

Como você pode ver, temos apenas um grande retângulo (constituido de celulas pintadas de preto) e seis formas geométricas do Excel que usaremos como botões.

A ideia aqui é que a margem preta sirva como delimitações para a cobrinha. O botão iniciar irá começar o jogo assim como o botão parar irá encerrar o jogo. Os botões em formato de setas servirão para direcionar a cobra.

Definindo o funcionamento do jogo

Para fazer o jogo funcionar, iremos usar da seguinte estratégia:

  1. A cobra será definida por três vetores que indicam a posição e a cor de cada parte do corpo. O desenho da cobra será feito dinamicamente pintando as células da planilha.
  2. Ao clicar no botão iniciar, todas as “comidas” da cobra irão aparecer no cenário de forma aleatória.
  3. A cobra irá mover-se constantemente a partir do momento em que o botão iniciar for clicado.
  4. Ao clicar em uma das setas, iremos alterar o valor de uma variável global que indica a direção da cobra.
  5. Ao atingir uma comida, iremos pegar atrelar o a cor da comida ao corpo da cobra.

Escrevendo o código

Neste código teremos 5 principais variáveis globais:

Dim cor(1 To 100) As Long    // Cada elemento desse vetor indica a cor de uma parte do corpo da cobraDim lin(1 To 100) As Integer // Cada elemento desse vetor indica a linha em que uma parte do corpo da cobra está posicionadaDim col(1 To 100) As Integer // Cada elemento desse vetor indica a coluna em que uma parte do corpo da cobra está posicionadaDim movimento As String      ///' Guarda o timer que será usado para manter a cobra em movimento

A macro Iniciar (ligada ao botão iniciar) apenas serve para chamar três outras macros:

Sub iniciar() 
limpar
prepararCampo
atualizarTudo
End Sub

A macro limpar simplesmente passa por cada célula do cenário alterando a cor para branco e em seguida reseta todas as cores e posições do corpo da cobra:

Sub limpar()
For i = 2 To 21
For j = 2 To 37
Cells(i, j).Interior.Color = 16777215
Next j
Next i
cor(1) = 255
lin(1) = 11
col(1) = 19
movimento = "esq"
For i = 2 To 100
cor(i) = 16777215
lin(i) = 39
col(i) = 39
Next i
End Sub

Para preparar o campo, usamos a seguinte macro:

Sub prepararCampo()     
For i = 2 To 21
For j = 2 To 37
If Rnd > 0.979 Then
Cells(i, j).Interior.Color = Rnd * 16777215
End If
Next j
Next i
End Sub

Essa macro passa por cada célula do cenário e sorteia se deve ou não inserir uma cor aleatória na célula através de um número aleatório com a expressão Rnd. Em seguida, a macro AtualizarTudo é chamada pelo comando iniciar:

Sub atualizarTudo()
atualizarPoosicao
verificarAlternativo
pintar
rodar
End Sub

Essa macro chama quatro outras macros que servem para dar movimento ao jogo. A macro atualizarPoosicao é escrita da seguinte forma:

Sub atualizarPoosicao()Dim AuxLin(1 To 100) As Integer
Dim AuxCol(1 To 100) As Integer

' MOSTRA A FILA

'Range("AS2") = "Lin"
'Range("AT2") = "Col"
'Range("AU2") = "Cor"
'For i = 1 To 100
' Cells(i + 2, 45) = lin(i)
' Cells(i + 2, 46) = col(i)
' Cells(i + 2, 47) = cor(i)
'Next i

If movimento = "esq" Then
l = 0
c = -1
ElseIf movimento = "dir" Then
l = 0
c = 1
ElseIf movimento = "cim" Then
l = -1
c = 0
ElseIf movimento = "bai" Then
l = 1
c = 0
End If
' Copia
For i = 100 To 1 Step -1
If i = 1 Then
lin(1) = lin(1) + l
col(1) = col(1) + c
Else
lin(i) = lin(i - 1)
col(i) = col(i - 1)
End If
Next i

End Sub

Essa macro basicamente copia cada parte do corpo da cobra e cola para a direção indicada pela variável global chamada movimento. Essa variável global para movimento é definida pelos botões com setas que estão ligados às macros abaixo:

Sub cim()
movimento = "cim"
End Sub
Sub bai()
movimento = "bai"
End Sub
Sub esq()
movimento = "esq"
End Sub
Sub dir()
movimento = "dir"
End Sub

Se não houver nenhuma cor diferente de branco na célula para qual a cobra está se movendo, não ocorrerá nada diferente, mas se houver, a macro verificarAlternativo vai entrar em cena:

Sub verificarAlternativo()If Cells(lin(1), col(1)).Interior.Color = 0 Then
parar
MsgBox "Game Over"
ElseIf Cells(lin(1), col(1)).Interior.Color = 16777215 Then

ElseIf Cells(lin(1), col(1)).Interior.Color <> cor(1) Then
AdicionaCor (Cells(lin(1), col(1)).Interior.Color)
ElseIf Cells(lin(1), col(1)).Interior.Color = cor(1) Then
TirarCor
End If

End Sub

Essa macro vai agir de acordo com a cor que for encontrada, se for a cor preta, teremos game over, mas se for colorida, iremos adicionar uma nova cor ao corpo.

Encontrando uma a mesma cor da cabeça da cobra, tiraremos uma parte do corpo da cobra:

Sub AdicionaCor(novacor As Long)
For i = 1 To 100
If cor(i) = 16777215 Then
cor(i) = novacor
Exit Sub
End If
Next i
End Sub
Sub TirarCor()
For i = 1 To 99
cor(i) = cor(i + 1)
Next i
End Sub

Tendo concluído essas fases, podemos finalmente pintar a cobra no cenário atraves do comando pintar:

Sub pintar()For t = 1 To 100
If cor(t) = 16777215 Then
t = t + 1
Exit For
End If
Next t
For i = 1 To t
Cells(lin(i), col(i)).Interior.Color = cor(i)
Next i

End Sub

Essa macro simplesmente passa por cada posição registrada no vetor e pinta no cenário com a cor correspondente. E para que tudo isso que citamos acima aconteça novamente, chamamos por fim a macro rodar:

Sub rodar()
mTimerTime = Now + TimeValue("00:00:1")
Application.OnTime mTimerTime, "atualizarTudo"
End Sub

Essa macro faz uso do comando Application.OnTime mTimerTime, "atualizarTudo" que basicamente agenda a execução da macro atualizarTudo para o tempo definido pela variável mTimerTime (no nosso exemplo em um segundo depois de agora). Com isso, fechamos um loop que ficará executando a macro atualizarTudo de um em um segundo. Para encerrar o jogo, usamos a macro Parar (ligada ao botão parar) que é escrita da seguinte forma:

Sub parar()
On Error Resume Next
// Paramos o timer
Application.OnTime mTimerTime, "atualizarTudo", Schedule:=False
On Error GoTo 0limpar
End Sub

Note que estamos usando a expressão On Error Resume Next para que caso ocorra algum erro, simplesmente ignore e continue. Assim como a expressão On Error GoTo 0 serve para deixar de ignorar os erros.

--

--