Fazendo um Jogo de Snake no Excel
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:
- 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.
- Ao clicar no botão iniciar, todas as “comidas” da cobra irão aparecer no cenário de forma aleatória.
- A cobra irá mover-se constantemente a partir do momento em que o botão iniciar for clicado.
- Ao clicar em uma das setas, iremos alterar o valor de uma variável global que indica a direção da cobra.
- 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 SubSub 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:=FalseOn 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.