每当圆形视图与故事板上的球拍碰撞时,它实际上会与视图的矩形框架发生碰撞。我该如何解决这个问题。我也尝试了UIBezierPath
,CAShapeLayer
,但它似乎没有用。
红色箭头是碰撞点,因为它似乎没有与球碰撞,而是与视图的框架碰撞。一次,用桨板触摸框架,它会反弹,等等。
答案 0 :(得分:5)
如果您使用UIDynamicAnimator
,则可以为要碰撞的项目定义collisionBoundsType
和collisionBoundingPath
,例如:
@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
,则会尊重您为项目定义的碰撞边界。例如:
上面说明了一个瞥见的打击,就像你的原始图像一样。如果您希望它在碰到划水板边缘时反弹,您可以为collisionDelegate
指定UICollisionBehavior
并为其指定新方向:
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)
}
产生类似的东西:
很明显,你必须要花很多时间才能获得理想的效果,但它说明了检测碰撞并为球增加线速度的基本思路。
答案 1 :(得分:1)
比接受的答案更简单的答案是将边界设置为椭圆形而不是定义的路径:
{{1}}