|
|
@@ -1,16 +1,16 @@
|
|
|
package main
|
|
|
|
|
|
import (
|
|
|
+ _ "embed"
|
|
|
+ "fmt"
|
|
|
"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
|
|
|
|
|
|
@@ -49,50 +49,23 @@ func drawTitle(s tcell.Screen, x, padding_top, frame int, style tcell.Style, tit
|
|
|
return len(lines)
|
|
|
}
|
|
|
|
|
|
-func main() {
|
|
|
+
|
|
|
+func DrawMainMenu(s tcell.Screen, defStyle tcell.Style, old_session bool) bool{
|
|
|
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)
|
|
|
+ var first_item_menu string
|
|
|
+ if (old_session){
|
|
|
+ first_item_menu = "Continue"
|
|
|
+ } else {
|
|
|
+ first_item_menu = "Start New Game"
|
|
|
}
|
|
|
- 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
|
|
|
+ settings, credits := false, false
|
|
|
frame := 0
|
|
|
ticker := time.NewTicker(500 * time.Millisecond)
|
|
|
defer ticker.Stop()
|
|
|
@@ -105,20 +78,20 @@ func main() {
|
|
|
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")
|
|
|
+ drawText(s, 10, title_size+gap_title_menu, xmax, ymax, defStyle, "Use arrows or WASD 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")
|
|
|
+ drawText(s, 10, title_size+gap_title_menu+2, xmax, ymax, defStyle, "▶ "+first_item_menu)
|
|
|
+ drawText(s, 10, title_size+gap_title_menu+3, xmax, ymax, defStyle, " Settings")
|
|
|
+ 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")
|
|
|
+ drawText(s, 10, title_size+gap_title_menu+2, xmax, ymax, defStyle, " "+first_item_menu)
|
|
|
+ drawText(s, 10, title_size+gap_title_menu+3, xmax, ymax, defStyle, "▶ Settings")
|
|
|
+ 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")
|
|
|
+ drawText(s, 10, title_size+gap_title_menu+2, xmax, ymax, defStyle, " "+first_item_menu)
|
|
|
+ drawText(s, 10, title_size+gap_title_menu+3, xmax, ymax, defStyle, " Settings")
|
|
|
+ drawText(s, 10, title_size+gap_title_menu+4, xmax, ymax, defStyle, "▶ Credits")
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -128,6 +101,11 @@ func main() {
|
|
|
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")
|
|
|
}
|
|
|
+
|
|
|
+ if settings {
|
|
|
+ drawText(s, 10, title_size+gap_title_menu, xmax,ymax, defStyle, "Nothing to customize for now ^^'")
|
|
|
+ drawText(s, 10, title_size+gap_title_menu+4, xmax,ymax, defStyle, "Press ENTER to go back to the menu")
|
|
|
+ }
|
|
|
|
|
|
// Update screen
|
|
|
s.Show()
|
|
|
@@ -145,23 +123,161 @@ func main() {
|
|
|
s.Sync()
|
|
|
case *tcell.EventKey:
|
|
|
if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC {
|
|
|
- return
|
|
|
- } else if ev.Key() == tcell.KeyUp && menu {
|
|
|
+ return false
|
|
|
+ } else if (ev.Key() == tcell.KeyUp || ev.Str() == "w" || ev.Str() == "W") && 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 {
|
|
|
+ } else if (ev.Key() == tcell.KeyDown || ev.Str() == "s" || ev.Str() == "S") && 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 && settings {
|
|
|
+ settings = false
|
|
|
+ menu = true
|
|
|
} else if ev.Key() == tcell.KeyEnter && curr_menu_item == 2 {
|
|
|
menu = false
|
|
|
credits = true
|
|
|
+ } else if ev.Key() == tcell.KeyEnter && curr_menu_item == 1 {
|
|
|
+ menu = false
|
|
|
+ settings = true
|
|
|
+ } else if ev.Key() == tcell.KeyEnter && curr_menu_item == 0 {
|
|
|
+ return true
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+func DrawCat(s tcell.Screen, x1,y1,x2,y2 int, style tcell.Style, direction rune) {
|
|
|
+ mycat := []string{" /\\_/\\","( o.o )", " > ^ <"}
|
|
|
+ switch direction{
|
|
|
+ case 'l':
|
|
|
+ mycat[len(mycat)-1] = " < ^ <"
|
|
|
+ case 'r':
|
|
|
+ mycat[len(mycat)-1] = " > ^ >"
|
|
|
+ default :
|
|
|
+ mycat[len(mycat)-1] = " > ^ <"
|
|
|
+ }
|
|
|
+
|
|
|
+ for index,cat := range mycat{
|
|
|
+ drawText(s, x1, y1 + index, x2,y2, style, cat)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+func main() {
|
|
|
+ // Initialize screen
|
|
|
+ defStyle := tcell.StyleDefault.Background(color.Black).Foreground(color.NewHexColor(0xf3e5ab))
|
|
|
+ s, err := tcell.NewScreen()
|
|
|
+ if err != nil {
|
|
|
+ log.Fatalf("%+v", err)
|
|
|
+ }
|
|
|
+ if err := s.Init(); err != nil {
|
|
|
+ log.Fatalf("%+v", err)
|
|
|
+ }
|
|
|
+ s.SetStyle(defStyle)
|
|
|
+
|
|
|
+ quit := func() {
|
|
|
+ maybePanic := recover()
|
|
|
+ s.Fini()
|
|
|
+ if maybePanic != nil {
|
|
|
+ panic(maybePanic)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ defer quit()
|
|
|
+
|
|
|
+ // Main Menu
|
|
|
+ start_game := DrawMainMenu(s, defStyle, false)
|
|
|
+
|
|
|
+ if (!start_game){
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ score := 0
|
|
|
+ level := 1
|
|
|
+ direction := 'n'
|
|
|
+ x_offset := 0
|
|
|
+game_loop:
|
|
|
+ go_to_menu := false
|
|
|
+ for {
|
|
|
+ if (go_to_menu){
|
|
|
+ break
|
|
|
+ }
|
|
|
+ s.Clear()
|
|
|
+
|
|
|
+ xmax,ymax := s.Size()
|
|
|
+
|
|
|
+ length_factor := 5
|
|
|
+ width_factor := 4
|
|
|
+
|
|
|
+ up_right_border := 3*xmax/width_factor
|
|
|
+ width_map := up_right_border - (xmax/width_factor) + 1
|
|
|
+
|
|
|
+ down_right_border := 4*ymax/length_factor
|
|
|
+ length_map := down_right_border - (ymax/length_factor) + 1
|
|
|
+
|
|
|
+ // Draw UI
|
|
|
+ drawText(s, xmax/width_factor, ymax/length_factor - 5, xmax, ymax, defStyle, "Use arrows or AD to move. Press q to return to Main Menu.")
|
|
|
+ drawText(s, xmax/width_factor, ymax/length_factor - 3, xmax, ymax, defStyle, fmt.Sprintf("Level: %d", level))
|
|
|
+ drawText(s, xmax/width_factor, ymax/length_factor - 2, xmax, ymax, defStyle, fmt.Sprintf("Score: %d", score))
|
|
|
+
|
|
|
+ // Draw Game Map Borders
|
|
|
+ // upper border
|
|
|
+ for i := range(width_map){
|
|
|
+ drawText(s,xmax/width_factor+i, ymax/length_factor-1, xmax, ymax, defStyle, "=")
|
|
|
+ }
|
|
|
+ // bottom border
|
|
|
+ for i := range(width_map){
|
|
|
+ drawText(s,xmax/width_factor+i, down_right_border, xmax, ymax, defStyle, "=")
|
|
|
+ }
|
|
|
+ // left border
|
|
|
+ for i := range(length_map){
|
|
|
+ drawText(s,xmax/width_factor, ymax/length_factor+i, xmax, ymax, defStyle, "|")
|
|
|
+ }
|
|
|
+ // right border
|
|
|
+ for i := range(length_map){
|
|
|
+ drawText(s,up_right_border, ymax/length_factor+i, xmax, ymax, defStyle, "|")
|
|
|
+ }
|
|
|
+
|
|
|
+ starting_point_x := (up_right_border + xmax/width_factor)/2 + x_offset
|
|
|
+ DrawCat(s, starting_point_x, down_right_border - 3, xmax,ymax,defStyle, direction)
|
|
|
+
|
|
|
+ s.Show()
|
|
|
+
|
|
|
+ ev := <- s.EventQ()
|
|
|
+ // Process event
|
|
|
+ switch ev := ev.(type) {
|
|
|
+ case *tcell.EventResize:
|
|
|
+ s.Sync()
|
|
|
+ case *tcell.EventKey:
|
|
|
+ if ev.Key() == tcell.KeyEscape || ev.Key() == tcell.KeyCtrlC {
|
|
|
+ return
|
|
|
+ } else if (ev.Key() == tcell.KeyRight || ev.Str() == "d" || ev.Str() == "D") {
|
|
|
+ direction = 'r'
|
|
|
+ if (starting_point_x + 1 < (up_right_border-6)){
|
|
|
+ x_offset += 1
|
|
|
+ }
|
|
|
+ } else if (ev.Key() == tcell.KeyLeft || ev.Str() == "a" || ev.Str() == "A") {
|
|
|
+ direction = 'l'
|
|
|
+ if (starting_point_x + 1 > (xmax/width_factor + 2)){
|
|
|
+ x_offset -= 1
|
|
|
+ }
|
|
|
+ } else if (ev.Key() == tcell.KeyUp || ev.Str() == "w" || ev.Str() == "W") {
|
|
|
+ direction = 'n'
|
|
|
+ } else if (ev.Str() == "q" || ev.Str() == "Q"){
|
|
|
+ go_to_menu = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ start_game = DrawMainMenu(s, defStyle, true)
|
|
|
+ if (start_game){
|
|
|
+ goto game_loop
|
|
|
+ }
|
|
|
+}
|