返回
Swift 游戏开发之黎锦拼图(二)
IOS
2024-02-04 16:20:51
Swift 游戏开发之黎锦拼图(二)
在上一篇文章中,我们完成了对拼图元素的拆分和基本拖拽的用户操作逻辑。现在我们先来补充完整当用户拖拽拼图元素时的逻辑。在现实生活中,拼图游戏总是被「禁固」在一个确定画布上,玩家只能在这个画布中发挥自己的想象力,恢复拼图。因此,我们也需要在画布上给用户限定一个「区域」。从之前的两张图片中,我们可以看到,画布其实是有边界的,一旦拼图元素超出这个边界,我们就需要将拼图元素给拉回来。
具体地,当用户拖拽拼图元素超出画布边界时,我们需要判断拼图元素超出边界的距离,然后将拼图元素拉回画布边界上距离最近的点。这个距离的计算可以采用勾股定理来实现。
func clampPosition(position: CGPoint, inBounds bounds: CGRect) -> CGPoint {
let x = max(bounds.minX, min(position.x, bounds.maxX))
let y = max(bounds.minY, min(position.y, bounds.maxY))
return CGPoint(x: x, y: y)
}
有了这个方法,我们就可以在拼图元素的拖拽事件中,对拼图元素的位置进行限制了。
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let position = touch.location(in: self)
let clampedPosition = clampPosition(position: position, inBounds: bounds)
// ... 其余代码
}
接下来,我们还需要处理拼图元素之间的碰撞检测。当两个拼图元素碰撞时,我们需要将碰撞的拼图元素弹开。碰撞检测的原理很简单,就是计算两个拼图元素的中心点之间的距离,如果距离小于两个拼图元素的半径之和,则认为两个拼图元素发生了碰撞。
func isCollided(puzzlePiece1: PuzzlePiece, puzzlePiece2: PuzzlePiece) -> Bool {
let distance = sqrt(pow(puzzlePiece1.center.x - puzzlePiece2.center.x, 2) + pow(puzzlePiece1.center.y - puzzlePiece2.center.y, 2))
return distance < (puzzlePiece1.radius + puzzlePiece2.radius)
}
有了这个方法,我们就可以在拼图元素的拖拽事件中,对拼图元素之间的碰撞进行检测了。如果检测到碰撞,则将碰撞的拼图元素弹开。
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let position = touch.location(in: self)
let clampedPosition = clampPosition(position: position, inBounds: bounds)
// ... 其余代码
for puzzlePiece in puzzlePieces {
if puzzlePiece != self && isCollided(puzzlePiece1: self, puzzlePiece2: puzzlePiece) {
// ... 处理碰撞逻辑
}
}
}
至此,我们完成了对拼图元素拖拽时的所有逻辑处理。下一篇文章,我们将继续完善拼图游戏的其他功能,敬请期待!