mirror of
https://github.com/vlang/v.git
synced 2025-09-12 08:57:09 -04:00
149 lines
3.1 KiB
V
149 lines
3.1 KiB
V
// Use `v -d show_fps run examples/gg/fire.v` to show a fire effect with an FPS counter.
|
|
import gg
|
|
import rand
|
|
|
|
const win_width = 800
|
|
const win_height = 600
|
|
const width = 100
|
|
const height = 140
|
|
const scale = 4
|
|
const palette = [
|
|
gg.rgb(0x07, 0x07, 0x07),
|
|
gg.rgb(0x1f, 0x07, 0x07),
|
|
gg.rgb(0x2f, 0x0f, 0x07),
|
|
gg.rgb(0x47, 0x0f, 0x07),
|
|
gg.rgb(0x57, 0x17, 0x07),
|
|
gg.rgb(0x67, 0x1f, 0x07),
|
|
gg.rgb(0x77, 0x1f, 0x07),
|
|
gg.rgb(0x8f, 0x27, 0x07),
|
|
gg.rgb(0x9f, 0x2f, 0x07),
|
|
gg.rgb(0xaf, 0x3f, 0x07),
|
|
gg.rgb(0xbf, 0x47, 0x07),
|
|
gg.rgb(0xc7, 0x47, 0x07),
|
|
gg.rgb(0xdf, 0x4f, 0x07),
|
|
gg.rgb(0xdf, 0x57, 0x07),
|
|
gg.rgb(0xdf, 0x57, 0x07),
|
|
gg.rgb(0xd7, 0x5f, 0x07),
|
|
gg.rgb(0xd7, 0x5f, 0x07),
|
|
gg.rgb(0xd7, 0x67, 0x0f),
|
|
gg.rgb(0xcf, 0x6f, 0x0f),
|
|
gg.rgb(0xcf, 0x77, 0x0f),
|
|
gg.rgb(0xcf, 0x7f, 0x0f),
|
|
gg.rgb(0xcf, 0x87, 0x17),
|
|
gg.rgb(0xc7, 0x87, 0x17),
|
|
gg.rgb(0xc7, 0x8f, 0x17),
|
|
gg.rgb(0xc7, 0x97, 0x1f),
|
|
gg.rgb(0xbf, 0x9f, 0x1f),
|
|
gg.rgb(0xbf, 0x9f, 0x1f),
|
|
gg.rgb(0xbf, 0xa7, 0x27),
|
|
gg.rgb(0xbf, 0xa7, 0x27),
|
|
gg.rgb(0xbf, 0xaf, 0x2f),
|
|
gg.rgb(0xb7, 0xaf, 0x2f),
|
|
gg.rgb(0xb7, 0xb7, 0x2f),
|
|
gg.rgb(0xb7, 0xb7, 0x37),
|
|
gg.rgb(0xcf, 0xcf, 0x6f),
|
|
gg.rgb(0xdf, 0xdf, 0x9f),
|
|
gg.rgb(0xef, 0xef, 0xc7),
|
|
gg.rgb(0xff, 0xff, 0xff),
|
|
]!
|
|
|
|
struct App {
|
|
mut:
|
|
gg &gg.Context = unsafe { nil }
|
|
buf [][]int
|
|
dying bool
|
|
tiles int
|
|
}
|
|
|
|
fn main() {
|
|
mut app := &App{
|
|
buf: [][]int{len: height - 1, init: []int{len: width}}
|
|
}
|
|
app.buf << []int{len: width, init: 36} // white fire base
|
|
|
|
app.gg = gg.new_context(
|
|
event_fn: event
|
|
frame_fn: frame
|
|
init_fn: retile
|
|
window_title: 'Fire Animation'
|
|
user_data: app
|
|
bg_color: palette[0]
|
|
width: win_width
|
|
height: win_height
|
|
)
|
|
app.gg.run()
|
|
}
|
|
|
|
fn retile(mut app App) {
|
|
size := app.gg.window_size()
|
|
app.tiles = size.width / (width * scale) + 1
|
|
}
|
|
|
|
fn (mut app App) draw() {
|
|
size := app.gg.window_size()
|
|
for t in 0 .. app.tiles {
|
|
app.gg.begin()
|
|
for y, row in app.buf {
|
|
for x, i in row {
|
|
app.gg.draw_square_filled(t * width * scale + x * scale,
|
|
(size.height - height * scale) + y * scale, scale, palette[i])
|
|
}
|
|
}
|
|
app.gg.end(
|
|
how: if t == 0 { .clear } else { .passthru }
|
|
)
|
|
// one pass per tile to avoid sgl vertex limit
|
|
}
|
|
}
|
|
|
|
@[direct_array_access]
|
|
fn (mut app App) tick() {
|
|
for x in 0 .. width {
|
|
for y in 1 .. height {
|
|
if app.buf[y][x] > 0 {
|
|
r := rand.intn(4) or { panic('failed to generate random number') }
|
|
xn := ((x - r + 1) % width + width) % width
|
|
app.buf[y - 1][xn] = app.buf[y][x] - r % 2
|
|
} else {
|
|
app.buf[y - 1][x] = 0
|
|
}
|
|
}
|
|
}
|
|
if app.dying {
|
|
for x in 0 .. width {
|
|
y := height - 1
|
|
app.buf[y][x] -= rand.intn(4) or { panic('failed to generate random number') }
|
|
if app.buf[y][x] < 0 {
|
|
app.buf[y][x] = 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn event(event &gg.Event, mut app App) {
|
|
match event.typ {
|
|
.key_up {
|
|
match event.key_code {
|
|
.space {
|
|
if app.dying {
|
|
app.dying = false
|
|
app.buf[height - 1] = []int{len: width, init: 36}
|
|
} else {
|
|
app.dying = true
|
|
}
|
|
}
|
|
else {}
|
|
}
|
|
}
|
|
.resized {
|
|
retile(mut app)
|
|
}
|
|
else {}
|
|
}
|
|
}
|
|
|
|
fn frame(mut app App) {
|
|
app.draw()
|
|
app.tick()
|
|
}
|