Initial commit: AtomicEngine v0.2

- Rust/WASM physics engine (grid, material, physics, render_buffer)
- 16 material types (stone, sand, water, wood, fire, lava, glass, ice, oil, acid, steam, spark, smoke + player placeholder)
- Fire system (fuel-based, flammability-scaled consumption, spread, smoke/sparks)
- Lighting system (emission, flood-fill propagation, glow, reflection)
- Per-material pixel texturing (wood grain, dirt specks, stone noise, flame variation)
- WebGL2 renderer with camera (WASD move, mouse wheel zoom)
- Native x86 debug binary (identical dimensions, FPS counter)
- Large world 1024x768 with active-region simulation (camera + 200px margin)
- UI material palette + FPS display
This commit is contained in:
2026-07-09 11:13:39 +02:00
commit 1bce9da0c6
21 changed files with 3261 additions and 0 deletions
+118
View File
@@ -0,0 +1,118 @@
mod grid;
mod material;
mod physics;
mod render_buffer;
use grid::Grid;
use physics::Physics;
use render_buffer::RenderBuffer;
fn main() {
let width = 1024u32;
let height = 768u32;
let rw = 320u32;
let rh = 180u32;
let mut grid = Grid::new(width, height);
let mut physics = Physics::new();
let mut rb = RenderBuffer::new(rw, rh);
grid.fill_rect(440, 720, 144, 48, 1);
grid.fill_rect(460, 700, 104, 20, 2);
grid.fill_rect(470, 600, 84, 12, 5);
grid.fill_circle(490, 560, 20, 3);
grid.fill_rect(430, 650, 50, 30, 4);
grid.fill_rect(540, 650, 50, 30, 6);
grid.fill_rect(500, 640, 10, 18, 11);
grid.fill_rect(480, 630, 64, 24, 5);
grid.fill_rect(480, 618, 64, 12, 9);
let cam_x = 512i32;
let cam_y = 600i32;
let zoom = 2.0f32;
let mut frame = 0;
let start = std::time::Instant::now();
loop {
physics.update(&mut grid, cam_x, cam_y, rw, rh, zoom);
rb.render(&grid, cam_x, cam_y, zoom);
frame += 1;
if frame % 60 == 0 {
let elapsed = start.elapsed();
let fps = frame as f64 / elapsed.as_secs_f64();
let (fire, wood, spark, smoke) = count_mats(&grid);
println!("--- {}s (frame {}) fps: {:.0} ---", frame / 60, frame, fps);
println!("fire: {}, wood: {}, spark: {}, smoke: {}", fire, wood, spark, smoke);
if fire == 0 {
let elapsed = start.elapsed();
let fps = frame as f64 / elapsed.as_secs_f64();
println!("Fire died at frame {}, avg fps: {:.0}", frame, fps);
break;
}
if frame >= 3600 {
println!("Timeout at 60s");
break;
}
}
}
}
fn count_mats(grid: &Grid) -> (u32, u32, u32, u32) {
let mut fire = 0u32;
let mut wood = 0u32;
let mut spark = 0u32;
let mut smoke = 0u32;
for y in 0..grid.height {
for x in 0..grid.width {
match grid.get(x, y) {
5 => wood += 1,
9 => fire += 1,
14 => spark += 1,
15 => smoke += 1,
_ => {}
}
}
}
(fire, wood, spark, smoke)
}
fn temp_range(grid: &Grid) -> (u8, u8) {
let mut min = 255u8;
let mut max = 0u8;
for y in 0..grid.height {
for x in 0..grid.width {
let idx = grid.index(x, y);
let t = grid.temps[idx];
if t > 0 {
min = min.min(t);
max = max.max(t);
}
}
}
if min == 255 { min = 0; }
(min, max)
}
fn print_grid(grid: &Grid) {
for y in 0..grid.height {
for x in 0..grid.width {
let c = match grid.get(x, y) {
5 => 'W',
9 => 'F',
14 => '*',
15 => '%',
0 => '.',
1 => '#',
4 => '~',
6 => 'L',
8 => '\'',
_ => '?',
};
print!("{}", c);
}
println!();
}
}