v0.5: Blue sky gradient, acid rework, iron, phase transitions, shadows (experimental)
- Blue sky gradient background (y<600 blue, 600-700 gradient, y>700 dark) - Acid system: health-based damage via acid_resist, not instant delete - New material: Iron (ID 16) - acid-proof, heat-conductive, reflective - Phase transitions: Iron→Lava (150°C), Sand→Glass (200°C), Glass→Lava (160°C) - Stone no longer melts (lava containment) - Heat transfer formula improved (divisor 255→200) - Iron metallic texture with bright highlights + light reflection - Shadow system attempted (grid-based, per-pixel) - reverted, needs rethink - Updated AGENTS.md for next session
This commit is contained in:
@@ -54,7 +54,7 @@ Grid ist SoA (Structure of Arrays):
|
|||||||
## Material-System
|
## Material-System
|
||||||
|
|
||||||
16 Materialien (0=Luft, 1=Stein, 2=Erde, 3=Sand, 4=Wasser, 5=Holz, 6=Lava,
|
16 Materialien (0=Luft, 1=Stein, 2=Erde, 3=Sand, 4=Wasser, 5=Holz, 6=Lava,
|
||||||
7=Player, 8=Dampf, 9=Feuer, 10=Glas, 11=Eis, 12=Öl, 13=Säure, 14=Funken, 15=Rauch).
|
7=Player, 8=Dampf, 9=Feuer, 10=Glas, 11=Eis, 12=Öl, 13=Säure, 14=Funken, 15=Rauch, 16=Eisen).
|
||||||
|
|
||||||
Properties pro Material: `MaterialProps` in `engine/src/material.rs`:
|
Properties pro Material: `MaterialProps` in `engine/src/material.rs`:
|
||||||
- `color`, `density`, Bewegung-Typ (`is_powder/is_liquid/is_gas/is_solid/is_static`)
|
- `color`, `density`, Bewegung-Typ (`is_powder/is_liquid/is_gas/is_solid/is_static`)
|
||||||
@@ -73,13 +73,20 @@ Properties pro Material: `MaterialProps` in `engine/src/material.rs`:
|
|||||||
- Lava (6) → Stein (1) bei temp ≤ 5°C
|
- Lava (6) → Stein (1) bei temp ≤ 5°C
|
||||||
- Holz (5) → Feuer (9) bei temp ≥ 240°C
|
- Holz (5) → Feuer (9) bei temp ≥ 240°C
|
||||||
- Öl (12) → Feuer (9) bei temp ≥ 120°C
|
- Öl (12) → Feuer (9) bei temp ≥ 120°C
|
||||||
|
- Sand (3) → Glas (10) bei temp ≥ 200°C
|
||||||
|
- Glas (10) → Lava (6) bei temp ≥ 160°C
|
||||||
|
- Eisen (16) → Lava (6) bei temp ≥ 150°C
|
||||||
|
- Stein schmilzt nicht (hält Lava auf)
|
||||||
|
|
||||||
**Reaktionen** (`physics::react`):
|
**Reaktionen** (`physics::react`):
|
||||||
- Wasser + Lava → Dampf + Stein
|
- Wasser + Lava → Dampf + Stein
|
||||||
- Wasser + Feuer → Dampf + Luft (löscht Feuer)
|
- Wasser + Feuer → Dampf + Luft (löscht Feuer)
|
||||||
- Lava + Holz/Öl → entzündet Holz/Öl sofort zu Feuer
|
- Lava + Holz/Öl → entzündet Holz/Öl sofort zu Feuer
|
||||||
- Säure + Holz/Sand → zerstört Holz/Sand
|
- Säure greift ALLE Materialien via `acid_resist` an (Health-basiert, nicht Instant-Delete):
|
||||||
- Säure + Stein/Erde → zerstört Stein/Erde (langsamer)
|
- resist < 100 (Holz 50, Erde 70): ~2s/Zelle
|
||||||
|
- resist 100–200 (Sand 150, Stein 180): ~4s/Zelle
|
||||||
|
- resist ≥ 200 (Eis, Öl): ~13s/Zelle
|
||||||
|
- resist = 255 (Eisen, Glas, Wasser, Lava): immun
|
||||||
|
|
||||||
**Feuer-System**:
|
**Feuer-System**:
|
||||||
- Braucht Brennstoff (Holz, Öl) um zu überleben — prüft direkt unter sich + Moore-Nachbarn
|
- Braucht Brennstoff (Holz, Öl) um zu überleben — prüft direkt unter sich + Moore-Nachbarn
|
||||||
@@ -165,6 +172,10 @@ Jedes Material bekommt deterministische Pixel-Variation basierend auf Grid-Koord
|
|||||||
|
|
||||||
**Beleuchtungs-Formel** (Material-Pixel): Additiv: `r = min(255, r × 150/256 + light)` — Ambient-Basis 59% + Licht obendrauf.
|
**Beleuchtungs-Formel** (Material-Pixel): Additiv: `r = min(255, r × 150/256 + light)` — Ambient-Basis 59% + Licht obendrauf.
|
||||||
|
|
||||||
|
**Hintergrund-Gradient**: Blauer Himmel (`[80,140,220]`) von y=0–600, fließender Übergang zu dunkel (`[20,20,30]`) bei y=600–700. Untergrund ab y=700 dunkel.
|
||||||
|
|
||||||
|
**Schatten**: Experimentell versucht (Platform-Schatten, Sonnen-Raycasting), aktuell ausgebaut. Neu-Ansatz für nächste Session.
|
||||||
|
|
||||||
### UI
|
### UI
|
||||||
- **Material-Palette**: Leiste am unteren Bildschirmrand, Farb-Swatch + Name + Taste
|
- **Material-Palette**: Leiste am unteren Bildschirmrand, Farb-Swatch + Name + Taste
|
||||||
- **FPS-Anzeige**: Oben rechts, grün, alle 500ms aktualisiert
|
- **FPS-Anzeige**: Oben rechts, grün, alle 500ms aktualisiert
|
||||||
|
|||||||
+8
-1
@@ -93,8 +93,11 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grid.fill_circle(400, 500, 15, 16);
|
||||||
|
grid.fill_circle(400, 500, 8, 9);
|
||||||
|
|
||||||
let cam_x = 400i32;
|
let cam_x = 400i32;
|
||||||
let cam_y = 630i32;
|
let cam_y = 500i32;
|
||||||
let zoom = 2.0f32;
|
let zoom = 2.0f32;
|
||||||
|
|
||||||
let mut frame = 0;
|
let mut frame = 0;
|
||||||
@@ -113,6 +116,10 @@ fn main() {
|
|||||||
println!("--- {}s (frame {}) fps: {:.0} ---", frame / 60, frame, fps);
|
println!("--- {}s (frame {}) fps: {:.0} ---", frame / 60, frame, fps);
|
||||||
println!("fire: {}, wood: {}, spark: {}, smoke: {}", fire, wood, spark, smoke);
|
println!("fire: {}, wood: {}, spark: {}, smoke: {}", fire, wood, spark, smoke);
|
||||||
|
|
||||||
|
let idx_inner = grid.index(400, 492);
|
||||||
|
let idx_outer = grid.index(400, 489);
|
||||||
|
println!("(400,492): m={} t={} (400,489): m={} t={}", grid.materials[idx_inner], grid.temps[idx_inner], grid.materials[idx_outer], grid.temps[idx_outer]);
|
||||||
|
|
||||||
if fire == 0 {
|
if fire == 0 {
|
||||||
let elapsed = start.elapsed();
|
let elapsed = start.elapsed();
|
||||||
let fps = frame as f64 / elapsed.as_secs_f64();
|
let fps = frame as f64 / elapsed.as_secs_f64();
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ pub static PROPS: [MaterialProps; M] = [
|
|||||||
MaterialProps { color: [100, 255, 60, 200], density: 30, is_powder: false, is_liquid: true, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 0, boil_temp: 150, heat_conduct: 15, acid_resist: 255, light_emit: 0, light_block: 80 },
|
MaterialProps { color: [100, 255, 60, 200], density: 30, is_powder: false, is_liquid: true, is_gas: false, is_solid: false, is_static: false, flammability: 0, melt_temp: 0, boil_temp: 150, heat_conduct: 15, acid_resist: 255, light_emit: 0, light_block: 80 },
|
||||||
MaterialProps { color: [255, 180, 40, 255], density: 1, is_powder: false, is_liquid: false, is_gas: true, is_solid: false, is_static: false, flammability: 0, melt_temp: 255, boil_temp: 255, heat_conduct: 30, acid_resist: 255, light_emit: 180, light_block: 30 },
|
MaterialProps { color: [255, 180, 40, 255], density: 1, is_powder: false, is_liquid: false, is_gas: true, is_solid: false, is_static: false, flammability: 0, melt_temp: 255, boil_temp: 255, heat_conduct: 30, acid_resist: 255, light_emit: 180, light_block: 30 },
|
||||||
MaterialProps { color: [160, 155, 150, 200], density: 1, is_powder: false, is_liquid: false, is_gas: true, is_solid: false, is_static: false, flammability: 0, melt_temp: 255, boil_temp: 255, heat_conduct: 5, acid_resist: 255, light_emit: 0, light_block: 80 },
|
MaterialProps { color: [160, 155, 150, 200], density: 1, is_powder: false, is_liquid: false, is_gas: true, is_solid: false, is_static: false, flammability: 0, melt_temp: 255, boil_temp: 255, heat_conduct: 5, acid_resist: 255, light_emit: 0, light_block: 80 },
|
||||||
MaterialProps { color: [200, 200, 210, 255], density: 110, is_powder: false, is_liquid: false, is_gas: false, is_solid: true, is_static: true, flammability: 0, melt_temp: 200, boil_temp: 255, heat_conduct: 200, acid_resist: 255, light_emit: 0, light_block: 150 },
|
MaterialProps { color: [200, 200, 210, 255], density: 110, is_powder: false, is_liquid: false, is_gas: false, is_solid: true, is_static: true, flammability: 0, melt_temp: 150, boil_temp: 255, heat_conduct: 80, acid_resist: 255, light_emit: 0, light_block: 150 },
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
@@ -133,12 +133,15 @@ pub fn interact(a: u8, b: u8) -> Interaction {
|
|||||||
|
|
||||||
pub fn transform(temp: u8, material: u8) -> u8 {
|
pub fn transform(temp: u8, material: u8) -> u8 {
|
||||||
match material {
|
match material {
|
||||||
|
3 => if temp >= 200 { 10 } else { 3 },
|
||||||
4 => if temp >= 100 { 8 } else { 4 },
|
4 => if temp >= 100 { 8 } else { 4 },
|
||||||
11 => if temp >= 5 { 4 } else { 11 },
|
5 => if temp >= 240 { 9 } else { 5 },
|
||||||
6 => if temp <= 5 { 1 } else { 6 },
|
6 => if temp <= 5 { 1 } else { 6 },
|
||||||
8 => if temp <= 80 { 4 } else { 8 },
|
8 => if temp <= 80 { 4 } else { 8 },
|
||||||
5 => if temp >= 240 { 9 } else { 5 },
|
10 => if temp >= 160 { 6 } else { 10 },
|
||||||
|
11 => if temp >= 5 { 4 } else { 11 },
|
||||||
12 => if temp >= 120 { 9 } else { 12 },
|
12 => if temp >= 120 { 9 } else { 12 },
|
||||||
|
16 => if temp >= 180 { 6 } else { 16 },
|
||||||
_ => material,
|
_ => material,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,14 +91,23 @@ impl RenderBuffer {
|
|||||||
let lvl = self.light[li] as u32;
|
let lvl = self.light[li] as u32;
|
||||||
|
|
||||||
if mat == 0 {
|
if mat == 0 {
|
||||||
let bg = [20u32, 20, 30];
|
let sky_r = 80u32;
|
||||||
|
let sky_g = 140u32;
|
||||||
|
let sky_b = 220u32;
|
||||||
|
let dark_r = 20u32;
|
||||||
|
let dark_g = 20u32;
|
||||||
|
let dark_b = 30u32;
|
||||||
|
let gyt = ((gy as i32 - 600) * 255 / 100).clamp(0, 255) as u32;
|
||||||
|
let bg_r = (sky_r * (255 - gyt) + dark_r * gyt) / 255;
|
||||||
|
let bg_g = (sky_g * (255 - gyt) + dark_g * gyt) / 255;
|
||||||
|
let bg_b = (sky_b * (255 - gyt) + dark_b * gyt) / 255;
|
||||||
let glow_r = 255u32;
|
let glow_r = 255u32;
|
||||||
let glow_g = 160u32;
|
let glow_g = 160u32;
|
||||||
let glow_b = 40u32;
|
let glow_b = 40u32;
|
||||||
let t = ((lvl * lvl) / 255).min(255);
|
let t = ((lvl * lvl) / 255).min(255);
|
||||||
let r = (bg[0] * (255 - t) + glow_r * t) / 255;
|
let r = (bg_r * (255 - t) + glow_r * t) / 255;
|
||||||
let g = (bg[1] * (255 - t) + glow_g * t) / 255;
|
let g = (bg_g * (255 - t) + glow_g * t) / 255;
|
||||||
let b = (bg[2] * (255 - t) + glow_b * t) / 255;
|
let b = (bg_b * (255 - t) + glow_b * t) / 255;
|
||||||
[r as u8, g as u8, b as u8, 255]
|
[r as u8, g as u8, b as u8, 255]
|
||||||
} else {
|
} else {
|
||||||
let props = &PROPS[mat as usize];
|
let props = &PROPS[mat as usize];
|
||||||
@@ -133,7 +142,17 @@ impl RenderBuffer {
|
|||||||
[r, g, b, base[3]]
|
[r, g, b, base[3]]
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
[20, 20, 30, 255]
|
let sky_r = 80u32;
|
||||||
|
let sky_g = 140u32;
|
||||||
|
let sky_b = 220u32;
|
||||||
|
let dark_r = 20u32;
|
||||||
|
let dark_g = 20u32;
|
||||||
|
let dark_b = 30u32;
|
||||||
|
let gyt = ((gy as i32 - 600) * 255 / 100).clamp(0, 255) as u32;
|
||||||
|
let r = (sky_r * (255 - gyt) + dark_r * gyt) / 255;
|
||||||
|
let g = (sky_g * (255 - gyt) + dark_g * gyt) / 255;
|
||||||
|
let b = (sky_b * (255 - gyt) + dark_b * gyt) / 255;
|
||||||
|
[r as u8, g as u8, b as u8, 255]
|
||||||
};
|
};
|
||||||
|
|
||||||
let pi = ((py * rw + px) * 4) as usize;
|
let pi = ((py * rw + px) * 4) as usize;
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
<title>AtomicEngine</title>
|
<title>AtomicEngine</title>
|
||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
html, body { width: 100%; height: 100%; overflow: hidden; background: #000; }
|
html, body { width: 100%; height: 100%; overflow: hidden; background: #508cdc; }
|
||||||
canvas {
|
canvas {
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
+1
-1
@@ -84,7 +84,7 @@ export class Renderer {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const gl = this.gl;
|
const gl = this.gl;
|
||||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
gl.clearColor(0.31, 0.55, 0.86, 1.0);
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||||
gl.useProgram(this.program);
|
gl.useProgram(this.program);
|
||||||
gl.bindVertexArray(this.vao);
|
gl.bindVertexArray(this.vao);
|
||||||
|
|||||||
Reference in New Issue
Block a user