148 lines
3.1 KiB
Go
148 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/gdamore/tcell/v2"
|
|
)
|
|
|
|
func initilize() (tcell.Screen, tcell.Style, error) {
|
|
style := tcell.StyleDefault.Background(tcell.ColorReset).Foreground(tcell.ColorReset)
|
|
|
|
var err error
|
|
|
|
screen, err := tcell.NewScreen()
|
|
if err != nil {
|
|
log.Println("Error creating screen: ", err)
|
|
}
|
|
err = screen.Init()
|
|
if err != nil {
|
|
log.Fatalln("Error initializing screen: ", err)
|
|
}
|
|
return screen, style, err
|
|
}
|
|
|
|
func quit(screen tcell.Screen) {
|
|
maybePanic := recover()
|
|
screen.Fini()
|
|
if maybePanic != nil {
|
|
panic(maybePanic)
|
|
}
|
|
}
|
|
|
|
func gameDirector(screen tcell.Screen, style tcell.Style, keypresses chan int, gamestate chan int, score *Score) {
|
|
|
|
// Destined to die, even before I was born.
|
|
defer quit(screen)
|
|
|
|
// Board size
|
|
var screenx = 80
|
|
var screeny = 24
|
|
|
|
// Last direction we went in
|
|
var lastpress int = 1
|
|
|
|
var snake Snake = initSnake((screenx/2)-1, (screeny/2)-1)
|
|
var apple Apple = placeApple(&snake)
|
|
|
|
for {
|
|
|
|
// Take input or sleep
|
|
select {
|
|
case press := <-keypresses:
|
|
if validateDirection(&snake, press) {
|
|
snakeDirection(press, &snake)
|
|
lastpress = press
|
|
}
|
|
case <-time.After(500 * time.Millisecond):
|
|
snakeDirection(lastpress, &snake)
|
|
}
|
|
|
|
if snake.head.x == apple.x && snake.head.y == apple.y {
|
|
apple = placeApple(&snake)
|
|
score.score += score.scoreCounter
|
|
score.scoreCounter++
|
|
snake.length = 3 + score.score
|
|
}
|
|
|
|
// Call it quits once the snake hits the border.
|
|
if snake.head.x == 0 || snake.head.x == screenx-1 {
|
|
score.reason = 2
|
|
close(gamestate)
|
|
return
|
|
} else if snake.head.y == 0 || snake.head.y == screeny-1 {
|
|
score.reason = 2
|
|
close(gamestate)
|
|
return
|
|
}
|
|
|
|
// Check if head intersects with any parts of the body
|
|
if hitsTail(&snake, snake.head.x, snake.head.y) {
|
|
score.reason = 3
|
|
close(gamestate)
|
|
return
|
|
}
|
|
|
|
// Clean the screen
|
|
screen.Clear()
|
|
|
|
// Draw the screen
|
|
drawBox(screen, style, 0, 0, screenx-1, screeny-1)
|
|
//drawCoords(screen, style, &snake)
|
|
drawApple(screen, style, &apple)
|
|
drawSnake(screen, style, &snake)
|
|
drawScore(screen, style, score)
|
|
|
|
// Draw the screen
|
|
screen.Show()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
func keyboardProcessor(screen tcell.Screen, keypresses chan int, gamestate chan int, score *Score) {
|
|
defer close(keypresses)
|
|
|
|
for {
|
|
|
|
// Poll for an event
|
|
ev := screen.PollEvent()
|
|
|
|
// Fetch the type, and check if any other actions are required.
|
|
switch ev := ev.(type) {
|
|
case *tcell.EventKey:
|
|
if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC {
|
|
score.reason = 1
|
|
return
|
|
} else if ev.Rune() == 'q' || ev.Rune() == 'Q' {
|
|
score.reason = 1
|
|
return
|
|
} else if ev.Key() == tcell.KeyCtrlL {
|
|
screen.Sync()
|
|
} else if ev.Rune() == 'C' || ev.Rune() == 'c' {
|
|
screen.Clear()
|
|
} else if ev.Key() == tcell.KeyLeft {
|
|
keypresses <- Left
|
|
} else if ev.Key() == tcell.KeyRight {
|
|
keypresses <- Right
|
|
} else if ev.Key() == tcell.KeyDown {
|
|
keypresses <- Down
|
|
} else if ev.Key() == tcell.KeyUp {
|
|
keypresses <- Up
|
|
}
|
|
}
|
|
|
|
// This function needs to know if the game is over.
|
|
select {
|
|
case <-time.After(10 * time.Millisecond):
|
|
case _, ok := <-gamestate:
|
|
if !ok {
|
|
return
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|