The Animation assignment also referred to as the Breakout game is the 5th and final assignment from the CS193P course Developing iOS 8 Apps with Swift from Stanford University. Really happy to have finally finished this assignment. In my opinion this was the most complex of all the five assignments in this course.
Platform: iOS 9
All the 9 required tasks mentioned in page 2 of the specifications document were completed. Though device rotation is not mentioned as a requirement it does appear as a hint. I didn’t allow device rotation because it seemed to me that it would drastically affect the game play negatively.
The main challenge that I faced in completing this assignment was the nuance of using UIKit Dynamics to make a game. There were numerous issues that I was not fully clear in the beginning on how to implement them. So slowly chipped away each issue one by one before I had a clear picture of how they all fit together.
I am summarizing some of the main issues I had problems with below and how I solved them. Please see the inline documentation in the source code for all the issues and their implementation details.
- Creating the ball and animating it: The shape of the rectangular view of the ball as the collision boundary didn’t seem right. Though prior to iOS 9 I don’t think it was possible to do anything about it. Please see Variation on Dropit Demo from Lecture 12 on how I solved this by setting UIDynamicItemCollisionBoundsType to be an .Ellipse.
- Animating the paddle on pan gesture and having the ball collide. Hints are given in the assignment specifications on how to implement this, but since I hadn’t done it before it wasn’t clear what the outcome would look like.
The solution is to add the paddle as a subview of the game view and additionally create a bezier path that acts as a collision boundary in the UIDynamicBehavior subclass. Then update that boundary repeatedly whenever the paddle moves.
Please see the movePaddle and syncPaddleBoundary methods for details.
- When the paddle was moved too quickly when hitting a ball, the ball would often end up trapped inside the paddle. The way I solved this is first check if the new paddle view’s frame intersected with the balls frame using CGRectIntersectsRect. If the frames don’t intersect then update / sync the boundary.
- Bricks are setup similar to the paddle, where they are added to the game view and their colliding boundaries added to the UIDynamicBehavior subclass.
The ball collides with the boundary and when a collision is detected, the brick is removed from the game view. A bricks array [String:Brick] is used to track all the bricks in the game view and match them against the NSCopying identifier from the collision delegate.
For details please see the methods createBricks and collisionBehavior.
- Special bricks and what behavior they would cause were open ended in the assignment specifications. I used 4 kinds of special bricks, one kind requires 3 hits before it disappears and the other three drops special powers that cause:
- paddles to become larger
- paddles to become smaller
- adds additional balls
- Pausing the game when user taps on Settings. This wasn’t too hard to implement, the main issue here is the moving ball(s). I used an array to capture the balls and remove them from the screen. When user came back, I re-created them and added back their linear velocity. Please see method settingsDidUpdate.
- Instead of putting up an alert when the game ends, a view is used (where it’s state is toggled) to show that the game is over indicating if you won or lost. This view is also used during startup. The startGame and gameOver methods show how this is done.
The following extra credit tasks were also attempted:
- Use sophisticated Dynamic Animation. For example, you might find a creative way to use the action method in a behavior or use something like linear velocity in your calculations.
- As mentioned above, creativity will be rewarded, especially interesting game-play settings.
- Do some cool artistic design in your user-interface (either by drawing or using images).
- Pausing your game when you navigate away from it (to go to settings) is a bit of a challenge (because you basically have to freeze the ball where it is, but when you come back, you have to get the ball going with the same linear velocity it had). Give it a try. It’s all about controlling the linear velocity of the ball.