Bevy 拼图游戏开发实战

ZoOL 使用 Bevy 0.15 开发拼图游戏的完整记录。从图片分割算法到交互实现,涵盖了独立工具链 + Bevy 游戏逻辑的完整流程。

文章系列

篇目文件名日期核心内容
Day 1Bevy制作拼图游戏 Day 1.md2024-10-22拼图生成器:贝塞尔曲线、图片裁剪、透明处理
Day 4Bevy制作拼图游戏 Day 4.md2024-11-05拖拽交互、ESC取消、Z轴排序、选中效果
Day 5Bevy制作拼图游戏 Day 5.md2024-11-08性能优化、UI布局、相机缩放、背景提示

Day 1: 拼图生成器

核心算法

参考了 SVG 拼图生成器,每个拼图块(Piece)由四条边(Edge)组成:

  • 直边(StraightEdge)
  • 锯齿边(IndentedEdge): 三段二次贝塞尔曲线拼成
  • TabSize / Jitter 控制凸起方向和大小

技术栈

  • bezier-rs - 贝塞尔曲线计算
  • image / imageproc - 图像处理
  • glam - 数学计算

关键代码模式

// 1. 计算边缘轮廓
let contour_gen = EdgeContourGenerator::new(piece_width, piece_height, tab_size, jitter, seed);
 
// 2. 转为贝塞尔曲线
let sub_path: Subpath<PuzzleId> = Subpath::from_beziers(&beziers, true);
 
// 3. 计算包围盒
let [box_min, box_max] = piece.sub_path.bounding_box();
 
// 4. 裁剪图片
let mut piece_image = origin_image.view(top_left_x, top_left_y, width, height).to_image();
 
// 5. 并行透明处理
piece_image.par_enumerate_pixels_mut().for_each(|(x, y, pixel)| {
    let point = DVec2::new(top_left_x + x as f64, top_left_y + y as f64);
    if !piece.contains(point) { *pixel = Rgba([0, 0, 0, 0]) }
});

设计决策

  • 坐标系原点在图片左上角,x 朝右,y 朝下
  • 先缩放原图到固定尺寸(Lanczos3 滤波器)
  • 并行处理加速边缘透明化

Day 4: 拖拽交互与选中效果

拖拽实现

使用 Bevy 0.15 的 Pointer<DragStart> / Pointer<DragEnd> 触发器模式:

  • DragStart 时记录点击位置和当前变换
  • DragEnd 时触发 MoveEnd 事件
  • MoveStart 组件标记正在移动的实体

Z 轴排序

Bevy 2D 坐标系中 z 越高越靠前:

  • 初始生成时用拼图序号作为 z 值
  • 拖拽时将 z 改为 200
  • 放下时计算周围拼图的最大 z 值 + 1

选中效果

  • 切图时额外生成一张白色背景图
  • Selected 组件触发时,彩色图片左上偏移 4px,白色背景变黄色
  • MoveTogether 组件维护已连接的拼图块集合

工作绕

  • 0.15 rc 阶段 Sprite Picking 存在 bug,重叠时可能引发两次点击
  • 用 ESC 键盘处理作为备甦方案

Day 5: UI 与性能

性能优化

// 降低非聚焦时的 tick 频率
app.insert_resource(WinitSettings::desktop_app());

相机缩放

使用事件驱动架构(AdjustScale):

  • 键盘 PageUp/PageDown 触发
  • 滚轮触发
  • 统一处理系统限制范围 [0.5, 3.0]

UI 布局问题

  • 添加 UI 后 Sprite Picking 失效
  • 关联 issue: bevyengine/bevy#16342
  • 解决: 暂时移除 UI,用键盘实现功能

背景提示

  • ToggleBackgroundHint 事件切换背景原图可见性
  • 帮助玩家定位拼图位置

技术要点总结

  1. 图形算法: 贝塞尔曲线 + 并行图像处理
  2. ECS 交互: 触发器(Trigger) + 组件标记 + 事件驱动
  3. 性能: WinitSettings 桌面模式
  4. 缩放: 事件统一处理多种输入
  5. 层级管理: z 轴动态调整算法

文件位置

  • /Users/zool/workspace/ZoOL's Valut/Bevy制作拼图游戏 Day 1.md
  • /Users/zool/workspace/ZoOL's Valut/Bevy制作拼图游戏 Day 4.md
  • /Users/zool/workspace/ZoOL's Valut/Bevy制作拼图游戏 Day 5.md