| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- package main
- import (
- "log"
- "strings"
- "time"
- _ "embed"
-
- "github.com/gdamore/tcell/v3"
- "github.com/gdamore/tcell/v3/color"
- )
- //go:embed assets/title/title_idle.txt
- var title_idle string
- //go:embed assets/title/title_blinking.txt
- var title_blinking string
- func drawText(s tcell.Screen, x1, y1, x2, y2 int, style tcell.Style, text string) {
- row := y1
- col := x1
- var width int
- for text != "" {
- text, width = s.Put(col, row, text, style)
- col += width
- if col >= x2 {
- row++
- col = x1
- }
- if row > y2 {
- break
- }
- if width == 0 {
- // incomplete grapheme at end of string
- break
- }
- }
- }
- func drawTitle(s tcell.Screen, x, padding_top, frame int, style tcell.Style, titles [][]string) int{
- lines := titles[frame]
- frame = (frame + 1) % 2
- // Draw Title
- xmax, ymax := s.Size()
- for l:= range lines{
- drawText(s,x, l+padding_top, xmax, ymax, style, lines[l])
- }
- return len(lines)
- }
- func main() {
- cats := [][]string{
- strings.Split(string(title_idle), "\n"),
- strings.Split(string(title_blinking), "\n")}
-
- defStyle := tcell.StyleDefault.Background(color.Black).Foreground(color.NewHexColor(0xf3e5ab))
- // Initialize screen
- s, err := tcell.NewScreen()
- if err != nil {
- log.Fatalf("%+v", err)
- }
- if err := s.Init(); err != nil {
- log.Fatalf("%+v", err)
- }
- s.SetStyle(defStyle)
- s.Clear()
-
- quit := func() {
- // You have to catch panics in a defer, clean up, and
- // re-raise them - otherwise your application can
- // die without leaving any diagnostic trace.
- maybePanic := recover()
- s.Fini()
- if maybePanic != nil {
- panic(maybePanic)
- }
- }
- defer quit()
- // Here's how to get the screen size when you need it.
- // xmax, ymax := s.Size()
- // Here's an example of how to inject a keystroke where it will
- // be picked up by a future read of the event queue. Note that
- // care should be used to avoid blocking writes to the queue if
- // this is done from the same thread that is responsible for reading
- // the queue, or else a single-party deadlock might occur.
- // s.EventQ() <- tcell.NewEventKey(tcell.KeyRune, rune('a'), 0)
- curr_menu_item := 0
- menu := true
- gap_title_menu := 3
- credits := false
- frame := 0
- ticker := time.NewTicker(500 * time.Millisecond)
- defer ticker.Stop()
-
- // Event loop
- for {
- s.Clear()
- title_size := drawTitle(s, 10, 2, frame, defStyle, cats)
- frame = (frame + 1) % 2
- xmax,ymax := s.Size()
- // Draw Menu
- if menu {
- drawText(s, 10, title_size+gap_title_menu, xmax, ymax, defStyle, "Use arrows to navigate. Press ENTER to select")
- switch curr_menu_item {
- case 0:
- drawText(s, 10, title_size+gap_title_menu+2, xmax, ymax, defStyle, "▶ Start New Game")
- drawText(s, 10, title_size+gap_title_menu+3, xmax, ymax, defStyle, " Level Selector")
- drawText(s, 10, title_size+gap_title_menu+4, xmax, ymax, defStyle, " Credits")
- case 1:
- drawText(s, 10, title_size+gap_title_menu+2, xmax, ymax, defStyle, " Start New Game")
- drawText(s, 10, title_size+gap_title_menu+3, xmax, ymax, defStyle, "▶ Level Selector")
- drawText(s, 10, title_size+gap_title_menu+4, xmax, ymax, defStyle, " Credits")
- case 2:
- drawText(s, 10, title_size+gap_title_menu+2, xmax, ymax, defStyle, " Start New Game")
- drawText(s, 10, title_size+gap_title_menu+3, xmax, ymax, defStyle, " Level Selector")
- drawText(s, 10, title_size+gap_title_menu+4, xmax, ymax, defStyle, "▶ Credits")
- }
- }
-
- if credits {
- drawText(s, 10, title_size+gap_title_menu, xmax,ymax, defStyle, "Abderrahmane Faiz")
- drawText(s, 10, title_size+gap_title_menu+1, xmax,ymax, defStyle, "\u001B]8;;https://afaiz.dev\u001B\\https://afaiz.dev\u001B]8;;\u001B\\")
- drawText(s, 10, title_size+gap_title_menu+2, xmax,ymax, defStyle, "ASCII Art found on https://emojicombos.com/cat")
- drawText(s, 10, title_size+gap_title_menu+4, xmax,ymax, defStyle, "Press ENTER to go back to the menu")
- }
-
- // Update screen
- s.Show()
- // Poll event (this can be in a select statement as well)
- select{
- case <- ticker.C:
- continue
- case ev := <-s.EventQ():
- // Process event
- switch ev := ev.(type) {
- default:
- continue
- case *tcell.EventResize:
- s.Sync()
- case *tcell.EventKey:
- if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC {
- return
- } else if ev.Key() == tcell.KeyUp && menu {
- if curr_menu_item == 0 {
- curr_menu_item = 2
- } else {
- curr_menu_item = curr_menu_item - 1
- }
- } else if ev.Key() == tcell.KeyDown && menu {
- curr_menu_item = (curr_menu_item + 1) % 3
- } else if ev.Key() == tcell.KeyEnter && credits {
- credits = false
- menu = true
- } else if ev.Key() == tcell.KeyEnter && curr_menu_item == 2 {
- menu = false
- credits = true
- }
- }
- }
- }
- }
|