ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

落沙模拟器:一画布装下沙、水、火、植物,看颗粒自己活起来

落沙模拟器:一画布装下沙、水、火、植物,看颗粒自己活起来

落沙模拟器:一画布装下沙、水、火、植物,看颗粒自己"活"起来

一句话需求丢给码道,自动生成一个网页版落沙模拟器(Falling Sand)——220×150 的颗粒世界里,沙子堆叠、水流淌、火向上窜、植物会生长,八种材料互相反应,按住鼠标拖一拖,就是一个会"活"的微观世界。双击 index.html 就能玩,零依赖。

分类: ai-development
标签: CodeArts, AI编程, 落沙模拟器, 颗粒系统, 网页游戏
难度: 初级
读者: 前端开发者、游戏爱好者、物理模拟爱好者


1. 开头钩子

小时候玩过一个叫"落沙"的网页小游戏:用鼠标画出沙子,看着它哗啦啦堆成山,再画一汪水,看它顺着坡流下去。这次我把这个童年记忆丢给码道 TUI:「做一个网页版落沙模拟器」,几分钟后它交出了一个单文件 index.html——沙子、水、油、木头、火、植物、石头、蒸汽八种材料,落体、流动、燃烧、蒸发、凝结、生长一条完整的反应链,全部跑在一个 220×150 的 canvas 里。按住鼠标拖一下,沙丘堆起来了,倒点水上去,水顺着沙坡流到低处,再点一把火,木头烧起来、火焰往上窜……整个过程像看一场微观世界的纪录片。


2. 码道 TUI 安装

码道 CLI 官方提供 WindowsmacOS/Linux 两种安装方式,按自己的系统选一种即可。

Windows(仅支持在 PowerShell 执行)

# 1. 一键安装
irm https://cnnorth4-cloudide-marketplace.obs.cn-north-4.myhuaweicloud.com/codearts/cli_tui/install_script/install.ps1 | iex# 2. 配置环境变量
$env:CODEARTS_CLI_AK="你的AK"
$env:CODEARTS_CLI_SK="你的SK"# 3. 启动 TUI
codearts

macOS / Linux(终端)

# 1. 一键安装
sh -c "$(curl -L https://cnnorth4-cloudide-marketplace.obs.cn-north-4.myhuaweicloud.com/codearts/cli_tui/install_script/install.sh)"# 2. 配置环境变量
export PATH=~/.codeartsdoer/installers:$PATH
export CODEARTS_CLI_AK=你的AK
export CODEARTS_CLI_SK=你的SK# 3. 启动 TUI
codearts

安装成功后终端会回显码道 CLI 的版本号。在 PowerShell 或终端里输入 codearts 回车,即可打开码道 TUI,把开发需求贴进输入框。

AK/SK 获取:https://codearts.huaweicloud.com/portal/settings/cli-auth

👉 还没有码道?立即开通体验:https://developer.huaweicloud.com/codeartsco.html?source=dmzntgwsf&sourcead=dmzntgwwbwz


3. 码道能力一览

  • 颗粒物理引擎:沙子落体堆叠、水流向低处、油浮于水、火焰上升,全部用网格状态机实现
  • 完整反应链:火点燃木头/植物/油 → 水浇灭火并生成蒸汽 → 蒸汽上升后凝结回水 → 植物吸水向空格生长
  • 细腻渲染:220×150 网格 + ImageData 像素直写 + 4 倍放大(pixelated),每格固定噪声营造颗粒质感
  • 顺手交互:八种材料按钮、画笔大小滑块、暂停/继续、清空画布,空格暂停、C 键清空
  • 性能在线:自底向上扫描 + moved 标记避免重复移动,左右方向随机化消除偏向,稳定 60fps
  • 单文件交付:HTML/CSS/JS 全在一个 index.html 里,双击即用、零依赖

4. 任务描述

需求就一段话,丢进码道 TUI 的输入框:

做一个网页版落沙模拟器(Falling Sand),单文件 index.html(内嵌 CSS 和 JS)。用 canvas 模拟可交互的颗粒世界:鼠标按住拖动画出沙子、水、火、植物等不同材料,颗粒会下落、流动、扩散并相互反应(水往低处流、沙子堆叠、火向上燃烧并点燃木头、水浇灭火、植物生长)。支持切换材料、调整画笔大小、暂停/继续、清空画布;界面好看:深色背景、细腻的颗粒渲染、流畅的帧率。


5. 开发过程及真实截图

需求输入

生成过程

生成结果

running

码道从提交需求到生成完成,直接输出一个可运行的 index.html,并给出能力清单:八种材料、落体/流动/燃烧/蒸发/凝结/生长反应链、220×150 网格像素渲染、画笔与暂停/清空控制,直接打开浏览器就能上手玩。


6. 代码解析(从项目源码提取)

沙子的"落体"逻辑。每个颗粒先看正下方,空了就掉下去;下方被占就随机往左下或右下斜滑,还会"挤开"水和油往下沉——这样沙堆才会自然形成坡面:

