diff options
author | Zhongheng Liu <z.liu@outlook.com.gr> | 2024-10-23 21:26:34 +0300 |
---|---|---|
committer | Zhongheng Liu <z.liu@outlook.com.gr> | 2024-10-23 21:26:34 +0300 |
commit | dc16793ad7548cb6e7cd43139566db8b6d138824 (patch) | |
tree | cae948a05b07bb9056dfac2da3d2b055dd07d4c9 | |
parent | 024eb0c2bbbc2f30fb8e2403ef22fabc27910acd (diff) | |
download | rulmarc-dc16793ad7548cb6e7cd43139566db8b6d138824.tar.gz rulmarc-dc16793ad7548cb6e7cd43139566db8b6d138824.tar.bz2 rulmarc-dc16793ad7548cb6e7cd43139566db8b6d138824.zip |
feat: a ton of input handling and Go TUI logic
Main: Added main interface with big output box and small input box
Effects: Added some blinking lights effect for the cursor to prompt user
of where to enter stuff
-rw-r--r-- | new_game.go | 99 | ||||
-rw-r--r-- | utils/helper/effects.go | 54 | ||||
-rw-r--r-- | utils/helper/incremental_print.go | 4 |
3 files changed, 135 insertions, 22 deletions
diff --git a/new_game.go b/new_game.go index b2d258b..ed91803 100644 --- a/new_game.go +++ b/new_game.go @@ -1,14 +1,30 @@ package main import ( + // "fmt" "time" . "github.com/gbin/goncurses" + "gitlab.com/stvnliu/ai_game/utils/helper" . "gitlab.com/stvnliu/ai_game/utils/types" "gitlab.com/stvnliu/ai_game/utils/windows" - "gitlab.com/stvnliu/ai_game/utils/helper" ) +const ( + STD_BLINK_INTERVAL = 450 * time.Millisecond +) + +func IncrementalPrintMany( + w *Window, + y int, + x int, + texts []string, + duration time.Duration, +) { + for i := 0; i < len(texts); i++ { + helper.IncrementalPrint(w, texts[i], y+i, x, int(1*time.Second)) + } +} func NewGame(scr *Window) { //_, _ := scr.MaxYX() game_name := windows.InputPrompt(scr, " New game information ", "Game name: ", 20) @@ -35,32 +51,75 @@ func NewGame(scr *Window) { panic("Oh shit something happened that shouldn't") } w.Box(0, 0) - input_window, input_window_error := NewWindow(6,mx-3,my-7,2) + input_window, input_window_error := NewWindow(6, mx-3, my-7, 2) if input_window_error != nil { - panic("Oh no") - } - input_window.Box(1, 1) - input_window.MovePrint(1, 1, "> ") - input_window.Move(1, 3) - w.Refresh() - input_window.Refresh() - texts := []string { - "Hello world!!", - "Welcome to R.U.L.M.A.R.C.", - "This is an experimental game project that uses Large Language Models to power realistically rendered characters.", - "============ Copyright 2024 @ Zhongheng Liu & Zhiyong He =============", - "Try it! Put in some characters in the input box below!", - "Please wait while we boot some Artificial Intelligencce models for the first part of the game...", - } - for i := 0; i < len(texts); i++ { - helper.IncrementalPrint(w, texts[i], 1+i, 1, 500) - } + panic("Oh no") + } + input_window.Box(1, 1) + input_window.MovePrint(1, 1, "> ") + input_window.Move(1, 3) + w.Refresh() + input_window.Refresh() + texts := []string{ + "Hello world!!", + "Welcome to R.U.L.M.A.R.C.", + "This is an experimental game project that uses Large Language Models to power realistically rendered characters.", + "============ Copyright 2024 @ Zhongheng Liu & Zhiyong He =============", + "Please wait while we boot some AI models for the first part of the game...", + } + IncrementalPrintMany(w, 1, 1, texts, time.Duration(1*time.Second)) + + init_done := make(chan bool, 1) + + go helper.BlinkCursorUntilDone( + w, + len(texts)+1, + 1, + STD_BLINK_INTERVAL, + init_done, + ) + + // Simulating game init process + // time.Sleep(time.Duration(10 * time.Second)) + init_done <- true // can trigger blinker process finish + texts2 := []string{ + "Ok we are done with everything!", + "Now try putting something in the input box below!", + } + IncrementalPrintMany(w, len(texts)+1, 1, texts2, time.Duration(1*time.Second)) + key := helper.BlinkCursorUntilInput(input_window, 1, 3, STD_BLINK_INTERVAL) + Cursor(0) + my_input := "You said: " + for { + Cursor(2) + _, cx := input_window.CursorYX() + if key != 0 { + // workaround for backspace key + if (key == KEY_BACKSPACE) || (key == 127) { + if cx-1 > 2 { + input_window.MoveDelChar(1, cx-1) + my_input = my_input[:len(my_input)-1] + } + } else if !((key == KEY_ENTER) || (key == KEY_RETURN)) { + input_window.MovePrint(1, cx, KeyString(key)) + my_input += KeyString(key) + input_window.Move(1, cx+1) + } else { + break + } + } + key = input_window.GetChar() + } + + helper.IncrementalPrint(w, my_input, 8, 1, int(time.Duration(1*time.Second))) + // User input processing for { ch := w.GetChar() switch Key(ch) { case 'q': w.Erase() w.Refresh() + w.Delete() return } w.Refresh() diff --git a/utils/helper/effects.go b/utils/helper/effects.go new file mode 100644 index 0000000..ff9a93a --- /dev/null +++ b/utils/helper/effects.go @@ -0,0 +1,54 @@ +package helper + +import ( + "fmt" + "time" + + . "github.com/gbin/goncurses" +) + +func BlinkCursorUntilInput(scr *Window, pos_y int, pos_x int, interval time.Duration) Key { + scr.Move(pos_y, pos_x) + var activation_key Key + for { + Cursor(2) + scr.Timeout(int((interval / 3).Milliseconds())) + activation_key = scr.GetChar() + if activation_key != 0 { + break + } + time.Sleep(interval / 3) + Cursor(0) + time.Sleep(interval / 3) + } + return activation_key +} +func BlinkCursorUntilDone(scr *Window, pos_y int, pos_x int, interval time.Duration, done <-chan bool) { + scr.Move(pos_y, pos_x) + for { + Cursor(2) + select { + case is_done, ok := <-done: + if ok && is_done { + return + } else { + fmt.Println("Channel closed?") + } + default: + time.Sleep(interval / 2) + Cursor(0) + time.Sleep(interval / 2) + + } + } +} +func BlinkCursorWithTime(scr *Window, pos_y int, pos_x int, duration time.Duration, interval time.Duration) { + scr.Move(pos_y, pos_x) + n := duration / interval + for i := 0; i < int(n); i++ { + Cursor(2) + time.Sleep(interval / 2) + Cursor(0) + time.Sleep(interval / 2) + } +} diff --git a/utils/helper/incremental_print.go b/utils/helper/incremental_print.go index 0b4fc4f..c94f904 100644 --- a/utils/helper/incremental_print.go +++ b/utils/helper/incremental_print.go @@ -10,8 +10,8 @@ func IncrementalPrint(scr *Window, text string, from_y int, from_x int, interval for i:=0; i < len(text); i++ { ch := string([]rune(text)[i]) _, mx := scr.MaxYX() - cy := i / mx + 2 + from_y - cx := i % mx + 2 + cy := i / mx + from_y + cx := i % mx + 1 scr.MovePrint(cy, cx, ch) time.Sleep( time.Duration(1000 / len(text)) * time.Millisecond) scr.Refresh() |