碰撞后将多个视图相互移动 iOS?

Move many views against one another after collision iOS?

过去几天我一直在尝试在我的 iOS 申请中实施以下内容,但没有成功

(Source)

我想要什么

当这些圆圈中的任何一个被用户拖动时(无论是红色还是灰色),与移动的圆圈接触的圆圈应该移动。 因此,如果所有圆圈都在一条线上,并且第一个向右移动,它将把其余的圆圈推向右边。

到目前为止我尝试了什么

1) intersects(_ rect2: CGRect) 方法。除了为每个圆圈使用 intersects 方法创建大量嵌套 for 循环外,我想不出别的办法。 首先,它看起来非常混乱,其次该方法低效即该方法在以下情况下不响应用户拖得太快了。

2) UICollisionBehaviour。在阅读另一个问题后,我发现这仅在 UIDynamicAnimator 负责在屏幕上移动视图而不是用户时才有效。(与拖动一样)

最后我认为,Sprite Kit 是我需要的,但我不确定如何或为什么将它用于我的应用程序的这么小的组件。

任何建议都是阿司匹林。谢谢!

我能够使用 Sprite kit 执行 移动以防止碰撞 效果。这并不难,正如我想象的那样。

然而,这只是一个概念证明,并没有解决诸如接受 超快 运动等问题。

如果您是 SpriteKit 的新手,请阅读 this article from RayWenderlich.com . Ofcourse Apple's Programming guide to Sprite Kit 是另一个了不起的资源。

代码

   class GameScene : SKScene

   var orangeBall : SKShapeNode!
   var greenBall  : SKShapeNode!

 // Description :  - Create two circular shapes here 
 //                - Give them physics bodies 
 //                - Add them  

  override func didMove(to view: SKView) {




    orangeBall = SKShapeNode(circleOfRadius: 50 )                       // Size of Circle
    orangeBall.position = CGPoint(x: frame.midX, y: frame.midY)         // Middle of Screen
    orangeBall.glowWidth = 1.0
    orangeBall.fillColor = SKColor.orange

    orangeBall.physicsBody = SKPhysicsBody(circleOfRadius: 50 )
    orangeBall.physicsBody?.affectedByGravity = false
    orangeBall.physicsBody?.isDynamic = true
    orangeBall.physicsBody?.allowsRotation = false
    orangeBall.physicsBody?.restitution = 1

    self.addChild(orangeBall)



    greenBall = SKShapeNode(circleOfRadius: 50 )                       // Size of Circle
    greenBall.position = CGPoint(x: frame.midX + 70, y: frame.midY + 55.0 )         // Middle of Screen
    greenBall.glowWidth = 1.0
    greenBall.fillColor = SKColor.green

    greenBall.physicsBody = SKPhysicsBody(circleOfRadius: 50)
    greenBall.physicsBody?.affectedByGravity = false
    greenBall.physicsBody?.isDynamic = true
    greenBall.physicsBody?.density = greenBall.physicsBody!.density * 0.000001
    greenBall.physicsBody?.allowsRotation = false
    greenBall.physicsBody?.restitution = 1

    self.addChild(greenBall)

}

正在配置触控

var fingerOnOrangeBall = false
var fingerOnGreenBall  = false


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

                if orangeBall.contains(touches.first!.location(in: self)){ fingerOnOrangeBall =  true }

                if greenBall.contains( touches.first!.location(in: self)){ fingerOnGreenBall =   true }



  }

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

    if fingerOnOrangeBall{

        let touch =      touches.first
        var position =   touch!.location(in: self.view)
        position =       self.convertPoint(fromView: position)
        orangeBall.position = position

    }

    if fingerOnGreenBall{

        let touch =      touches.first
        var position =   touch!.location(in: self.view)
        position =       self.convertPoint(fromView: position)
        greenBall.position = position

    }

}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

                   if   fingerOnOrangeBall { fingerOnOrangeBall =  false  }

                   if   fingerOnGreenBall {  fingerOnGreenBall =  false  }

}
 }