v / examples / quadtree_demo / quadtree_demo.v
182 lines · 163 sloc · 3.87 KB · e2e5cf8db56f3562c7baa735061690be936bdf3e
Raw
1module main
2
3import datatypes
4import gg
5import time
6import math
7import rand
8
9const win_width = 1340
10const win_height = 640
11const timer_period = 40 * time.millisecond // defaulted at 25 fps
12
13const font_small = gg.TextCfg{
14 color: gg.black
15 size: 20
16}
17
18struct App {
19mut:
20 gg &gg.Context
21 qt datatypes.Quadtree
22 players []datatypes.AABB
23 particles []Particle
24 retrieveds []datatypes.AABB
25 nodes []datatypes.Quadtree
26 width f64 = 1340
27 height f64 = 640
28}
29
30struct Particle {
31mut:
32 pmt datatypes.AABB
33 speed f64
34 angle f64
35}
36
37fn (mut p Particle) update() {
38 p.pmt.x += p.speed * math.cos(p.angle * math.pi / 180)
39 p.pmt.y += p.speed * math.sin(p.angle * math.pi / 180)
40
41 if p.pmt.x < 0 {
42 p.pmt.x = 0
43 p.speed = -p.speed
44 p.angle = -p.angle
45 }
46 if p.pmt.x > 1340 {
47 p.pmt.x = 1340
48 p.speed = -p.speed
49 p.angle = -p.angle
50 }
51 if p.pmt.y < 0 {
52 p.pmt.y = 0
53 p.speed = -p.speed
54 p.angle = 180 - p.angle
55 }
56 if p.pmt.y > 640 {
57 p.pmt.y = 640
58 p.speed = -p.speed
59 p.angle = 180 - p.angle
60 }
61}
62
63fn (mut app App) start() {
64 app.players << datatypes.AABB{1200 * rand.f64(), 500 * rand.f64(), 20, 20}
65 app.insert_particles()
66 for mut particle in app.particles {
67 particle.speed = 10 * rand.f64()
68 particle.angle = 200 * rand.f64()
69 }
70 app.nodes << app.qt.get_nodes()
71}
72
73fn (mut app App) update() {
74 app.qt.clear()
75 app.nodes = []
76 for mut particle in app.particles {
77 particle.update()
78 app.qt.insert(particle.pmt)
79 }
80 app.find_particles()
81 app.nodes << app.qt.get_nodes()
82}
83
84fn (mut app App) insert_particles() {
85 mut grid := 10.0
86 mut gridh := app.qt.perimeter.width / grid
87 mut gridv := app.qt.perimeter.height / grid
88 num_particles := 100
89 for _ in 0 .. num_particles {
90 mut x := rand_minmax(0, gridh) * grid
91 mut y := rand_minmax(0, gridv) * grid
92 mut random_particle := datatypes.AABB{
93 x: x
94 y: y
95 width: rand_minmax(1, 4) * grid
96 height: rand_minmax(1, 4) * grid
97 }
98 app.particles << Particle{random_particle, 0.0, 0.0}
99 }
100}
101
102fn (mut app App) find_particles() {
103 app.retrieveds = []
104 app.retrieveds << app.qt.retrieve(app.players[0])
105}
106
107fn main() {
108 mut app := &App{
109 gg: unsafe { nil }
110 }
111 app.gg = gg.new_context(
112 bg_color: gg.white
113 width: win_width
114 height: win_height
115 create_window: true
116 window_title: 'Quadtree Demo'
117 frame_fn: frame
118 event_fn: on_event
119 user_data: app
120 )
121 app.qt = app.qt.create(0, 0, 1340, 640, 8, 4, 0)
122 app.start()
123 spawn app.run()
124 app.gg.run()
125}
126
127fn (mut app App) on_mouse_move(mouse_x f32, mouse_y f32) {
128 for mut player in app.players {
129 player.x = (mouse_x / gg.window_size_real_pixels().width) * 1340
130 player.y = (mouse_y / gg.window_size_real_pixels().height) * 640
131 }
132}
133
134fn on_event(mut e gg.Event, mut app App) {
135 match e.typ {
136 .mouse_move { app.on_mouse_move(e.mouse_x, e.mouse_y) }
137 else {}
138 }
139}
140
141fn (mut app App) run() {
142 for {
143 app.update()
144 time.sleep(timer_period)
145 }
146}
147
148fn frame(app &App) {
149 app.gg.begin()
150 app.draw()
151 app.gg.end()
152}
153
154fn (app &App) display() {
155 for player in app.players {
156 app.gg.draw_rect_filled(f32(player.x), f32(player.y), f32(player.width),
157 f32(player.height), gg.black)
158 }
159 for particle in app.particles {
160 app.gg.draw_rect_empty(f32(particle.pmt.x), f32(particle.pmt.y), f32(particle.pmt.width),
161 f32(particle.pmt.height), gg.blue)
162 }
163 for node in app.nodes {
164 app.gg.draw_rect_empty(f32(node.perimeter.x), f32(node.perimeter.y),
165 f32(node.perimeter.width), f32(node.perimeter.height), gg.red)
166 }
167 for retrieved in app.retrieveds {
168 app.gg.draw_rect_filled(f32(retrieved.x + 1), f32(retrieved.y + 1),
169 f32(retrieved.width - 2), f32(retrieved.height - 2), gg.green)
170 }
171 app.gg.draw_text(1200, 25, 'Nodes: ${app.nodes.len}', font_small)
172 app.gg.draw_text(1200, 50, 'Particles: ${app.particles.len}', font_small)
173}
174
175fn (app &App) draw() {
176 app.display()
177}
178
179fn rand_minmax(min f64, max f64) f64 {
180 mut val := min + (rand.f64() * (max - min))
181 return val
182}
183