如何创建与Swift UIDynamics绑定的圆形碰撞?

时间:2018-04-03 14:05:09

标签: swift collision-detection uibezierpath cashapelayer bounds

此帖子已修改为包含屏幕截图和代码 ...

尝试解决这个问题需要四天时间,所以有人可以清楚地指出我的实施有什么问题吗?这是我的第一次大声笑。

请看下面的截图。

-I'我正在使用UIKit Dynamics并试图将这3个较小的球捕获到较大球的 ROUND 范围内,但它们只被保留在较大球的范围内#39; s矩形。

enter image description here

以下是相关代码:

大型泡泡在IB中创建,并在我的班级中声明:

@IBOutlet weak var homeMainBubble: UIButton!

var gravity: UIGravityBehavior!
var animator: UIDynamicAnimator!
var collision: UICollisionBehavior!

var ballOne : UIImageView!
var ballTwo : UIImageView!
var ballThree : UIImageView!

var circlePath : UIBezierPath!


    override func viewDidAppear(_ animated: Bool) {

    circlePath = UIBezierPath(arcCenter: CGPoint(x: homeMainBubble.frame.midX,y: homeMainBubble.frame.midY), radius: homeMainBubble.frame.width/2, startAngle: CGFloat(0), endAngle:CGFloat(Double.pi * 2), clockwise: true)}

viewDidAppear()中,我创建了一个UIBezierPath()

//Adds or removes fake balls inside 'mainBubble()' when swiped up or down---------------------
func addOrRemoveFakeBalls(fakeBalls: String) {

    let ballOneIs = positionOneBubble()
    let ballImages = ["playBubble", "statsBubble", "settingsBubble", "cheatsBubble"]

    let ballOneImage = ballImages[ballOneIs.tag - 1] //Determines the image to used for 'fake ball 1' based on the bubble in position one
    var ballTwoImage : String = ""
    var ballThreeImage : String = ""

    if ballOneImage == "playBubble" { //Derivitive from ballOneImage, this determines the ball to the left & ensures correct array looping.
        ballTwoImage = ballImages[3]
    } else {ballTwoImage = ballImages[ballOneIs.tag - 2]}

    if ballOneImage == "cheatsBubble" { //Derivitive from ballOneImage, this determines the ball to the right & ensures correct array looping.
        ballThreeImage = ballImages[0]
    } else {ballThreeImage = ballImages[ballOneIs.tag]}

    switch fakeBalls {
    case "Add":
        ballOne = Ellipse(frame: CGRect(x: 125, y: 50, width: largeBubbleWidth, height: largeBubbleWidth))
        ballOne.image = UIImage(named: ballOneImage)
        ballOne.layer.zPosition = 1
        ballOne.alpha = 0.3
        ballTwo = Ellipse(frame: CGRect(x: 100, y: 50, width: mediumBubbleWidth, height: mediumBubbleWidth))
        ballTwo.image = UIImage(named: ballTwoImage)
        ballTwo.layer.zPosition = 1
        ballTwo.alpha = 0.3
        ballThree = Ellipse(frame: CGRect(x: 150, y: 50, width: mediumBubbleWidth, height: mediumBubbleWidth))
        ballThree.image = UIImage(named: ballThreeImage)
        ballThree.layer.zPosition = 1
        ballThree.alpha = 0.3

        homeMainBubble.addSubview(ballOne)
        homeMainBubble.addSubview(ballTwo)
        homeMainBubble.addSubview(ballThree)

        animator = UIDynamicAnimator(referenceView: homeMainBubble)

        gravity = UIGravityBehavior(items: [ballOne, ballTwo, ballThree])
        gravity.magnitude = 1
        animator.addBehavior(gravity)

        collision = UICollisionBehavior(items: [ballOne, ballTwo, ballThree])

        collision.addBoundary(withIdentifier: "Circle" as NSCopying, for: circlePath)

        collision.collisionDelegate = self


       collision.translatesReferenceBoundsIntoBoundary = true

        animator.addBehavior(collision)

    case "Remove":

        animator.removeAllBehaviors()
        gravity.removeItem(ballOne)
        gravity.removeItem(ballTwo)
        gravity.removeItem(ballThree)
        collision.removeAllBoundaries()
        ballOne.removeFromSuperview()
        ballTwo.removeFromSuperview()
        ballThree.removeFromSuperview()

    default: break
    }

}

我暂时添加了collision.translatesReferenceBoundsIntoBoundary = true,这样球就不会从屏幕上掉下来,但是随着这一点被注释掉,为什么“圆圈路径”会被删除。 UIBezierPath()里面没有我的小球?

我几乎尝试了每一种方法,除了我想要的每一个结果之外:P。

为了让3个较小的球被困在大球的图像(非矩形)范围内,我缺少什么?

感谢您保存我的一周! :)

1 个答案:

答案 0 :(得分:0)

如果您使用的是 @Service("myCoolService") <bean class="com.a.cool.Class"> <property name="someProp" ref="myCoolService"/> </bean> ,那么您可以按照其他question & answer

中的建议进行操作

即使您看起来希望将UIDynamics定义为圆的collisionBoundingPath

UIBezierPath

从那里,您可以通过override public var collisionBoundingPath: UIBezierPath { let radius = min(bounds.size.width, bounds.size.height) / 2.0 return UIBezierPath(arcCenter: CGPointZero, radius: radius, startAngle: 0, endAngle: CGFloat(M_PI * 2.0), clockwise: true) } 自定义较小球撞击外边缘的行为(再次,请参阅链接的问题和答案)。

更新

发布更多代码后,我认为您遇到的另一个问题是UICollisionBehaviorDelegate不包括&#34;主球&#34;。你只是在3个子球之间添加碰撞行为,这可能就是为什么他们没有像你想要的那样正确地与大球交互。希望这有帮助!