Showing posts with label debugging. Show all posts
Showing posts with label debugging. Show all posts

Tuesday, 17 June 2014

iOS Sprite Kit Game (Luke's Paddle Tree Game)

Activities @ Lynda - 




Screen Recording in iPhone Simulator


iOS Game Dev with Sprite Kit with Simon Allardice 
    (thanks Lynda for an awesome course!!) DONE
Screenshots of My First Game (Adapted from Copyright Lynda.com Tutorial)
  • GitHub Link: Luke's Breaking Bricks iOS Sprite Kit Game
  • Instructions: 
    • Touch and hold the bottom Paddle to play and prevent it falling. 
    • Move left and right to stop the ball hitting the bottom. 
    • Pause feature activates if you let go of paddle! Touch again to Unpause.
    • Destroy upper bricks to cause Tree to fall down. 
    • Win if Tree touches bottom of screen (tough luck if you deflect it elsewhere haha)
    • Lose if bottom Paddle or Ball touches bottom of screen.
    • Note: The paddle rapidly impulses automatically, so the ball is propelled faster with each contact with the paddle (brace yourself!)
    • Note: Win screen Screenshot not shown (you have to Win to see it!!!), Audio for winning was prepared by yours truly :)
  • Wondering how I preparing the game? It took under 2 days to prepare this game. The purpose of preparing it was to learn iOS Sprite Kit fundamentals programming in Objective-C using Xcode. Most of the code used to prepare the game came from following the Lynda.com course video. I added the following extensions to the game of my own in order to test the framework, but I expended minimal effort in doing so:
    • Custom background (simply a few random coloured brush strokes in Photoshop)
    • Custom sounds (silly 'You Win' and 'You Lose' sounds recorded using Quicktime Player)
    • Custom particle effects (simply replaced the particle effect snow flakes with an image of my head and slightly modified the effect in Particle Effects Editor)
    • Pause feature that activates when use stops touching screen (adapted from this post on Stackoverflow.com). Pause deactivates when the user touches the screen again
    • Tree shaped and coloured object and an animation sequence associated with it. The animation sequence throws the tree it into the screen amongst the bricks at the start of each game. The animation helps it slowly wiggle out of them
    • 'You Win' screen which appears upon contact between the tree object and the bottom of screen (the user may need to destroy the bricks to make it fall)
    • Impulses are automatically applied to the paddle so when the user holds down on the paddle and moves it left and right, the paddle will rapidly spring up and down in this defensive approach, so that each time the ball bounces off the paddle the ball speed increases, which in turn rapidly increases the game difficulty so you can fail or win fast and often! Alternatively an offensive approach can be taken during gameplay if the user chooses to simply hold down on the paddle but does not move left or right, as this will cause the paddle to only rise upward toward the bricks (until the user moves their touch left or right again)
    • If you'd like to know more, please feel free to contact me! Please ensure that you appropriately credit me and the sources I used if you share.

