概述
已有文档:canvas_game.md 介绍了Canvas游戏基础。本文聚焦拖拽物体的实现。
ImageSprite拖拽
方法一:Dragged事件
当 ImageSprite1.被拖动(被拖动, 起X, 起Y, 当X, 当Y, 上X, 上Y)
如果 被拖动
设 ImageSprite1.X坐标 = ImageSprite1.X坐标 + (当X - 上X)
设 ImageSprite1.Y坐标 = ImageSprite1.Y坐标 + (当Y - 上Y)
注意:Dragged事件的坐标是相对于Canvas的,不是相对于Sprite的。需要计算偏移量。
方法二:Touched + Moved(更精确)
设 正在拖拽 = false
设 偏移X = 0
设 偏移Y = 0
当 Canvas1.触摸按下(X, Y)
' 检查是否触摸到了Sprite
设 碰撞 = ImageSprite1.碰到点(X, Y)
如果 碰撞
设 正在拖拽 = true
设 偏移X = X - ImageSprite1.X坐标
设 偏移Y = Y - ImageSprite1.Y坐标
当 Canvas1.拖动(被拖动, 起X, 起Y, 当X, 当Y, 上X, 上Y)
如果 正在拖拽 且 被拖动
设 ImageSprite1.X坐标 = 当X - 偏移X
设 ImageSprite1.Y坐标 = 当Y - 偏移Y
当 Canvas1.触摸释放(X, Y)
设 正在拖拽 = false
碰撞检测
Sprite与Sprite碰撞
当 ImageSprite1.碰到(ImageSprite2)
' 碰撞触发
标签_状态.文本 = "碰撞!"
' 反弹效果
设 ImageSprite1.速度 = -ImageSprite1.速度
Sprite与边界碰撞
当 ImageSprite1.到达边界(边缘)
如果 边缘 = "左" 或 边缘 = "右"
设 ImageSprite1.水平方向 = -ImageSprite1.水平方向
否则 如果 边缘 = "上" 或 边缘 = "下"
设 ImageSprite1.垂直方向 = -ImageSprite1.垂直方向
自定义碰撞区域
定义 矩形碰撞(x1, y1, w1, h1, x2, y2, w2, h2) 返回 是否碰撞
如果 x1 < x2 + w2 且 x1 + w1 > x2 且 y1 < y2 + h2 且 y1 + h1 > y2
返回 true
返回 false
实战案例:拼图游戏
设 目标位置 = [
创建字典("x" → 50, "y" → 50),
创建字典("x" → 150, "y" → 50),
创建字典("x" → 50, "y" → 150),
创建字典("x" → 150, "y" → 150)
]
设 吸附距离 = 30
设 完成数 = 0
当 Canvas1.触摸释放(X, Y)
设 正在拖拽 = false
' 检查是否到达目标位置
设 i = 当前拖拽索引
设 目标X = 从字典 列表第i项(目标位置) 获取 "x"
设 目标Y = 从字典 列表第i项(目标位置) 获取 "y"
设 距离 = 数学.平方根((X-目标X)^2 + (Y-目标Y)^2)
如果 距离 < 吸附距离
' 吸附到目标位置
设 当前Sprite.X坐标 = 目标X
设 当前Sprite.Y坐标 = 目标Y
设 完成数 = 完成数 + 1
如果 完成数 = 4
标签_状态.文本 = "🎉 拼图完成!"
实战案例:地球围绕太阳旋转
设 角度 = 0
设 轨道半径 = 150
设 太阳X = Canvas1.宽度 / 2
设 太阳Y = Canvas1.高度 / 2
设 旋转速度 = 2 ' 度/帧
当 Clock_旋转.计时
设 角度 = (角度 + 旋转速度) 模 360
设 弧度 = 角度 * 数学.PI / 180
设 地球X = 太阳X + 轨道半径 * 数学.余弦(弧度)
设 地球Y = 太阳Y + 轨道半径 * 数学.正弦(弧度)
' 更新地球位置
设 ImageSprite_地球.X坐标 = 地球X - ImageSprite_地球.宽度/2
设 ImageSprite_地球.Y坐标 = 地球Y - ImageSprite_地球.高度/2
' 绘制轨道线(可选)
调用 Canvas1.清除()
调用 Canvas1.画圆(太阳X, 太阳Y, 轨道半径, 灰色)
常见问题
Q1: 拖动时有跳跃?
确保在Touched时记录偏移量,Dragged时减去偏移量。
Q2: Sprite飞出Canvas边界?
' 限制Sprite在Canvas范围内
设 新X = 数学.最大值(0, 数学.最小值(Canvas1.宽度 - Sprite.宽度, 新X))
设 新Y = 数学.最大值(0, 数学.最小值(Canvas1.高度 - Sprite.高度, 新Y))
设 Sprite.X坐标 = 新X
设 Sprite.Y坐标 = 新Y
Q3: 多个Sprite同时拖动?
Canvas不支持多点触控拖动多个Sprite。只能同时拖一个。
总结
| 需求 | 方法 |
|---|---|
| 拖动Sprite | Dragged事件 + 偏移量 |
| 碰撞检测 | 碰到事件 / 碰到点 |
| 轨道旋转 | 三角函数计算位置 |
| 吸附效果 | 距离判断 + 自动定位 |
版权声明:MIT App Inventor 官方文档采用 CC BY-SA 4.0 授权,本文档由 ai2claw 🐝 整理。
扫码添加客服咨询