use package core
-#private_file imgui :: package imgui
+#private_file gfx :: package immediate_mode
#private_file events :: package js_events
#private_file gl :: package gl
particle_board: ParticleBoard;
+world_width :: 400
+world_height :: 400
world_texture : gl.GLTexture
world_texture_data : [] u8
-world_width := 512
-world_height := 256
window_width := 0
window_height := 0
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.bindTexture(gl.TEXTURE_2D, -1);
- imgui.immediate_renderer_init();
+ gfx.immediate_renderer_init();
particle_board = create_board(world_width, world_height);
}
}
draw :: () {
- use imgui;
-
prepare_world_texture();
- use_ortho_projection(0, ~~window_width, 0, ~~window_height);
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
+ gfx.set_texture();
+ gfx.use_ortho_projection(0, ~~window_width, 0, ~~window_height);
draw_selection_bar();
gl.bindTexture(gl.TEXTURE_2D, world_texture);
- immediate_set_texture(0);
- immediate_textured_quad(.{ 0, BAR_HEIGHT }, .{ ~~window_width, ~~window_height - BAR_HEIGHT }, .{ 0, 0 }, .{ 1, 1 }, color=.{ 1, 1, 1 });
- immediate_set_texture();
+ gfx.set_texture(0);
+ gfx.use_ortho_projection(0, ~~window_width, 0, ~~window_height);
+ gfx.textured_quad(.{ 0, BAR_HEIGHT }, .{ ~~window_width, ~~window_height - BAR_HEIGHT }, .{ 0, 0 }, .{ 1, 1 });
- immediate_flush();
+ gfx.flush();
gl.bindTexture(gl.TEXTURE_2D, -1);
draw_selection_bar :: () {
- use imgui;
-
- immediate_quad(.{ 0, 0 }, .{ ~~window_width, BAR_HEIGHT }, color=.{.2,.2,.2});
+ gfx.quad(.{ 0, 0 }, .{ ~~window_width, BAR_HEIGHT }, color=.{.2,.2,.2});
x_off := 4.0f;
for type: Particle.types {
if type == selected_particle {
- immediate_quad(.{ x_off - 4, 0 }, .{ BAR_HEIGHT, BAR_HEIGHT }, color=.{1,1,0});
+ gfx.quad(.{ x_off - 4, 0 }, .{ BAR_HEIGHT, BAR_HEIGHT }, color=.{1,1,0});
}
color := particle_type_to_color(type) |> convert_color();
- immediate_quad(.{ x_off, 4 }, .{ BAR_HEIGHT - 8, BAR_HEIGHT - 8 }, color=color);
+ gfx.quad(.{ x_off, 4 }, .{ BAR_HEIGHT - 8, BAR_HEIGHT - 8 }, color=color);
x_off += BAR_HEIGHT;
}
}
- convert_color :: (use c: Color) -> imgui.Color4 {
+ convert_color :: (use c: Color) -> gfx.Color4 {
return .{
~~cast(i32) r / 255.0f,
~~cast(i32) g / 255.0f,
update_sand :: (use board: ^ParticleBoard, x: i32, y: i32) {
index := get_index(board, x, y);
- particles[index].velocity.y += Gravity;
+ particles[index].velocity.y += Gravity * random.float(0.8, 1.2);
- if particles[get_index(board, x, y + 1)].type != .Empty {
+ directly_below_index := get_index(board, x, y + 1);
+ if directly_below_index < 0 || particles[directly_below_index].type != .Empty {
particles[index].velocity.y = 0;
}
vy := cast(i32) particles[index].velocity.y;
+ prev_move_index := -1;
for yy: y + 1 .. y + vy + 2 {
b_index := get_index(board, x, yy);
bl_index := get_index(board, x - 1, yy);
move_to_index := first_empty(board, b_index, bl_index, br_index);
- if move_to_index != -1 {
- particle_set(board, move_to_index, particles[index]);
+ if move_to_index == -1 && prev_move_index != -1 {
+ particle_set(board, prev_move_index, particles[index]);
particle_set(board, index, .{ .Empty });
return;
+ } else {
+ prev_move_index = move_to_index;
}
}
- b_index := get_index(board, x, y + 1);
- if can_sink(board, b_index) {
- particle_switch(board, index, b_index);
+ if prev_move_index != -1 {
+ particle_set(board, prev_move_index, particles[index]);
+ particle_set(board, index, .{ .Empty });
+ return;
+ }
+
+ if can_sink(board, directly_below_index) {
+ particle_switch(board, index, directly_below_index);
}
}
update_water :: (use board: ^ParticleBoard, x: i32, y: i32) {
index := get_index(board, x, y);
- particles[index].velocity.y += Gravity;
+ // :CopyPaste from update_sand
+ particles[index].velocity.y += Gravity * random.float(0.8, 1.2);
- if particles[get_index(board, x, y + 1)].type != .Empty {
+ // :CopyPaste from update_sand
+ directly_below_index := get_index(board, x, y + 1);
+ if directly_below_index < 0 || particles[directly_below_index].type != .Empty {
particles[index].velocity.y = 0;
}
- vy := cast(i32) particles[index].velocity.y;
- b_index := get_index(board, x, y + vy + 1);
- bl_index := get_index(board, x - 1, y + vy + 1);
- br_index := get_index(board, x + 1, y + vy + 1);
+ // :CopyPaste from update_sand
+ vy := cast(i32) particles[index].velocity.y;
+ prev_move_index := -1;
+ for yy: y + 1 .. y + vy + 2 {
+ b_index := get_index(board, x, yy);
+ bl_index := get_index(board, x - 1, yy);
+ br_index := get_index(board, x + 1, yy);
+
+ move_to_index := first_empty(board, b_index, bl_index, br_index);
- move_to_index := first_empty(board, b_index, br_index, bl_index);
+ if move_to_index == -1 do break;
+ else do prev_move_index = move_to_index;
+ }
- if move_to_index != -1 {
- particle_set(board, move_to_index, particles[index]);
+ if prev_move_index != -1 {
+ particle_set(board, prev_move_index, particles[index]);
particle_set(board, index, .{ .Empty });
return;
}