Initial project import
This commit is contained in:
commit
23f2d29e32
11957 files changed
+1754577
No files matched your search
@@ -0,0 +1,116 @@
|
||||
import os
|
||||
import rand
|
||||
import term
|
||||
import term.termios
|
||||
import time
|
||||
|
||||
const snooze = time.millisecond * 70
|
||||
const symbols = '0123456789!@#$%^&*()-=+[]{}|;:<>?~bdjpqtvz'
|
||||
|
||||
struct RainColumn {
|
||||
mut:
|
||||
col int
|
||||
len int // length of the rain column
|
||||
head int = 1 // y position of the head of rain column
|
||||
}
|
||||
|
||||
fn main() {
|
||||
init_terminal()!
|
||||
rain() // ctrl-c to exit
|
||||
}
|
||||
|
||||
fn rain() {
|
||||
mut rain_columns := []RainColumn{}
|
||||
mut width := 0
|
||||
mut height := 0
|
||||
|
||||
for {
|
||||
// clear screen and all rain columns if terminal resized
|
||||
w, h := term.get_terminal_size()
|
||||
if w != width || h != height {
|
||||
width = w
|
||||
height = h
|
||||
term.clear()
|
||||
rain_columns.clear()
|
||||
}
|
||||
// gradually add more rain columns
|
||||
if rain_columns.len < (width / 4 * 3) {
|
||||
rain_columns << random_rain_column(width, height)
|
||||
}
|
||||
// update and print all rain columns
|
||||
for mut rc in rain_columns {
|
||||
update_rain_column(mut rc, width, height)
|
||||
print_rain_column(rc, height)
|
||||
}
|
||||
// snooze controls update speed
|
||||
time.sleep(snooze)
|
||||
}
|
||||
}
|
||||
|
||||
fn update_rain_column(mut rc RainColumn, width int, height int) {
|
||||
rc.head += 1
|
||||
if rc.head > height + rc.len {
|
||||
rc = random_rain_column(width, height)
|
||||
}
|
||||
}
|
||||
|
||||
fn random_rain_column(max_col int, max_height int) RainColumn {
|
||||
return RainColumn{
|
||||
// console positions are 1 based, not zero
|
||||
col: rand.int_in_range(1, max_col + 1) or { 1 }
|
||||
len: rand.int_in_range(4, max_height / 4 * 3) or { 4 }
|
||||
}
|
||||
}
|
||||
|
||||
fn print_rain_column(rc RainColumn, height int) {
|
||||
// print head in gray
|
||||
if rc.head <= height {
|
||||
print_at(term.gray(random_symbol()), rc.col, rc.head)
|
||||
}
|
||||
// print the char above the head in green to remove
|
||||
// gray color of the previous head. Dim chars
|
||||
// randomly to add more interest to the effect
|
||||
if (rc.head - 1) <= height {
|
||||
symbol := random_dim(term.green(random_symbol()))
|
||||
print_at(symbol, rc.col, rc.head - 1)
|
||||
}
|
||||
// remove tail by printing a space
|
||||
tail := rc.head - rc.len + 1
|
||||
if tail > 0 && tail <= height {
|
||||
print_at(' ', rc.col, tail)
|
||||
}
|
||||
}
|
||||
|
||||
fn print_at(s string, x int, y int) {
|
||||
term.set_cursor_position(term.Coord{ x: x, y: y })
|
||||
print(s)
|
||||
}
|
||||
|
||||
fn random_symbol() string {
|
||||
idx := rand.int_in_range(0, symbols.len) or { 0 }
|
||||
return symbols[idx].ascii_str()
|
||||
}
|
||||
|
||||
fn random_dim(s string) string {
|
||||
i := rand.int_in_range(0, 10) or { 0 }
|
||||
return if i == 1 { term.dim(s) } else { s }
|
||||
}
|
||||
|
||||
fn init_terminal() ! {
|
||||
mut old_state := termios.Termios{}
|
||||
termios.tcgetattr(0, mut old_state)
|
||||
// restore terminal state on exit
|
||||
at_exit(fn [mut old_state] () {
|
||||
termios.set_state(0, old_state)
|
||||
println('\e[?1049l\e[?25h') // cursor on, alternate buffer mode off
|
||||
})!
|
||||
// exit on Ctrl+C
|
||||
os.signal_opt(os.Signal.int, fn (sig os.Signal) {
|
||||
exit(0)
|
||||
})!
|
||||
// exit/restore setup, ok to init terminal
|
||||
mut new_state := old_state
|
||||
new_state.disable_echo()
|
||||
termios.set_state(0, new_state)
|
||||
print('\e[?1049h\e[?25l') // cursor off, alternate buffer mode on
|
||||
}
|
||||
Reference in new issue
Block a user