如何使圆形视图与桨碰撞

每当圆形视图与故事板上的桨碰撞时,它实际上与视图的矩形框架碰撞。 我该如何解决这个问题。 我也尝试过UIBezierPathCAShapeLayer ,它似乎没有用。

红色箭头是碰撞点,因为它似乎没有与球碰撞,而是与视图的框架碰撞。 一次,用桨板触摸框架,它会反弹,等等。

屏幕快照

如果您正在使用UIDynamicAnimator ,则可以为将要发生collisionBoundingPath的项目定义collisionBoundsTypecollisionBoundingPath ,例如:

 @IBDesignable public class BallView : UIView { @IBInspectable public var fillColor: UIColor = UIColor.blackColor() { didSet { setNeedsLayout() } } override public var collisionBoundsType: UIDynamicItemCollisionBoundsType { return .Path } 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) } private var shapeLayer: CAShapeLayer! public override func layoutSubviews() { if shapeLayer == nil { shapeLayer = CAShapeLayer() shapeLayer.strokeColor = UIColor.clearColor().CGColor layer.addSublayer(shapeLayer) } let radius = min(bounds.size.width, bounds.size.height) / 2.0 shapeLayer.fillColor = fillColor.CGColor shapeLayer.path = UIBezierPath(arcCenter: CGPoint(x: bounds.size.width / 2.0, y: bounds.size.height / 2.0), radius: radius, startAngle: 0, endAngle: CGFloat(M_PI * 2.0), clockwise: true).CGPath } } @IBDesignable public class PaddleView : UIView { @IBInspectable public var cornerRadius: CGFloat = 5 { didSet { setNeedsLayout() } } @IBInspectable public var fillColor: UIColor = UIColor.blackColor() { didSet { setNeedsLayout() } } override public var collisionBoundsType: UIDynamicItemCollisionBoundsType { return .Path } override public var collisionBoundingPath: UIBezierPath { return UIBezierPath(roundedRect: CGRect(x: -bounds.size.width / 2.0, y: -bounds.size.height / 2.0, width: bounds.width, height: bounds.height), cornerRadius: cornerRadius) } private var shapeLayer: CAShapeLayer! public override func layoutSubviews() { if shapeLayer == nil { shapeLayer = CAShapeLayer() shapeLayer.strokeColor = UIColor.clearColor().CGColor layer.addSublayer(shapeLayer) } shapeLayer.fillColor = fillColor.CGColor shapeLayer.path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height), cornerRadius: cornerRadius).CGPath } } 

如果执行此操作,然后将这些项添加到UICollisionBehavior ,它将遵循您为项定义的碰撞边界。 例如:

碰撞动画


上面说明了一个瞥见的打击,就像你的原始图像一样。 如果你想让它UICollisionBehavior ,即使它碰到了桨的边缘,你可以为UICollisionBehavior指定collisionDelegate并给它一个新的方向:

 let collision = UICollisionBehavior(items: [paddleView, ballView]) collision.translatesReferenceBoundsIntoBoundary = true collision.collisionDelegate = self self.animator.addBehavior(collision) 

并符合UICollisionBehaviorDelegate ,然后实现collisionBehavior(beganContactForItem:withItem:atPoint:)

 func collisionBehavior(behavior: UICollisionBehavior, beganContactForItem item1: UIDynamicItem, withItem item2: UIDynamicItem, atPoint p: CGPoint) { let postCollisionDirection = UIDynamicItemBehavior(items: [ballView]) postCollisionDirection.addLinearVelocity(CGPoint(x: ballView.center.x - paddleView.center.x, y: -200), forItem: ballView) animator.addBehavior(postCollisionDirection) } 

产生的结果如下:

在此处输入图像描述

显然,为了获得理想的效果,你必须要花很多时间来解决这个问题,但它说明了检测碰撞并为球增加线速度的基本思路。

比接受的答案更简单的答案是将边界设置为椭圆而不是定义的路径:

  override public var collisionBoundsType: UIDynamicItemCollisionBoundsType { return .Elliptical }