feat: Add new materials (dirt, stone, grass, wood) with unique behaviors
This commit is contained in:
parent
a6f0baf02c
commit
6ad564eea0
@ -12,6 +12,10 @@
|
||||
<div class="tools">
|
||||
<button id="sand-btn" class="active">Sand</button>
|
||||
<button id="water-btn">Water</button>
|
||||
<button id="dirt-btn">Dirt</button>
|
||||
<button id="stone-btn">Stone</button>
|
||||
<button id="grass-btn">Grass</button>
|
||||
<button id="wood-btn">Wood</button>
|
||||
<button id="eraser-btn">Eraser</button>
|
||||
</div>
|
||||
<div class="navigation">
|
||||
|
99
script.js
99
script.js
@ -6,12 +6,20 @@ const WATER_SPREAD = 3;
|
||||
const SAND_COLOR = '#e6c588';
|
||||
const WATER_COLOR = '#4a80f5';
|
||||
const WALL_COLOR = '#888888';
|
||||
const DIRT_COLOR = '#8B4513';
|
||||
const STONE_COLOR = '#A9A9A9';
|
||||
const GRASS_COLOR = '#7CFC00';
|
||||
const WOOD_COLOR = '#8B5A2B';
|
||||
|
||||
// Element types
|
||||
const EMPTY = 0;
|
||||
const SAND = 1;
|
||||
const WATER = 2;
|
||||
const WALL = 3;
|
||||
const DIRT = 4;
|
||||
const STONE = 5;
|
||||
const GRASS = 6;
|
||||
const WOOD = 7;
|
||||
|
||||
// Global variables
|
||||
let canvas, ctx;
|
||||
@ -41,6 +49,10 @@ window.onload = function() {
|
||||
// Tool selection
|
||||
document.getElementById('sand-btn').addEventListener('click', () => setTool(SAND));
|
||||
document.getElementById('water-btn').addEventListener('click', () => setTool(WATER));
|
||||
document.getElementById('dirt-btn').addEventListener('click', () => setTool(DIRT));
|
||||
document.getElementById('stone-btn').addEventListener('click', () => setTool(STONE));
|
||||
document.getElementById('grass-btn').addEventListener('click', () => setTool(GRASS));
|
||||
document.getElementById('wood-btn').addEventListener('click', () => setTool(WOOD));
|
||||
document.getElementById('eraser-btn').addEventListener('click', () => setTool(EMPTY));
|
||||
|
||||
// Navigation controls
|
||||
@ -81,6 +93,14 @@ function setTool(tool) {
|
||||
document.getElementById('sand-btn').classList.add('active');
|
||||
} else if (tool === WATER) {
|
||||
document.getElementById('water-btn').classList.add('active');
|
||||
} else if (tool === DIRT) {
|
||||
document.getElementById('dirt-btn').classList.add('active');
|
||||
} else if (tool === STONE) {
|
||||
document.getElementById('stone-btn').classList.add('active');
|
||||
} else if (tool === GRASS) {
|
||||
document.getElementById('grass-btn').classList.add('active');
|
||||
} else if (tool === WOOD) {
|
||||
document.getElementById('wood-btn').classList.add('active');
|
||||
} else if (tool === EMPTY) {
|
||||
document.getElementById('eraser-btn').classList.add('active');
|
||||
}
|
||||
@ -317,7 +337,7 @@ function updatePhysics() {
|
||||
const index = y * CHUNK_SIZE + x;
|
||||
const type = chunk[index];
|
||||
|
||||
if (type === EMPTY) continue;
|
||||
if (type === EMPTY || type === STONE || type === WOOD) continue;
|
||||
|
||||
const worldX = chunkX * CHUNK_SIZE + x;
|
||||
const worldY = chunkY * CHUNK_SIZE + y;
|
||||
@ -326,6 +346,10 @@ function updatePhysics() {
|
||||
updateSand(worldX, worldY);
|
||||
} else if (type === WATER) {
|
||||
updateWater(worldX, worldY);
|
||||
} else if (type === DIRT) {
|
||||
updateDirt(worldX, worldY);
|
||||
} else if (type === GRASS) {
|
||||
updateGrass(worldX, worldY);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -354,6 +378,71 @@ function updateSand(x, y) {
|
||||
}
|
||||
}
|
||||
|
||||
function updateDirt(x, y) {
|
||||
// Try to move down
|
||||
if (getPixel(x, y + 1) === EMPTY) {
|
||||
setPixel(x, y, EMPTY);
|
||||
setPixel(x, y + 1, DIRT);
|
||||
}
|
||||
// Try to move down-left or down-right
|
||||
else if (getPixel(x - 1, y + 1) === EMPTY) {
|
||||
setPixel(x, y, EMPTY);
|
||||
setPixel(x - 1, y + 1, DIRT);
|
||||
}
|
||||
else if (getPixel(x + 1, y + 1) === EMPTY) {
|
||||
setPixel(x, y, EMPTY);
|
||||
setPixel(x + 1, y + 1, DIRT);
|
||||
}
|
||||
// Dirt can displace water
|
||||
else if (getPixel(x, y + 1) === WATER) {
|
||||
setPixel(x, y, WATER);
|
||||
setPixel(x, y + 1, DIRT);
|
||||
}
|
||||
|
||||
// Dirt can turn into grass if exposed to air above
|
||||
if (getPixel(x, y - 1) === EMPTY && Math.random() < 0.001) {
|
||||
setPixel(x, y, GRASS);
|
||||
}
|
||||
}
|
||||
|
||||
function updateGrass(x, y) {
|
||||
// Grass behaves like dirt for physics
|
||||
if (getPixel(x, y + 1) === EMPTY) {
|
||||
setPixel(x, y, EMPTY);
|
||||
setPixel(x, y + 1, GRASS);
|
||||
}
|
||||
else if (getPixel(x - 1, y + 1) === EMPTY) {
|
||||
setPixel(x, y, EMPTY);
|
||||
setPixel(x - 1, y + 1, GRASS);
|
||||
}
|
||||
else if (getPixel(x + 1, y + 1) === EMPTY) {
|
||||
setPixel(x, y, EMPTY);
|
||||
setPixel(x + 1, y + 1, GRASS);
|
||||
}
|
||||
else if (getPixel(x, y + 1) === WATER) {
|
||||
setPixel(x, y, WATER);
|
||||
setPixel(x, y + 1, GRASS);
|
||||
}
|
||||
|
||||
// Grass can spread to nearby dirt
|
||||
if (Math.random() < 0.0005) {
|
||||
const directions = [
|
||||
{dx: -1, dy: 0}, {dx: 1, dy: 0},
|
||||
{dx: 0, dy: -1}, {dx: 0, dy: 1}
|
||||
];
|
||||
|
||||
const dir = directions[Math.floor(Math.random() * directions.length)];
|
||||
if (getPixel(x + dir.dx, y + dir.dy) === DIRT) {
|
||||
setPixel(x + dir.dx, y + dir.dy, GRASS);
|
||||
}
|
||||
}
|
||||
|
||||
// Grass dies if covered (no air above)
|
||||
if (getPixel(x, y - 1) !== EMPTY && Math.random() < 0.05) {
|
||||
setPixel(x, y, DIRT);
|
||||
}
|
||||
}
|
||||
|
||||
function updateWater(x, y) {
|
||||
// Try to move down
|
||||
if (getPixel(x, y + 1) === EMPTY) {
|
||||
@ -472,6 +561,14 @@ function render() {
|
||||
ctx.fillStyle = WATER_COLOR;
|
||||
} else if (type === WALL) {
|
||||
ctx.fillStyle = WALL_COLOR;
|
||||
} else if (type === DIRT) {
|
||||
ctx.fillStyle = DIRT_COLOR;
|
||||
} else if (type === STONE) {
|
||||
ctx.fillStyle = STONE_COLOR;
|
||||
} else if (type === GRASS) {
|
||||
ctx.fillStyle = GRASS_COLOR;
|
||||
} else if (type === WOOD) {
|
||||
ctx.fillStyle = WOOD_COLOR;
|
||||
}
|
||||
|
||||
// Draw the pixel
|
||||
|
Loading…
x
Reference in New Issue
Block a user