App Inventor 2 拖拽物体教程 - 按住移动与碰撞检测

« 返回首页

概述

已有文档Canvas游戏基础。本文聚焦拖拽物体的实现。

ImageSprite拖拽

方法一:Dragged事件

when 图像精灵1.Dragged(被拖动, 起X, 起Y, 当X, 当Y, 上X, 上Y) {
  if 被拖动 {
    图像精灵1.X = 图像精灵1.X + (当X - 上X)
    图像精灵1.Y = 图像精灵1.Y + (当Y - 上Y)
  }
}

注意:Dragged事件的坐标是相对于Canvas的,不是相对于Sprite的。需要计算偏移量。

方法二:Touched + Dragged(更精确)

global 正在拖拽 = false
global 偏移X = 0
global 偏移Y = 0

when 画布1.Touched(x, y, touchedAnySprite) {
  if touchedAnySprite {
    正在拖拽 = true
    偏移X = x - 图像精灵1.X
    偏移Y = y - 图像精灵1.Y
  }
}

when 画布1.Dragged(startX, startY, prevX, prevY, currentX, currentY, draggedAnySprite) {
  if 正在拖拽 and draggedAnySprite {
    图像精灵1.X = currentX - 偏移X
    图像精灵1.Y = currentY - 偏移Y
  }
}

when 画布1.TouchUp(x, y) {
  正在拖拽 = false
}

碰撞检测

Sprite与Sprite碰撞

when 图像精灵1.CollidedWith(other) {
  标签_状态.Text = "碰撞!"
  图像精灵1.Heading = 180 - 图像精灵1.Heading
}

Sprite与边界碰撞

when 图像精灵1.EdgeReached(edge) {
  图像精灵1.Bounce(edge)
}

自定义碰撞区域

function 矩形碰撞(x1, y1, w1, h1, x2, y2, w2, h2) {
  return x1 < x2 + w2 and x1 + w1 > x2 and y1 < y2 + h2 and y1 + h1 > y2
}

实战案例:拼图游戏

global 目标X = [50, 150, 50, 150]
global 目标Y = [50, 50, 150, 150]
global 吸附距离 = 30
global 完成数 = 0
global 当前拖拽索引 = 1

when 画布1.TouchUp(x, y) {
  正在拖拽 = false
  var 目标位置X = select(目标X, 当前拖拽索引)
  var 目标位置Y = select(目标Y, 当前拖拽索引)
  var 距离 = sqrt((x - 目标位置X) ^ 2 + (y - 目标位置Y) ^ 2)
  if 距离 < 吸附距离 {
    图像精灵1.X = 目标位置X
    图像精灵1.Y = 目标位置Y
    完成数 = 完成数 + 1
    if 完成数 = 4 {
      标签_状态.Text = "拼图完成!"
    }
  }
}

实战案例:地球围绕太阳旋转

global 角度 = 0
global 轨道半径 = 150
global 旋转速度 = 2
global 太阳X = 0
global 太阳Y = 0

when Screen1.Initialize() {
  太阳X = 画布1.Width / 2
  太阳Y = 画布1.Height / 2
}

when 计时器_旋转.Timer() {
  角度 = (角度 + 旋转速度) % 360
  var 弧度 = 角度 * 3.1415926 / 180
  var 地球X = 太阳X + 轨道半径 * cos(弧度)
  var 地球Y = 太阳Y + 轨道半径 * sin(弧度)
  图像精灵_地球.X = 地球X - 图像精灵_地球.Width / 2
  图像精灵_地球.Y = 地球Y - 图像精灵_地球.Height / 2
}

常见问题

Q1: 拖动时有跳跃?

确保在Touched时记录偏移量,Dragged时减去偏移量。

Q2: Sprite飞出Canvas边界?

// 限制Sprite在Canvas范围内
global 新X = max(0, min(画布1.Width - Sprite.Width, 新X))
global 新Y = max(0, min(画布1.Height - Sprite.Height, 新Y))
Sprite.X坐标 = 新X
Sprite.Y坐标 = 新Y

Q3: 多个Sprite同时拖动?

Canvas不支持多点触控拖动多个Sprite。只能同时拖一个。

总结

需求 方法
拖动Sprite Dragged事件 + 偏移量
碰撞检测 碰到事件 / 碰到点
轨道旋转 三角函数计算位置
吸附效果 距离判断 + 自动定位

版权声明:MIT App Inventor 官方文档采用 CC BY-SA 4.0 授权,本文档由 ai2claw 🐝 整理。

文档反馈