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
|
use crate::{Board, sim::board::Cell};
pub struct UpdateCtx<'a> {
pub self_x: i32,
pub self_y: i32,
pub self_cell: Cell,
pub delta_time: f32,
pub seqno_parity: u8,
pub board: &'a mut Board,
}
impl UpdateCtx<'_> {
pub fn candidates_swap(&mut self, candidates: &[(i32, i32)]) -> bool {
for candidate in candidates {
let target = self.board.cell_at_position(candidate.0, candidate.1);
if let Some(target) = target
&& target.material.def().density < self.self_cell.material.def().density
{
// swap the cells
self.board
.set_cell_at_position(self.self_x, self.self_y, target);
self.board
.set_cell_at_position(candidate.0, candidate.1, self.self_cell);
return true;
}
}
false
}
}
// TODO: chunks
pub fn sim_tick(board: &mut Board, seqno: u64, delta_time: f32) {
// scan bottom to top to enable contiguous falling
let seqno_parity = (seqno as u8) & 0b1;
let bx = (board.size_x / 2) as i32;
let by = (board.size_y / 2) as i32;
for y in (-by..by + 1).rev() {
// invert scan order on every other frame
for col in -bx..bx + 1 {
let x = if seqno_parity == 0 { col } else { -col };
let cell = board.cell_at_position(x, y);
if let Some(mut cur) = cell
&& cur.flags & 0b1 == seqno_parity
{
// flip the parity bit
cur.flags = cur.flags ^ 0b1;
if let Some(update) = cur.material.def().sim_update {
update(&mut UpdateCtx {
self_x: x,
self_y: y,
self_cell: cur,
board,
delta_time,
seqno_parity,
});
}
}
}
}
}
|