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
This commit is contained in:
parent
024eb0c2bb
commit
dc16793ad7
3 changed files with 135 additions and 22 deletions
99
new_game.go
99
new_game.go
|
@ -1,14 +1,30 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
// "fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
. "github.com/gbin/goncurses"
|
. "github.com/gbin/goncurses"
|
||||||
|
"gitlab.com/stvnliu/ai_game/utils/helper"
|
||||||
. "gitlab.com/stvnliu/ai_game/utils/types"
|
. "gitlab.com/stvnliu/ai_game/utils/types"
|
||||||
"gitlab.com/stvnliu/ai_game/utils/windows"
|
"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) {
|
func NewGame(scr *Window) {
|
||||||
//_, _ := scr.MaxYX()
|
//_, _ := scr.MaxYX()
|
||||||
game_name := windows.InputPrompt(scr, " New game information ", "Game name: ", 20)
|
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")
|
panic("Oh shit something happened that shouldn't")
|
||||||
}
|
}
|
||||||
w.Box(0, 0)
|
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 {
|
if input_window_error != nil {
|
||||||
panic("Oh no")
|
panic("Oh no")
|
||||||
}
|
}
|
||||||
input_window.Box(1, 1)
|
input_window.Box(1, 1)
|
||||||
input_window.MovePrint(1, 1, "> ")
|
input_window.MovePrint(1, 1, "> ")
|
||||||
input_window.Move(1, 3)
|
input_window.Move(1, 3)
|
||||||
w.Refresh()
|
w.Refresh()
|
||||||
input_window.Refresh()
|
input_window.Refresh()
|
||||||
texts := []string {
|
texts := []string{
|
||||||
"Hello world!!",
|
"Hello world!!",
|
||||||
"Welcome to R.U.L.M.A.R.C.",
|
"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.",
|
"This is an experimental game project that uses Large Language Models to power realistically rendered characters.",
|
||||||
"============ Copyright 2024 @ Zhongheng Liu & Zhiyong He =============",
|
"============ Copyright 2024 @ Zhongheng Liu & Zhiyong He =============",
|
||||||
"Try it! Put in some characters in the input box below!",
|
"Please wait while we boot some AI models for the first part of the game...",
|
||||||
"Please wait while we boot some Artificial Intelligencce models for the first part of the game...",
|
}
|
||||||
}
|
IncrementalPrintMany(w, 1, 1, texts, time.Duration(1*time.Second))
|
||||||
for i := 0; i < len(texts); i++ {
|
|
||||||
helper.IncrementalPrint(w, texts[i], 1+i, 1, 500)
|
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 {
|
for {
|
||||||
ch := w.GetChar()
|
ch := w.GetChar()
|
||||||
switch Key(ch) {
|
switch Key(ch) {
|
||||||
case 'q':
|
case 'q':
|
||||||
w.Erase()
|
w.Erase()
|
||||||
w.Refresh()
|
w.Refresh()
|
||||||
|
w.Delete()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.Refresh()
|
w.Refresh()
|
||||||
|
|
54
utils/helper/effects.go
Normal file
54
utils/helper/effects.go
Normal file
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,8 +10,8 @@ func IncrementalPrint(scr *Window, text string, from_y int, from_x int, interval
|
||||||
for i:=0; i < len(text); i++ {
|
for i:=0; i < len(text); i++ {
|
||||||
ch := string([]rune(text)[i])
|
ch := string([]rune(text)[i])
|
||||||
_, mx := scr.MaxYX()
|
_, mx := scr.MaxYX()
|
||||||
cy := i / mx + 2 + from_y
|
cy := i / mx + from_y
|
||||||
cx := i % mx + 2
|
cx := i % mx + 1
|
||||||
scr.MovePrint(cy, cx, ch)
|
scr.MovePrint(cy, cx, ch)
|
||||||
time.Sleep( time.Duration(1000 / len(text)) * time.Millisecond)
|
time.Sleep( time.Duration(1000 / len(text)) * time.Millisecond)
|
||||||
scr.Refresh()
|
scr.Refresh()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue