about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--js/sand/index.html29
-rw-r--r--js/sand/sand.js78
2 files changed, 107 insertions, 0 deletions
diff --git a/js/sand/index.html b/js/sand/index.html
new file mode 100644
index 0000000..76beee4
--- /dev/null
+++ b/js/sand/index.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>sand</title>
+    <style>
+        body, html {
+            margin: 0;
+            padding: 0;
+            height: 100%;
+            width: 100%;
+            overflow: hidden;
+        }
+
+        #sand {
+            position: absolute;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
+        }
+    </style>
+</head>
+<body>
+    <canvas id="sand"></canvas>
+    <script src="sand.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/js/sand/sand.js b/js/sand/sand.js
new file mode 100644
index 0000000..65e87bd
--- /dev/null
+++ b/js/sand/sand.js
@@ -0,0 +1,78 @@
+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();
\ No newline at end of file