如何在标签和图像之间创建碰撞检测
How to create a Collision Detection between a label and an Image
前言
我想创建一个简单的游戏,您应该可以在其中拖动标签,如果将其拖动到正确的位置,您就赢了。更具体地说:这是一款帮助自闭症儿童的游戏。在这个游戏中,他们必须创建从 1 到 10 的正确数字序列,将带有数字的标签拖到正确的位置(实际上是图像)。现在你会更好地理解:
问题
我已经创建了拖动标签的代码(使用平移手势识别器),但我不知道如何创建碰撞检测:当卡片“1”被拖动并与蓝色图像发生碰撞时“1”有事发生,
我的心理代码是:
if LB_1 *collides with* IMG_1 {
self.IMG_1?.backgroundColor = UIColor.green
}
我希望问题很清楚。
啊我不使用 SpriteKit。我使用 "SingleViewApplication" 作为模板而不是 "Game"。
您可以检查它们的框架是否相交。
CGRect
有方法 intersects.
所以你的 if 语句应该如下:
if LB_1.frame.intersects(IMG_1.frame) {
self.IMG_1?.backgroundColor = UIColor.green
}
如果这对你来说还不够,你可以计算intersection rect的面积。
您想使用 contains()
。如果你使用 intersects()
那么一旦两个矩形接触它就会 return 为真。使用 contains()
,直到拖动的视图完全在目标视图内,它才会 return 为真,这似乎更直观。
我刚刚编写了一个实现此功能的示例应用程序,并且运行良好。
我创建了一个简单的 UIView 子class,我称之为 BoxedView,它只是在它的图层周围设置了一个边框,以便您可以看到它。
我设置了一个视图控制器,其中包含 2 个盒装视图、一个较大的 "targetView" 和一个用户可以拖动的较小视图。
我的手势识别器的 target/action 在用户拖动时移动拖动视图的框架,如果目标视图包含拖动视图,它会设置一个 Bool highlightTargetView,这会导致目标视图周围的框得到更厚。
整个视图控制器 class' 代码如下所示:
class ViewController: UIViewController {
@IBOutlet weak var targetView: BoxedView!
var viewStartingFrame: CGRect = CGRect.zero
var highlightTargetView: Bool = false {
didSet {
targetView.layer.borderWidth = highlightTargetView ? 5 : 1
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func userDraggedView(_ gesture: UIPanGestureRecognizer) {
switch gesture.state {
case .began:
viewStartingFrame = gesture.view?.frame ?? CGRect.zero
case .changed:
let offset = gesture.translation(in: view)
gesture.view?.frame = viewStartingFrame.offsetBy(dx: offset.x, dy: offset.y)
highlightTargetView = targetView.frame.contains(gesture.view?.frame ?? CGRect.zero)
case .ended:
gesture.view?.frame = viewStartingFrame
highlightTargetView = false
default:
break
}
}
}
为了数学运算,我使用了两个视图的框架 属性,它位于父视图的坐标系中(在这种情况下,父视图是视图控制器的内容视图,但关键是我们比较两个使用相同坐标系的矩形。)如果你使用任一视图的边界 属性 你的数学将不起作用,因为视图的 bounds
在该视图的局部坐标系。
下面是程序在 运行:
时的样子
为了比较,我修改了程序以使用 intersects()
函数也显示它的样子,并创建了一个视频来展示它的样子:
前言
我想创建一个简单的游戏,您应该可以在其中拖动标签,如果将其拖动到正确的位置,您就赢了。更具体地说:这是一款帮助自闭症儿童的游戏。在这个游戏中,他们必须创建从 1 到 10 的正确数字序列,将带有数字的标签拖到正确的位置(实际上是图像)。现在你会更好地理解:
问题
我已经创建了拖动标签的代码(使用平移手势识别器),但我不知道如何创建碰撞检测:当卡片“1”被拖动并与蓝色图像发生碰撞时“1”有事发生, 我的心理代码是:
if LB_1 *collides with* IMG_1 {
self.IMG_1?.backgroundColor = UIColor.green
}
我希望问题很清楚。 啊我不使用 SpriteKit。我使用 "SingleViewApplication" 作为模板而不是 "Game"。
您可以检查它们的框架是否相交。
CGRect
有方法 intersects.
所以你的 if 语句应该如下:
if LB_1.frame.intersects(IMG_1.frame) {
self.IMG_1?.backgroundColor = UIColor.green
}
如果这对你来说还不够,你可以计算intersection rect的面积。
您想使用 contains()
。如果你使用 intersects()
那么一旦两个矩形接触它就会 return 为真。使用 contains()
,直到拖动的视图完全在目标视图内,它才会 return 为真,这似乎更直观。
我刚刚编写了一个实现此功能的示例应用程序,并且运行良好。
我创建了一个简单的 UIView 子class,我称之为 BoxedView,它只是在它的图层周围设置了一个边框,以便您可以看到它。
我设置了一个视图控制器,其中包含 2 个盒装视图、一个较大的 "targetView" 和一个用户可以拖动的较小视图。
我的手势识别器的 target/action 在用户拖动时移动拖动视图的框架,如果目标视图包含拖动视图,它会设置一个 Bool highlightTargetView,这会导致目标视图周围的框得到更厚。
整个视图控制器 class' 代码如下所示:
class ViewController: UIViewController {
@IBOutlet weak var targetView: BoxedView!
var viewStartingFrame: CGRect = CGRect.zero
var highlightTargetView: Bool = false {
didSet {
targetView.layer.borderWidth = highlightTargetView ? 5 : 1
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func userDraggedView(_ gesture: UIPanGestureRecognizer) {
switch gesture.state {
case .began:
viewStartingFrame = gesture.view?.frame ?? CGRect.zero
case .changed:
let offset = gesture.translation(in: view)
gesture.view?.frame = viewStartingFrame.offsetBy(dx: offset.x, dy: offset.y)
highlightTargetView = targetView.frame.contains(gesture.view?.frame ?? CGRect.zero)
case .ended:
gesture.view?.frame = viewStartingFrame
highlightTargetView = false
default:
break
}
}
}
为了数学运算,我使用了两个视图的框架 属性,它位于父视图的坐标系中(在这种情况下,父视图是视图控制器的内容视图,但关键是我们比较两个使用相同坐标系的矩形。)如果你使用任一视图的边界 属性 你的数学将不起作用,因为视图的 bounds
在该视图的局部坐标系。
下面是程序在 运行:
时的样子为了比较,我修改了程序以使用 intersects()
函数也显示它的样子,并创建了一个视频来展示它的样子: