v2 / examples / sokol / particles / modules / particle / system.v
120 lines · 111 sloc · 2.26 KB · e2e5cf8db56f3562c7baa735061690be936bdf3e
Raw
1// Copyright(C) 2019 Lars Pontoppidan. All rights reserved.
2// Use of this source code is governed by an MIT license file distributed with this software package
3module particle
4
5import math.vec
6import rand
7import sokol.sgl
8
9pub struct SystemConfig {
10pub:
11 pool int
12}
13
14pub struct System {
15pub:
16 width int
17 height int
18mut:
19 pool []&Particle
20 bin []&Particle
21}
22
23pub fn (mut s System) init(sc SystemConfig) {
24 unsafe { s.pool.flags.set(.noslices | .noshrink) }
25 unsafe { s.bin.flags.set(.noslices | .noshrink) }
26 for i := 0; i < sc.pool; i++ {
27 p := new(vec.Vec2[f64]{f32(s.width) * 0.5, f32(s.height) * 0.5})
28 s.bin << p
29 }
30}
31
32pub fn (mut s System) update(dt f64) {
33 mut p := &Particle(unsafe { nil })
34 mut moved := 0
35 for i := 0; i < s.pool.len; i++ {
36 p = s.pool[i]
37 p.update(dt)
38 if p.is_dead() {
39 s.bin << p
40 s.pool.delete(i)
41 moved++
42 }
43 }
44 if moved != 0 {
45 $if trace_moves_spool_to_sbin ? {
46 eprintln('${moved:4} particles s.pool -> s.bin')
47 }
48 }
49}
50
51pub fn (s System) draw() {
52 sgl.begin_quads()
53 for p in s.pool {
54 p.draw()
55 }
56 sgl.end()
57}
58
59pub fn (mut s System) reset() {
60 for i in 0 .. s.pool.len {
61 mut p := s.pool[i]
62 p.reset()
63 p.life_time = 0
64 }
65 for i in 0 .. s.bin.len {
66 mut p := s.pool[i]
67 p.reset()
68 p.life_time = 0
69 }
70}
71
72pub fn (mut s System) explode(x f32, y f32) {
73 mut reserve := 500
74 center := vec.Vec2[f64]{x, y}
75 mut p := &Particle(unsafe { nil })
76 mut moved := 0
77 for i := 0; i < s.bin.len && reserve > 0; i++ {
78 p = s.bin[i]
79 p.reset()
80 p.location.from(center)
81 p.acceleration = vec.Vec2[f64]{rand.f32_in_range(-0.5, 0.5) or { -0.5 }, rand.f32_in_range(-0.5, 0.5) or {
82 -0.5
83 }}
84 p.velocity = vec.Vec2[f64]{rand.f32_in_range(-0.5, 0.5) or { -0.5 }, rand.f32_in_range(-0.5, 0.5) or {
85 -0.5
86 }}
87 p.life_time = rand.f64_in_range(500, 2000) or { 500 }
88 s.pool << p
89 s.bin.delete(i)
90 moved++
91 reserve--
92 }
93 if moved != 0 {
94 $if trace_moves_sbin_to_spool ? {
95 eprintln('${moved:4} particles s.bin -> s.pool')
96 }
97 }
98}
99
100pub fn (mut s System) free() {
101 for p in s.pool {
102 if unsafe { p == 0 } {
103 print(ptr_str(p) + ' ouch')
104 continue
105 }
106 unsafe { free(p) }
107 }
108 s.pool.clear()
109 for p in s.bin {
110 if unsafe { p == 0 } {
111 print(ptr_str(p) + ' ouch')
112 continue
113 }
114 unsafe {
115 // println('Freeing from bin')
116 free(p)
117 }
118 }
119 s.bin.clear()
120}
121