function updateSand(x, y) {const b = get(x, y + 1);if (b === EMPTY || b === WATER || b === OIL) { swap(x, y, x, y + 1); return; }const d = Math.random() < 0.5 ? -1 : 1;const dl = get(x + d, y + 1);if (dl === EMPTY || dl === WATER || dl === OIL) { swap(x, y, x + d, y + 1); return; }const dr = get(x - d, y + 1);if (dr === EMPTY || dr === WATER || dr === OIL) { swap(x, y, x - d, y + 1); return; }
}

火与反应链。火焰每帧检查周围八格:碰到水或蒸汽就熄灭并变成蒸汽;碰到木头/植物/油则按概率点燃;火焰有寿命,烧尽后可能留下一缕蒸汽——"水浇灭火"变成看得见的物理过程:

function updateFire(x, y) {const p = idx(x, y);let extinguish = false;for (let dy = -1; dy <= 1; dy++) {for (let dx = -1; dx <= 1; dx++) {if (!dx && !dy) continue;const nx = x + dx, ny = y + dy;if (!inB(nx, ny)) continue;const n = grid[idx(nx, ny)];if (n === WATER || n === STEAM) extinguish = true;else if (n === WOOD && Math.random() < 0.035) setCell(nx, ny, FIRE, 60 + (Math.random()*40|0));else if (n === PLANT && Math.random() < 0.08) setCell(nx, ny, FIRE, 35 + (Math.random()*25|0));else if (n === OIL && Math.random() < 0.22) setCell(nx, ny, FIRE, 50 + (Math.random()*40|0));}}if (extinguish) { setCell(x, y, STEAM, 70 + (Math.random()*30|0)); return; }life[p]--;if (life[p] <= 0) { ... }// 火焰向上漂移const above = get(x, y - 1);if (above === EMPTY && Math.random() < 0.7) { swap(x, y, x, y - 1); return; }
}

主循环:自底向上 + 随机方向。每帧从最后一行往上扫,moved 标记保证每个颗粒一帧只移动一次;每行再随机决定从左还是从右扫,避免所有颗粒统一偏向一侧——沙堆左右才对称:

function step() {moved.fill(0);for (let y = H - 1; y >= 0; y--) {const ltr = Math.random() < 0.5;for (let i = 0; i < W; i++) {const x = ltr ? i : (W - 1 - i);const p = idx(x, y);if (moved[p]) continue;switch (grid[p]) {case SAND: updateSand(x, y); break;case WATER: updateWater(x, y); break;case FIRE: updateFire(x, y); break;case PLANT: updatePlant(x, y); break;case STEAM: updateSteam(x, y); break;}}}
}

画笔的颗粒感paint 用圆形笔刷,并按材料密度做概率放置——密度越低的材料越稀疏,画出来的沙带有天然颗粒感而不是整块糊状:

function paint(gx, gy) {const r = brushSize, mat = currentMat, dens = DENSITY[mat] || 1;for (let dy = -r; dy <= r; dy++) {for (let dx = -r; dx <= r; dx++) {if (dx*dx + dy*dy > r*r) continue;const x = gx + dx, y = gy + dy;if (!inB(x, y)) continue;const p = idx(x, y);if (mat === EMPTY) { grid[p] = 0; life[p] = 0; continue; }if (Math.random() > dens) continue;if (grid[p] === EMPTY || grid[p] === WATER || grid[p] === SAND || grid[p] === OIL) {grid[p] = mat;life[p] = mat === FIRE ? (60 + (Math.random()*40|0)) : 0;}}}
}

7. 真实运行效果

双击 index.html 打开:左侧工具栏列出沙、水、油、木、火、植物、石、橡皮八种材料,右侧滑块调画笔大小(1–14)。按住鼠标在画布上拖一条线,沙粒立刻落下堆成山丘;把材料切成"水",在沙丘顶上倒一注,蓝色水流顺着坡面流到低处、被沙堆截出分支;再切"火"点一下木头,火苗向上窜动并引燃相邻的植物和油,倒水上去"呲"地变成蒸汽,蒸汽上升后凝回水珠。右上角 HUD 实时显示当前材料、粒子数和 FPS,空格暂停、C 清空,随时重来。


8. 能力总结

亮点 说明
八种材料 沙、水、油、木、火、植物、石、蒸汽 + 橡皮,颗粒世界要素齐全
真实反应链 燃烧、熄灭、蒸发、凝结、生长闭环,物理过程一目了然
颗粒物理 落体、斜滑、流动、浮力、向上漂移,行为自然不僵硬
细腻渲染 220×150 网格像素直写 + 4 倍放大 + 噪声颗粒质感
性能优化 自底向上扫描、moved 去重、方向随机化,稳定 60fps
零依赖交付 单文件 index.html,双击即用

9. 总结

这次用码道 TUI 做落沙模拟器,最惊喜的是"一句话把童年记忆变成能玩的程序":没有复杂的物理引擎依赖,码道用一张网格 + 一套状态机就把沙子、水、火、植物之间的互动讲得清清楚楚,还顺手做了像素渲染和 60fps 优化。如果你也想试试这种"一句话出一个能玩的微观世界",装好码道 TUI 后,把想法描述清楚丢进去就行。可以免费开通体验版:https://developer.huaweicloud.com/codeartsco.html?source=dmzntgwsf&sourcead=dmzntgwwbwz

返回列表