Um jogo Snake completo desenvolvido em Go como projeto de estudo para aprender os fundamentos e conceitos avançados da linguagem.
Este projeto foi desenvolvido como uma jornada de aprendizado em Go, implementando um jogo Snake funcional com múltiplas features avançadas. O objetivo foi aplicar conceitos fundamentais e intermediários da linguagem através de um projeto prático e divertido.
- 🎮 Menu Inicial - Interface de boas-vindas com instruções
- 🔄 Reiniciar Jogo - Pressione R para jogar novamente
- 📊 Sistema de Níveis - Velocidade aumenta a cada 50 pontos
- 🏆 High Score - Recorde salvo em arquivo persistente
- ⭐ Power-ups - Comida especial que vale 50 pontos (20% de chance)
- 🧱 Obstáculos - Paredes aleatórias que aumentam com o nível
- 🔊 Sistema de Sons - Feedback sonoro para cada ação
- 🎨 Interface ASCII - Visual clean com caracteres Unicode
type Point struct {
X int
Y int
}
var score int = 0
direction := "right"Aplicação: Estruturas de dados básicas para posições e estado do jogo.
type Game struct {
Snake Snake
Food Food
Score int
HighScore int
Level int
Obstacles []Point
}Aplicação: Organização do estado completo do jogo em estruturas lógicas.
g.Snake.Body = append([]Point{newHead}, g.Snake.Body...)
g.Obstacles = []Point{}Aplicação: Lista dinâmica para o corpo da cobra e obstáculos.
func (g *Game) MoveSnake() { }
func (g *Game) CheckCollision(p Point) bool { }Aplicação: Métodos com receivers para organizar lógica relacionada ao Game.
func (g *Game) Reset() {
g.Score = 0
g.Level = 1
}Aplicação: Modificar estado do jogo sem criar cópias desnecessárias.
type beep.Streamer interface {
Stream(samples [][2]float64) (n int, ok bool)
Err() error
}Aplicação: Implementação de interface para geração de sons customizados.
const (
StateMenu GameState = iota
StatePlaying
StateGameOver
)Aplicação: State machine para controlar fluxo do jogo.
go game.HandleInput(end)
go playTone(800, 50*time.Millisecond)Aplicação:
- Leitura de input em paralelo ao game loop
- Sons não-bloqueantes
end := make(chan bool)
end <- trueAplicação: Comunicação entre goroutines para sinalizar término do jogo.
ticker := time.NewTicker(game.Speed)
if game.Speed != lastSpeed {
ticker.Stop()
ticker = time.NewTicker(game.Speed)
}Aplicação: Game loop com velocidade dinâmica baseada no nível.
func LoadHighScore() int {
data, err := os.ReadFile("highscore.txt")
score, err := strconv.Atoi(strings.TrimSpace(string(data)))
return score
}Aplicação: Persistência do high score entre sessões.
import (
"github.com/nsf/termbox-go"
"github.com/faiface/beep"
)Aplicação:
termbox-go: Renderização no terminalbeep: Sistema de áudio
- ↑ ↓ ← → : Movimentar a cobra
- ENTER : Iniciar jogo
- R : Reiniciar após game over
- ESC : Sair do jogo
- ◆ Comida normal: 10 pontos
- ★ Power-up: 50 pontos
- ▓ Obstáculos: Evite!
- A cada 50 pontos você sobe de nível
- Cada nível aumenta velocidade e obstáculos
- Go 1.25.3
- Git
git clone https://github.com/seu-usuario/snake-game-go.git
cd snake-game-gogo get -u github.com/nsf/termbox-go
go get -u github.com/faiface/beep
go get -u github.com/faiface/beep/speakerOu simplesmente:
go mod tidygo run snake.goPara gerar um executável:
Windows:
go build -o snake.exe snake.go
snake.exeLinux/macOS:
go build -o snake snake.go
./snakesnake-game-go/
├── snake.go # Código principal
├── go.mod # Dependências
├── go.sum # Checksums das dependências
├── highscore.txt # High score persistente (gerado automaticamente)
└── README.md # Este arquivo
O jogo utiliza uma máquina de estados para controlar o fluxo:
┌─────────┐ ENTER ┌──────────┐ Game Over ┌──────────┐
│ Menu │ ───────> │ Playing │ ──────────> │GameOver │
└─────────┘ └──────────┘ └──────────┘
^ │
└──────────────────────────────────────────────┘
R (Restart)
for {
select {
case <-end:
return
case <-ticker.C:
switch game.State {
case StateMenu:
game.DrawMenu()
case StatePlaying:
game.MoveSnake()
game.Draw()
case StateGameOver:
game.DrawGameOver()
}
}
}func (g *Game) MoveSnake() {
if g.CheckWallCollision(newHead) ||
g.CheckSelfCollision(newHead) ||
g.CheckObstacleCollision(newHead) {
g.GameOver = true
}
}Utilizamos termbox-go para desenhar no terminal:
termbox.SetCell(x, y, '█', termbox.ColorGreen, termbox.ColorDefault)
termbox.Flush()Caracteres usados:
●- Cabeça da cobra (amarela)█- Corpo da cobra (verde)◆- Comida normal (vermelha)★- Power-up (amarelo/magenta piscando)▓- Obstáculos (branco)╔═╗║╚╝- Bordas
Geração de tons senoidais customizados:
type ToneGenerator struct {
freq float64
pos float64
sr beep.SampleRate
}
func (t *ToneGenerator) Stream(samples [][2]float64) (n int, ok bool) {
for i := range samples {
v := math.Sin(t.pos * 2 * math.Pi * t.freq / float64(t.sr))
samples[i][0] = v
samples[i][1] = v
t.pos++
}
return len(samples), true
}Sons implementados:
- Comer comida: 800Hz, 50ms
- Power-up: 600→800→1000Hz (crescente)
- Level up: 1000→1200Hz (duplo)
- Game Over: 400→300→200Hz (descendente)
| Nível | Velocidade | Obstáculos |
|---|---|---|
| 1 | 150ms | 2 |
| 2 | 140ms | 4 |
| 3 | 130ms | 6 |
| 5 | 110ms | 10 |
| 10+ | 50ms | 20 (max) |
- Linguagem: Go 1.25.3
- Terminal UI: termbox-go
- Áudio: beep
- Ferramentas: Go Modules
Este projeto cobriu:
✅ Sintaxe Go: Variáveis, tipos, structs, funções
✅ Controle de Fluxo: If/else, loops, switch
✅ Estruturas de Dados: Slices, arrays, maps
✅ Ponteiros: Passagem por referência
✅ Concorrência: Goroutines e channels
✅ Packages: Importação e uso de bibliotecas
✅ I/O: Leitura/escrita de arquivos
✅ Game Development: Game loop, collision detection, state machines
✅ Audio Programming: Geração de ondas sonoras
✅ Terminal UI: Renderização de gráficos ASCII
- Multiplayer local (2 jogadores)
- Modo sem bordas (cobra atravessa paredes)
- Top 10 rankings
- Diferentes temas visuais
- Configurações de dificuldade
- Achievements/conquistas
- Pausa durante o jogo
Este projeto está sob a licença MIT. Veja o arquivo LICENSE para mais detalhes.
Desenvolvido como projeto de estudo em Go.
Contato:
- GitHub: @mfugissecruz
- Email: mfugissecruz@gmail.com
- Comunidade Go pela excelente documentação
- termbox-go por facilitar UI no terminal
- beep pelo sistema de áudio simples
⭐ Se este projeto foi útil para você, considere dar uma estrela!