A kind of Augmented Reality programming game that makes you a better programmer.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ttarpit/ui.go

140 lines
2.9 KiB

package main
import (
. "lcthw.dev/go/ttarpit/debug"
"time"
"fmt"
"github.com/gdamore/tcell/v2"
"github.com/gdamore/tcell/v2/encoding"
"lcthw.dev/go/ttarpit/game"
"lcthw.dev/go/ttarpit/builder"
)
type UI struct {
Screen tcell.Screen
DefaultStyle tcell.Style
DeadStyle tcell.Style
}
func (ui *UI) DrawText(x int, y int, text string) {
for i, cell := range text {
ui.Screen.SetContent(x+i, y, cell, nil, tcell.StyleDefault)
}
}
func (ui *UI) StyleText(x int, y int, text string, style tcell.Style) {
for i, cell := range text {
ui.Screen.SetContent(x+i, y, cell, nil, style)
}
}
func (ui *UI) Render(data *game.Game, build *builder.Builder) {
if data.HP <= 0 {
ui.Screen.SetStyle(ui.DeadStyle)
ui.Screen.Sync()
ui.Screen.Clear()
ui.DrawText(0, 10, fmt.Sprintf("YOU DIED!"))
} else {
ui.Screen.SetStyle(ui.DefaultStyle)
ui.Screen.Clear()
}
time_since := time.Until(data.EndTime)
ui.DrawText(0, 0, "Welcome to Turing's Tarpit")
ui.DrawText(0, 2, fmt.Sprintf("HP: %d", data.HP))
ui.DrawText(0, 3, fmt.Sprintf("Errors: %d", data.Errors))
ui.DrawText(0, 4, fmt.Sprintf("Deadline: %s", time_since.Round(time.Second)))
green := tcell.StyleDefault.Background(tcell.ColorGreen).Foreground(tcell.ColorBlack)
red := tcell.StyleDefault.Background(tcell.ColorRed).Foreground(tcell.ColorBlack)
yellow := tcell.StyleDefault.Background(tcell.ColorYellow).Foreground(tcell.ColorBlack)
switch build.BuildState {
case builder.START:
ui.StyleText(0, 5, "Build: READY", green)
case builder.RUNNING:
ui.StyleText(0, 5, "Build: RUNNING", yellow)
case builder.PASSED:
ui.StyleText(0, 5, "Build: PASSED", green)
case builder.FAILED:
ui.StyleText(0, 5, "Build: FAILED", red)
}
// show the errors
ui.Screen.Show()
}
func (ui *UI) HandleKeys(ev *tcell.EventKey) bool {
switch ev.Key() {
case tcell.KeyEscape:
return false
}
switch ev.Rune() {
case 'q':
return false
}
return true
}
func (ui *UI) HandleEvents() bool {
switch ev := ui.Screen.PollEvent().(type) {
case *tcell.EventResize:
ui.Screen.Sync()
case *tcell.EventKey:
return ui.HandleKeys(ev)
}
return true
}
func (ui *UI) Exit() {
ui.Screen.Fini()
}
func (ui *UI) RenderLoop(g *game.Game, build *builder.Builder) {
go func () {
for {
ui.Render(g, build)
time.Sleep(100 * time.Millisecond)
}
}()
for ui.HandleEvents() {
ui.Render(g, build)
}
}
func MakeUI() *UI {
var err error
encoding.Register()
ui := new(UI)
ui.Screen, err = tcell.NewScreen()
if err != nil { Log.Fatal(err) }
err = ui.Screen.Init()
if err != nil { Log.Fatal(err) }
ui.DefaultStyle = tcell.StyleDefault.
Background(tcell.ColorBlack).
Foreground(tcell.ColorWhite)
ui.DeadStyle = tcell.StyleDefault.
Background(tcell.ColorDarkRed).
Foreground(tcell.ColorWhite)
ui.Screen.SetStyle(ui.DefaultStyle)
ui.Screen.Clear()
return ui
}