1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#include "../graphics.c"
typedef struct {
f64 x;
f64 y;
f64 vx;
f64 vy;
} Entity;
typedef struct {
i64 time;
i64 num_entities;
Entity entities[10 * 1024 * 1024];
} World;
World world = {0};
vec4_f32 background = { .0f, .0f, .08f, 1.f };
i64 time_0;
void update_and_render_frame(void) {
p_handle_events();
i64 time_elapsed = p_time() - time_0;
time_0 += time_elapsed;
if (g_platform.key_pressed[BUTTON_LEFT]) {
i64 n = world.num_entities++;
world.entities[n] = (Entity) {
.x = (f64) g_platform.cursor_x - (f64) g_platform.frame_width / 2,
.y = -((f64) g_platform.cursor_y - (f64) g_platform.frame_height / 2),
};
}
if (time_elapsed > 0) {
if (g_platform.key_down[BUTTON_RIGHT]) {
for (i64 n = 0; n < time_elapsed; ++n)
world.entities[world.num_entities + n] = (Entity) {
.x = (f64) g_platform.cursor_x - (f64) g_platform.frame_width / 2,
.y = -((f64) g_platform.cursor_y - (f64) g_platform.frame_height / 2),
};
world.num_entities += time_elapsed;
}
for (i64 n = 0; n < world.num_entities; ++n) {
Entity *e = &world.entities[n];
for (i64 k = 0; k < n; ++k) {
Entity *u = &world.entities[k];
f64 dx = e->x - u->x;
f64 dy = e->y - u->y;
f64 d = dx * dx + dy * dy;
if (d < 1000.) continue;
f64 r = sqrt(d);
dx /= r;
dy /= r;
f64 a = (1. / d) * time_elapsed;
if (d < 5000.)
a = -a;
e->vx -= dx * a;
e->vy -= dy * a;
u->vx += dx * a;
u->vy += dy * a;
}
}
for (i64 n = 0; n < world.num_entities; ++n) {
Entity *e = &world.entities[n];
e->x += e->vx * time_elapsed;
e->y += e->vy * time_elapsed;
f64 z = (M_PI * 2.0) * (rand() % 10000) * .0001;
e->vx += .0001 * cos(z);
e->vy += .0001 * sin(z);
}
world.time += time_elapsed;
}
for (i32 j = 0; j < g_platform.frame_height; ++j)
for (i32 i = 0; i < g_platform.frame_width; ++i)
g_platform.pixels[j * g_platform.frame_width + i] = background;
for (i64 n = 0; n < world.num_entities; ++n) {
Entity *e = &world.entities[n];
i32 x = g_platform.frame_width / 2 + (i32) floor(e->x + .5);
i32 y = g_platform.frame_height / 2 - (i32) floor(e->y + .5);
for (i32 j = y - 10; j <= y + 10; ++j) {
if (j < 0 || j >= g_platform.frame_height) continue;
for (i32 i = x - 10; i <= x + 10; ++i) {
if (i < 0 || i >= g_platform.frame_width) continue;
if ((i - x) * (i - x) + (j - y) * (j - y) > 100) continue;
f64 v = (e->vx * e->vx + e->vy * e->vy) * 8.;
g_platform.pixels[j * g_platform.frame_width + i] = (vec4_f32) { -.2 + v * 2., .1 + v * .7, 1. - v, 1.f };
}
}
}
p_render_frame();
}
i32 main(i32 argc, c8 **argv) {
(void) argc;
(void) argv;
g_platform = (Platform) {
.title = "Particles",
.exact_resolution = 1,
};
time_0 = p_time();
srand(p_time());
p_event_loop();
return 0;
}
|