const canvas = document.getElementById('sand'); const ctx = canvas.getContext('2d'); canvas.width = window.innerWidth - 12; canvas.height = window.innerHeight - 12; const gridSize = 10; const gridWidth = Math.floor(canvas.width / gridSize); const gridHeight = Math.floor(canvas.height / gridSize); const grid = Array(gridHeight).fill().map(() => Array(gridWidth).fill(0)); let mouseDown = false; canvas.addEventListener('mousedown', (e) => { mouseDown = true; addSand(e); }); canvas.addEventListener('mouseup', () => { mouseDown = false; }); canvas.addEventListener('mousemove', (e) => { if (mouseDown) { addSand(e); } }); function addSand(e) { const rect = canvas.getBoundingClientRect(); const x = Math.floor((e.clientX - rect.left) / gridSize); const y = Math.floor((e.clientY - rect.top) / gridSize); if (x >= 0 && x < gridWidth && y >= 0 && y < gridHeight) { grid[y][x] = 1; } } const updateGrid = () => { for (let y = gridHeight - 2; y >= 0; y--) { for (let x = 0; x < gridWidth; x++) { if (grid[y][x] === 1) { if (grid[y + 1][x] === 0) { grid[y][x] = 0; grid[y + 1][x] = 1; } else if (x > 0 && grid[y + 1][x - 1] === 0) { grid[y][x] = 0; grid[y + 1][x - 1] = 1; } else if (x < gridWidth - 1 && grid[y + 1][x + 1] === 0) { grid[y][x] = 0; grid[y + 1][x + 1] = 1; } } } } }; const drawGrid = () => { // Clear the canvas ctx.fillStyle = 'beige'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Draw the sand ctx.fillStyle = 'black'; for (let y = 0; y < gridHeight; y++) { for (let x = 0; x < gridWidth; x++) { if (grid[y][x] === 1) { ctx.fillRect(x * gridSize, y * gridSize, gridSize, gridSize); } } } }; const animate = () => { updateGrid(); drawGrid(); requestAnimationFrame(animate); }; animate();