build 2D Games • Uses graphics hardware on both Macs and iOS • SceneKit • Tools for creating 3D games • Physics Engine, Particle Generator • gravity, collisions, motion... • Possible to combine with SpriteKit • Metal • SpriteKit and SceneKit is for "casual games" • API that brings app code close to GPU to maximize performance • For games that require lot of processing power • Like OpenGL but should be easier and you get more performance on iOS devices
iOS – no need for external libraries • Built-in tool for texture atlases and particles • Really easy to implement stuff, also features things like video- sprites and applying image effects and masks • Cons • Locked to iOS • Still rather new framework – some features may be missing compared to older frameworks • If you develop cross-platform, Unity is good choice • If you are a beginner in game development and/or solely focused on iOS, SpriteKit is a good choice
controller with one view (UIView) • The view is added to Window so that it's visible on the screen • SpriteKit • Exactly the same, but change UIView to SKView!
– content. Content is provided by an SKScene object • SKView inherites UIView • SKScene represents a "level" or "screen" in the game • Handles the per-frame logic • Create your own class that extends SKScene • Composed with SKNodes (Base class): SKSpriteNode, SKLabelNode, SKShapeNode, SKLightNode, SKCameraNode, SKAudioNode
Start screen, game screen, highscore screen • SKScene contains nodes, where the root node is SKScene itself • Different nodes available • Usually you subclass SKScene • Create initial content (nodes), implement the game logic, implement responder methods for touch events
{ let TITLE = "Game Title" override func didMove(to view: SKView) { ... } func createTitle() -> SKLabelNode { let helloNode = SKLabelNode(fontNamed: "Chalkduster") // To be able to reference to the node later helloNode.name = self.TITLE helloNode.text = self.TITLE helloNode.fontSize = 50; // Center of the screen helloNode.position = CGPoint(x: self.frame.midX, y: self.frame.midY) return helloNode; }
Called immediately after a scene is presented with a view override func didMove(to view: SKView) { self.backgroundColor = SKColor.white self.addChild(self.createAlien()); self.addChild(self.createShootButton()); let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame) self.physicsBody = borderBody } ... }
to your project alienSprite = SKSpriteNode(imageNamed: "alien") // Position the alien in the middle of the screen alienSprite.position = CGPoint(x: self.frame.midX, y: self.frame.midY) // Scale the texture down alienSprite.setScale(0.5) // Add physics! The physic boundaries are exactly the same than in the texture alienSprite.physicsBody = SKPhysicsBody(texture: alienSprite.texture!, size: alienSprite.size) // The mass in kg alienSprite.physicsBody!.mass = 0.2 // How bouncy alien alienSprite.physicsBody!.restitution = 0.5 // Frictional force when in contact alienSprite.physicsBody!.friction = 0.5 return alienSprite }
body • Unaffected by forces or impulses, no mass or volume • Boundaries to the game (SKScene) // Boundaries let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame) self.physicsBody = borderBody
between bodies • By default, everything collides with each other • You can customize this: CollisionBitMask • Contacts • Contact event happens when two bodies touch. It's possible to implement custom logic when bodies in contact • By default, no events are send on collide • You can customize this
custom code // // This body's contactTestBitMask is compared to others body's // category mask by performing a logical AND operation // // NOTIFY WHEN HITTING ALIEN ballSprite.physicsBody!.contactTestBitMask = ALIEN_CATEGORY
after a scene is presented with a view override func didMoveToView(view: SKView) { self.physicsWorld.contactDelegate = self; } func didBegin(_ contact: SKPhysicsContact) { let bodyABitMask = contact.bodyA.categoryBitMask let bodyBBitMask = contact.bodyB.categoryBitMask // Do something } func didEnd(_ contact: SKPhysicsContact) { } }