Game Elements 
Scenes (Architecture)
  • Node Types (Sprite, Label, Video, Shape, Emitter, Crop, Effect, etc) 
  • Node Use (manipulable independent Visual Elements Creation and Artwork, Property Configuration, Scene Inclusion, Manipulation, Drawing Order), FPS 
  • Node Association and Inheritance
  • Node Positioning and Coordinate System
    • Anchor Points of Scene and Nodes (Default to Parent Scene)
    • CGPoint (Core Graphics framework) (Explicit and Inline Creation)
  • Physics World (connect and configure different Scene {gravity, zero gravity} and Node Physics Body Properties
    • Physics Bodies (Volume-based (Default is Dynamic Volume or use Static) {simple Draw Path and Play-Testing for complex shapes to minimise Performance impact} , Edge-based). Each one has Bitmask Properties
      • categoryBitMask (Turned On by Default, each Physics Body can belong to multiple Categories and belong to all by Default)
      • collisionBitMask (Turned On by Default, cross-references all Categories where Physics Body should Register a Collision and provide notification of an event)
      • contactBitMask (Turned Off by Default, cross-references all Categories where Physics Body should Register a Contact and provide notification of an event)
    • Physics Body Properties (Mass, Density, Friction {object resistance at collision}, Linear Damping {object resistance moving across space}, Restitution {object bounciness at collision 0 to 1.0f}, Angular Damping, Velocity, etc)
    • Vectors (Magnitude {Force, Impulse}, Direction)
    • Touch Events 
    • Flexibility (Rotation Orientation Compatibility)
    • Collisions (causes them to bounce on impact, and prevents intersection of objects)
    • Contact (apply manually with custom code to be informed when touch detected between objects and apply logic to event)
      • didBeginContact and didEndContact  (reacts to contact using SKPhysicsContactDelegate Protocol)
    • Categories (meaningful Groupings of objects Defined for association with different Physics Body Objects, where Bitmasks are used to describe the actions upon touch between objects of different Categories {inform us, allow or disallow cross-over, bounce, nothing}, 32 Categories allowed to be toggled)
      • Bitwise Operators for defining Multiple Constants for each Categories
    • Landscape Orientation
      • CMD + Right Arrow (in Simulator)
    • Rendering/Game Loop 
      • update method (called at beginning of every frame)
      • didEvaluationActions method (check modifications after Sprite Kit evaluates actions and before any nodes changed are rendered to frame)
      • didSimulatePhysics methods (check mods of Physics Simulation but before affected nodes rendered to screen)
    • Texture Atlases (Manage Artwork Assets for Higher Performance by Grouping images)
      • Animation by Iterating Multiple Images
  • Game Play
    • Scene Transitions (Transition to Second Scene, Win and Lose Scene, Restart First Scene)
    • Sound Effects (SKAction in CAF format)
    • Convert to CAF Format (i.e. M4A from QuickTime Player to CAF Format File)
    • Apple Audio File Convert Tool use by type at Command-Line: 
                /usr/bin/afconvert -f caff -d LEI16 {INPUT} {OUTPUT}
    • Particle Systems (use Small Image and repeat Multiple times)
    • Particle Emitter controls effects under defined Particle Effect Rules using transitioning and Particle Emitter Inheritance to link gradually between nodes
    • Particle Emitter Editor (alternative to creating and setting properties of emitter node object with SKEmitterNode in code, instead simply define properties and save to SKS File for use to create Emitter Nodes)
    • iOS > New File > Resources > Sprite Kit Particle File
    • Actions (SKAction Class)
      • Methods with Reversible Actions
      • Combinations of Sequencing, Grouping, and Repeating Actions
      • Wait Action
  • Refactor 
    • Select Code Snippet > Right Click > Refactor > Extract 
Purchases:
Challenges:
  • Overcoming error "The model used to open the store is incompatible with the one used to create the store”?". 
    • Solution: Delete the SQL file in the apps documents directory
  • Display SQL syntax in Xcode Debugging Area
    • Solution: 
Menu > Product > Scheme > Edit Scheme > Arguments  "-com.apple.CoreData.SQLDebug 1"
  • Discovered how to overcome app always crashing (lost so much time trying to work this out) when attempting to save enum data to core data persistent store. I simply followed this Stackoverflow post from Paras Joshi to reset session and cache data in iPhone Simulator. Absolute lifesaver, this is now my favourite Xcode feature (how sad)!
         Menu > iOS Simulator > Reset Content and Settings

Wednesday, 7 May 2014

Post WDI - iOS Dev App (Web View, Custom Classes, Date Formatting, Dynamic Binding, Super, Self, Segue, View Controller Stack)


Activities @ TeamTreeHouse - 

iOS Development (using Xcode 5 IDE) with Amit Bijlani (Cont'd)

DONE Building API Reader (Table View) iPhone App
  • @synthesise { replace setter and getter methods in .m file associated with @property instance variables in .h file }
  • @interface declaration { NSString *title; } (optional in latest Xcode!)
  • Scoping instance variables { only visible in Class declared within unless use getters and setters }
  • Setter method (in .h) { - (void) setTitle:(NSString *)title; }
  • Getter method (in .h) { - (NSString *) title; }
  • Setter method implementation (in .m, returns instance so use *) { - (void) setTitle:(NSString *)_title { title = _title; }
  • Getter method implementation (in .m) { - (NSString *) title { return title; } }
  • Primitive Type (i.e. int) declaration { @property (nonatomic) int views  } (not require 'strong'/'weak', etc)
  • Legibility Alternative for Primitive Type (Boolean)
.m@property (nonatomic) BOOL unread;
// alternative@property (nonatomic, getter = isUnread) BOOL unread; 

ViewControllerif (blogPost.isUnread) {   NSLog(@"%@", @"hi");}
  • Custom Class instance variable setter access approaches {
    • Dot Notation { NSString *string = blogPost.title; }
    • Convenience Constructor { NSString *string = [blogPost title];
    • Set Method { [blogPost setTitle:@"my title"]; }
  • Self 
    • directly accesses Setter and Getters of the instance variable in @interface
    • allows multiple instance vars to refer to a particular instance of a Class
    • where Class has Parent Class like NSObject, the instance of a Class ('self') needs to refer to the Parent from which it inherits properties and methods (using 'super')
  • Super { refers to Parent Class within implementation }
    • i.e. self = [super init]; // self refers to particular instance of the Class. calls Super/Parent Class to use its methods (i.e. init, dealloc, etc) to initialise instance of Custom Class
  • Customer Class { benefits in that code is more maintainable than with say NSDictionary for data }
  • Dedicated Initializers { responsible to initialize new instances of Class with data, ensures that when a Custom Class is initialized, it must have a title for example }
    • init (NSString, etc)
    • initWithObjects (NSArray, NSDictionary)
    • i.e. - (id) initWithTitle:(NSString *)someTitle;
  • Convenience Constructors { Class methods (i.e. + sign in Help) that performs Alloc and Init in one step and returns an instance }
    • alloc init
    • arrayWithObjects
    • i.e. + (id) blogPostWithTitle:(NSString *)someTitle;  // 'someTitle' passed as argument with this Class method (uses + sign)
  • id { general purpose data type that follows Dynamic Binding Design Pattern where Class of an Instance is not specified immediately (i.e. only definition created in Controller, but it is Bound at Runtime when run app which causes the Object to become a specific type like NSString). it can create instance of any Class and not always know return type. not required to use asterix * (i.e. id *myObject) to indicate instance when specifying 'id', as this is already implied }
  • Dynamic Binding { see above }
  • Display Images from JSON URL { NSURL (i.e. URLWithString) downloaded as UIData (i.e. dataWithContentsOfURL) object (binary), parsed to convert to UIImage object (i.e. imageWithData), and set to the UIImageView (i.e. imageView) }
  • Debugging Malformed and Erroneous Data { i.e. JSON with empty fields ( if ( [blogPost.thumbnail isKindOfClass:[NSString class]] ) { // only display if not NSNull ) }
  • Concatenating Data { [NSString stringWithFormat:@"%@ %@", blogPost.author, blogPost.date]; }
  • Custom Date Styles with NSDateFormatterStyle {
NSDATE *today = [[NSDate alloc] init]; // or use convenience constructor [NSDate date]

NSLog@“%@“, today); // prints today’s date
// NSDate Object stores in ‘seconds’ from Jan 1 2001 until today (represented internally). where 60 sec/min, 60 min/hour, 24 hr/day
NSTimeInterval secondsPerDay = 60 * 60 * 24; // typedef double used with the Date object
NSDate *tomorrow = [NSDate dateWithTimeIntervalSinceNow:secondsPerDay]; // add time to now NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow:-secondsPerDay]; // minus seconds per day
// create instance of NSDateFormatter NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@“EE MMM, dd”];(see Help Menu "Date Formatting Guide > Date Formatters > Fixed Formats (depends on iOS version)http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns

// pass date object *today through date formatter and output a string NSString *todayString = [dateFormatter stringFromDate:today];
  • URL open in Default Browser
NSURL *url = [NSURL URLWithString:@"http://www.lukeschoen.com"]; UIApplication *application = [UIApplication sharedApplication]; // retrieves shared instance of singleton application object UIApplicationMain (see Support Files > main.m)[application openURL:url]; // call UIApplicationMain's method 'openURL'
  • Navigation Controller { manages presentation of hierarchy of data in app. manages multiple View Controllers and navigation between them. Navigation Controller has following elements:
      • Nav Bar (back button, title)
      • View (custom content)
      • Toobar (optional)
    • View Hierarchy
      • Stack of View Controllers { LIFO (Last In First Out) }
        • viewControllers (NSArray)
      • rootViewController
    • Stack Manipulation
      • Push (View Controller) on Stack (point to same View Controller unless there is a Modal View Controller)
        • Properties set
          • topViewController
          • visibleViewController (points to last one pushed onto the Stack)
  • Link ViewControllers in Storyboard { click Cell, press CTRL and Drag, select say 'push' (push View Controller on the Stack by creating a Segue aka Scene between the View Controllers) }
  • Link & Intercept Segue Event with Code { click Segue (connection between View Controllers), Attributes Inspector > Storyboard Segue > Identifier > "___" (i.e. showBlogPost) }
.h
@property (strong, nonatomic) IBOutlet UIWebView *detailView;@property (strong, nonatomic) NSURL *blogPostURL;
.m (of Master View Controller)

// check 'identifier' given to the segue in the storyboard.    // prepareForSegue is part of UIViewController- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {   NSLog(@"%@",segue.identifier);
// use BlogPost Custom Class (on event where segue for DetailView is fired). DetailViewController (segue object) has @properties 'detailView' and 'blogPostURL' defined if ([[segue identifier] isEqualToString:@"showBlogPost"]) {  // access blogpost object from blogposts array that was selected from Table View       NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];   BlogPost *blogPost = [self.blogPosts objectAtIndex:indexPath.row]; [segue.destinationViewController setBlogPostURL:blogPost.url];

.m (of Detail/Web View Controller)
- (void)viewDidLoad {    [super viewDidLoad];// below refers to @property blogPostURL that was set in Master View Controller to prepare segue and show URL details associated with list itemNSURLRequest *urlRequest = [NSURLRequest requestWithURL:self.blogPostURL]; 
  • WebView { subclass of UIView, uses WebKit rendering engine to display webpages }
  • UIWebView { control dragged to Storyboard and instantiated in code to load webpage by clicking the UIWebView in Assistant Editor, pressing CTRL and dragging the UIWebView from Storyboard to section of code in @interface }
  • Embed WebView and Display Common DetailView (in viewDidLoad method)
NSURL *url = [NSURL URLWithString:@"http://www.lukeschoen.com"]; // create instance of url request    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; [self.detailView loadRequest:urlRequest]; // load default webpage using @property detailView

Links:

Purchases:

Friday, 2 May 2014

Post WDI - iOS Development Device Deployed App (Memory Leaks, MVC, Custom Methods, Forward Declarations, Fluid Imaging, Animations, Sensors, Testing, Debugging, Deployment)

Activities @ TeamTreeHouse - 

iOS Development (using Xcode 5 IDE) with Douglass Turner & Amit Bijlani (Cont'd)

DONE Building First iPhone App (Beyond the Basics)
  • Primative Data (Scalar) Types (Fixed memory size allocated by compiler depending on type automatically) { char %c, unsigned int %u, long %ld, float %f, double %lf }
  • Pointers (Dynamic Memory with variable storage) 
    • Memory Address %p  i.e. printf("%p", &i);
    • Mitigates "Passing by Value" Issues (instead of allocate mem twice for same data which is resource intensive, store value in only one place and pass pointer)  i.e. int i = 100; incrememt(int *x); int *i; // i outputs mem addr
  • Arrays
    • Inherit from NSObject (all objects do, it allows mem handling and access to runtime) creates list of string objects accessible with objectAtIndex
    • Example 1: int primts[3]; // store 3 no's. points mem addr 0 plus offset
    • Example 2: // equivalents
Alloc and Init Method
NSNumber *number; // declare varnumber = [NSNumber alloc]; // alloc mem add for object[number initWithInt:100]; // init mem w value using convenience method
Refactored EquivalentNSNumber *number = [[NSNumber alloc] initWithInt:100]; // equivalent to above three lines
Literal Shorthand Equivalent (iOS7 more readable and maintainable)NSNumber *oneHundred = @100; // alloc and init behind the scenes[NSNumber numberWithInt:100];
  • C Language Equivalents
  • Property Attributes (of Classes)
    • @  
      • Compiler Directive (highlights shorthand notation in Objective-C)
      • Examples: @"" (NSString), @100 (NSNumber), @[ ] (NSArray), @{ } (NSDictionary)
    • @property   (i.e. @property (nonatomic, strong) NSString *title;)
      • Uses: Declaration sets up getter and setter methods so can set and get instance vars encapsulated in custom classes, and so objects are available in all methods and may be used with 'self' instance of the View Controller (otherwise cannot get access as out of scope)  i.e. self.vehicles = [[NSArray alloc initWithObjects ...
      • Strong (reference) { retain object/property }
      • Weak (reference) { no concerned if underlying property deallocated and used for child in parent child relationships } 
      • Retain { used in previous versions before AFC when had to maintain retain counts)
      • AFC { Automatic Reference Counting)
      • Retain Count { retain count of 1 means only one object pointing to mem location (i.e. after alloc and init one custom class), whilst retain count of 2 means two objects pointing to same mem location until pointer set to nil }
      • Retain Count Logging { NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)title)); }
      • Deallocate { when no objects pointing to mem addr can deallocate }
      • Nonatomic { non multi-threaded apps where only one process reading or writing at any time }
      • Atomic { multi-threaded apps where multiple processes point to same mem locations and prioritiation of access to data or locking }
  • Memory Leaks
.h (header)@interface Vehicle : NSObject;@property (nonatomic, strong) id wheel;
.m (implementation)Vehicle *vehicle1 = [[Vehicle alloc] init];vehicle1.wheel = vehicle1; // 'wheel' is child property of vehicle1 pointing to its parent creating a 'retain' cyclevehicle1 = nil; // deallocated vehicle1 but 'wheel' is still pointing to vehicle1 and not released causing memory leak
  • Scoping and Self { declare delegates pointing to self when creating a delegate property. use 'self' to implement methods as part of Delegate Protocol }
  • Help and Sample Code { Help > Documentation and API Reference }
  • AppDelegate { helps hook into events of app lifecycle. not used for simple app (move to Support Files) }
  • Interface .h { defines methods and properties of class }
  • Implementation .m { implements methods of interface }
  • Communication and Connections { Code communicates with View Controller and Storyboard View elements connect with IBAction }
  • Target-Action Design Pattern { where target is View Controller and action is method created triggered by IBAction connection }
  • Shortcuts 
    • CMD+0 (Navigator show/hide)
    • CMD+R (Compiles program)
    • CMD+? (Help menu)
      • + .... <method>  { Class Methods that can be directly called on the Class }
      • - .... <method> { Instance Methods called directly on instance variables }
      • [ ...  { code for Method Calls / send a msg to Class }
      • ^{ }   { code denoted with carat denotes passing in a Code Block }
    • CTRL+Click+Drag (places controls relative to other control)
    • CMD+Click { shows class header info }
    • OPT+Click { shows info about class }
    • CMD+ ~ { switches between Xcode and Reference Docs }
  • UIView { belong to each View layer with a property NSArray of 'subViews' and contain added control elements within bounds }
  • Window { main View Controller attaches View to Window on launch of app }
  • UIViewController { manages resizing, layouts, interactions, events, coordination with data, lifecycle events upon load and unload of views }
    • viewDidLoad
    • viewWillAppear
    • viewWillDisappear
    • viewDidUnload
  • UIView Class { rectangular area defined by Frame property of type CGRect with size, origin, and Struct properties }
  • Randomisation { pseudo random numbers generator function arc4random_uniform(max_number) }
  • MVC (Model-View-Controller) Convention 
    • Benefits: design pattern following Single Responsibility Principle allows reuse of Model for multiple View Controllers, and custom models allow use of 'readonly' data to control format and prevent vulnerabilities
    • View (IB aka Storyboard)
    • Controller { View Controller class responsible for retrieving and displaying data on the View. Shift any data (i.e. NSArray) to the Model to achieve MVC design pattern }
    • Model { responsible for storing and providing data. data should be moved to its own class } 
  • Custom Getter and Setter Methods using Hidden Methods
    • Example
@property (strong, nonatomic) NSArray *vehicles; // declaration creates instance var with same name prefixed with underscore (hidden) providing access to this vars value using getters and setters
@interface LSCarYard:NSObject { // object with '_vehicles' as hidden instance var created by @property NSArray *_vehicles; }
// getter method (get is implied) would return an array object -(NSArray*) vehicles;
// setter method (takes Array object as argument) -(void) setVehicles: (NSArray*) newVehicles;
// alloc and initLSCarYard *caryard = [LSCarYard alloc] init];
// get object by calling the 'vehicles' method and returning the _vehicles instance variableNSArray *array = carYard.vehicles; // use dot notation to access object properties
// assign a new array setter by calling setVehicles method to set the value of _vehicles instance varcarYard.vehicles = array;
  • Forward Declarations { @class instructs header of class that a class exists but will be imported in the implementation file instead of the header (not good practice to import local classes within the @interface) }
  • Protect with ReadOnly Attribute (Data Traceability and Scalability)
    • Use: avoids overriding elements accidently (i.e. @property (strong, nonatomic, readonly) ...)
  • Images (images.xcassets)
    • Display Image Options
      • Image View Control 
      • UIImageView { insertSubview atIndex (i.e. background at 0) provides layer insertion flexibility versus just using 'addSubview' }
    • View Hierarchy drag-and-drop to modify layer in which they are displayed 
    • Device Displays 
      • Points Coordinate System { consistency across device resolutions }
      • Auto-Layout { responsive apps for different form factors }
      • Form Factor Toggle { 3.5 inch, 4 inch, device, etc } 
      • Constraints and Pins (Bridging and Validation) { points from bounds of screen to maintain height and width }
      • Fluid Resizing { fixes distorted image fill to fit flush }
      • Retina (2x) has 326 pixels per inch (PPI) for 3.5 inch display and is a high res image with high pixels in small area (not necessarily scaled)
    • Button States { normal (OFF), highlighted (ON), selected }
    • Relative Controls
      • Shortcuts {CTRL+Click+Drag (places controls relative to other control) }
  • Image Based Animation (rapid sequence of images measured in FPS creates illusion of motion)
    • UIImageView { array of UIImage objects (both normal and retina) for an animation }
  • Property Based Animation { using Alpha property for semi-transparency accompanied by animation code to create fading appearance }
  • Intercepting Motion Events (Animations)
    • Sensors 
      • Accelerometer (detects acceleration or speed)
      • Gyroscope (detects rotation events)
    • Events and Actions
      • Shake { captures acceleration and rotation along x, y, z, where constant for this motion is UIEventSubtypeMotionShake }
      • UIResponder is parent class and grandfathers methods including
        • motionBegan
        • motionEnded
        • motionCancelled
      • Simulate Motion Events { Menu > Hardware > <select gesture> }
  • Pragma Marks { directives that appear in Xcode menus to expedite access to methods }
    • #pragma mark - { used to categorise methods by creating a line between them in the Breadcrumb Navigation area }
  • DRY (Don't Repeat Yourself) Principle { refactor and organise code so repetitive tasks are shifted into and called from new methods to comply }
  • Sounds 
    • AudioToolBox Framework manual installation (does not automatically locate) into the Main Bundle using NSBundle path for resources to load sound
  • Testing, Debugging, and Device Deployment (built-in debugger)
    • Debug Navigator { compressing or decompressing the thread list with lower bar }
    • Debug Bar (toggle break points, step over and into)
    • Console
    • main.m (Supporting File in C)
    • Line Numbers (turning them ON)
    • Exception (Dynamic) Breakpoints 
    • Multiple Breakpoints (using Gutter)
    • UINib { View that the compiler creates from the Storyboard }
    • Orphaned Connections { IBOutlets in Connections Inspector no longer used }
  • App Icon and Launch Images 
    • Note: SystemUI automatically crops corners for display in Spotlight (first screen on iPhone when search for apps)
    • Points { standard size for non-retina iPhone, and 2x means twice the amount of points in pixels (i.e. 60 for 2x translates to 120x120 pixels) } 
  • App Store Configuration
    • Help > "app-related" (search)