2016-03-20 4 views
2

Всякий раз, когда круговой обзор сталкивается с веслом на раскадровке, он фактически сталкивается с прямоугольной рамкой вида. Как решить эту проблему. Я также пробовал UIBezierPath, CAShapeLayer и, похоже, он не работает.Как сделать круговой обзор сталкиваться с веслом

Красная стрелка является встречной точкой, поскольку она, похоже, не сталкивается с мячом, а не сталкивается с рамкой зрения. один раз, рамка касается тростника, который он отскакивает назад и так далее.

screen snapshot

+2

Как вы обнаружение столкновения? Измените свой вопрос, чтобы включить код. –

+0

Я не использовал Collision, написал func, который проверяет ось y весла и ось y представления, как только они равны. Мяг отскакивает назад. Я использовал NS Timer для обновления кадра на 20 пикселей View, как 0 - 20- 40- 60 и т. Д. –

+0

Вы должны взглянуть на UI Dynamics и/или SpriteKit. – dasdom

ответ

4

Если вы используете 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, он будет соблюдать границы столкновений, которые вы определили для предметов. Например:

collision animation


выше иллюстрирует скользящий удар, как в исходном изображении. Если вы хотите, чтобы подпрыгивать вверх, даже если она попадает на край лопасти, вы можете указать 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) 
} 

Это дает что-то вроде:

enter image description here

Очевидно, вам придется немного поиграть, чтобы добиться желаемого эффекта, но это иллюстрирует основную идею обнаружения столкновения и соответственно прибавляет линейную скорость к мячу.

+0

Спасибо, Rob, для Paddle я применил UIPanGesture для перемещения по горизонтали один раз, он касается мяча, который он отскакивает назад, весло не двигается вообще, похоже, не работает с столкновением. почему это? –

+0

Посмотрите на свое исходное изображение: если настоящий шар попал в весло, как у вас, он будет оглядываться в сторону и вниз, а не возвращаться обратно. – Rob

+0

Это прекрасно, поскольку вы показали, что мяч сталкивается, с краем весла, но он должен снова оправиться назад и нажать на экран. возможно ли это с помощью Collisions & Gravity? –

0

Еще более простой ответ, чем принятый ответ будет установить границы быть эллиптическими вместо определенного пути:

override public var collisionBoundsType: UIDynamicItemCollisionBoundsType { 
     return .Elliptical 
}