Please note, this blog entry is from a previous course. You might want to check out the current one.
Create the paddle lazily. Place it outside (just a little bit) of the game view – which perhaps a bad way to know if it has been created recently. … and make it nice and colorful, with rounded corners etc …
struct Constants { static let PaddleSize = CGSize(width: 80.0, height: 20.0) static let PaddleCornerRadius: CGFloat = 5.0 static let PaddleColor = UIColor.greenColor() } lazy var paddle: UIView = { let paddle = UIView(frame: CGRect(origin: CGPoint(x: -1, y: -1), size: Constants.PaddleSize)) paddle.backgroundColor = Constants.PaddleColor paddle.layer.cornerRadius = Constants.PaddleCornerRadius paddle.layer.borderColor = UIColor.blackColor().CGColor paddle.layer.borderWidth = 2.0 paddle.layer.shadowOffset = CGSize(width: 2.0, height: 2.0) paddle.layer.shadowOpacity = 0.5 self.gameView.addSubview(paddle) return paddle }()
When the paddle is outside the game view (at the beginning and possibly after device roatation), reset its position:
override func viewDidLayoutSubviews() { ... if !CGRectContainsRect(gameView.bounds, paddle.frame) { resetPaddle() } ... }
The initial position of the paddle in the middle of the bottom of the screen (and we set the barrier for the dynamic behavior … to be done later on):
func resetPaddle() { paddle.center = CGPoint(x: gameView.bounds.midX, y: gameView.bounds.maxY - paddle.bounds.height) addPaddleBarrier() }
To move the paddle, I added three gesture. The pan gesture handles most movement. However in the heat of the game it might be necessary to move faster … that’s what the left and right swipe gestures are fore:
override func viewDidLoad() { ... gameView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: "panPaddle:")) let swipeLeft = UISwipeGestureRecognizer(target: self, action: "swipePaddleLeft:") swipeLeft.direction = .Left gameView.addGestureRecognizer(swipeLeft) let swipeRight = UISwipeGestureRecognizer(target: self, action: "swipePaddleRight:") swipeRight.direction = .Right gameView.addGestureRecognizer(swipeRight) }
While panning change the position of the paddle according to the panned distance. For swipes move to the far left or right:
func panPaddle(gesture: UIPanGestureRecognizer) { switch gesture.state { case .Ended: fallthrough case .Changed: placePaddle(gesture.translationInView(gameView)) gesture.setTranslation(CGPointZero, inView: gameView) default: break } } func swipePaddleLeft(gesture: UIPanGestureRecognizer) { switch gesture.state { case .Ended: placePaddle(CGPoint(x: -gameView.bounds.maxX, y: 0.0)) default: break } } func swipePaddleRight(gesture: UIPanGestureRecognizer) { switch gesture.state { case .Ended: placePaddle(CGPoint(x: gameView.bounds.maxX, y: 0.0)) default: break } }
To change the position of the paddle, change its origin – but take care, not to move it off screen:
func placePaddle(translation: CGPoint) { var origin = paddle.frame.origin origin.x = max(min(origin.x + translation.x, gameView.bounds.maxX - Constants.PaddleSize.width), 0.0) paddle.frame.origin = origin addPaddleBarrier() }
The barrier equals the dimensions and form of the paddle:
struct Constants { ... static let PaddlePathName = "Paddle" } func addPaddleBarrier() { breakout.addBarrier(UIBezierPath(roundedRect: paddle.frame, cornerRadius: Constants.PaddleCornerRadius), named: Constants.PaddlePathName) }
Now we have a working paddle, and it’s possible to change the initial position of the ball depending on the paddle:
func placeBall(ball: UIView) { var center = paddle.center center.y -= Constants.PaddleSize.height / 2 + Constants.BallRadius ball.center = center }
The complete code for step #2 is available on GitHub.













