package main import ( "citrons.xyz/talk/tui" "math/rand" "log" "strings" "time" ) type ball struct { x int y int vx int vy int inGoal bool } func main() { tui.Start() s := tui.Size() var balls [20]ball for i := 0; i < len(balls); i++ { balls[i].x = rand.Int() % s.Width - 1 balls[i].y = rand.Int() % s.Height if rand.Int() % 2 == 1 { balls[i].vx = 1 } else { balls[i].vx = -1 } if rand.Int() % 2 == 1 { balls[i].vy = 1 } else { balls[i].vy = -1 } } var sb strings.Builder for { tui.Clear() s := tui.Size() for y := 0; y < s.Height; y++ { for x := 0; x < s.Width; x++ { if (x + 66) % 10 == 1 && (y + 2) % 5 == 1 { tui.Write(x, y, "*", tui.Style {Fg: tui.Green}) } } } tui.Write(2, 1, "normal", tui.Style {Fg: tui.Red}) tui.Write(2, 2, "bold", tui.Style {Fg: tui.Yellow, Bold: true}) tui.Write(2, 3, "italic", tui.Style {Fg: tui.Green, Italic: true}) tui.Write(2, 4, "underline", tui.Style {Fg: tui.Blue, Underline: true}) tui.Write(2, 5, "strikethrough", tui.Style {Fg: tui.Magenta, Strikethrough: true}) tui.Write(2, 6, "hooray!", tui.Style {Fg: tui.White, Bold: true, Italic: true, Underline: true, Strikethrough: true}) gx := s.Width / 2 - 1 for i := 0; i < len(balls); i++ { if balls[i].inGoal { continue } balls[i].x += balls[i].vx balls[i].y += balls[i].vy if balls[i].x < 0 { balls[i].x = 0 balls[i].vx = -balls[i].vx } else if balls[i].x >= s.Width - 1 { balls[i].x = s.Width - 2 balls[i].vx = -balls[i].vx } if balls[i].y < 0 { balls[i].y = 0 balls[i].vy = -balls[i].vy } else if balls[i].y >= s.Height { balls[i].y = s.Height - 1 balls[i].vy = -balls[i].vy } if balls[i].x >= gx - 1 && balls[i].x <= gx + 1 && balls[i].y == 0 { balls[i].inGoal = true continue } tui.Write(balls[i].x, balls[i].y, "⚽", tui.DefaultStyle) } tui.Write(gx, 0, "🥅", tui.DefaultStyle) w := tui.Write(2, 8, sb.String(), tui.DefaultStyle) tui.MoveCursor(2 + w, 8) err := tui.Present() if err != nil { log.Fatal(err) } select { case ev := <-tui.Events(): switch ev := ev.(type) { case tui.TextInput: sb.WriteRune(rune(ev)) case error: log.Fatal(ev) } case <-time.After(time.Second / 16): } } }