Slide 1

Slide 1 text

@giginet

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

!

Slide 8

Slide 8 text

IDE

Slide 9

Slide 9 text

IDE Game Development Tool

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

Let’s make your !

Slide 17

Slide 17 text

SpriteKit

Slide 18

Slide 18 text

SpriteKit β€’ Apple official game engine for 2D games β€’ Since iOS 7 β€’ Available on iOS, macOS, tvOS and watchOS β€’ Similar API with cocos2d-iphone

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

β€’ RepresentaBon of each game screens SKScene TitleScene GameScene

Slide 22

Slide 22 text

β€’ Rendered objects in scenes β€’ Tree hierarchy SKNode

Slide 23

Slide 23 text

class GameScene: SKScene { override func sceneDidLoad() { super.sceneDidLoad() let sprite = SKSpriteNode(imageNamed: "riko") addChild(sprite) } }

Slide 24

Slide 24 text

SKNode β€’ SKSpriteNode β€’ SKLabelNode β€’ SKEmiJerNode β€’ SKTileMapNode β€’ and more…

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

No content

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

class GameScene: SKScene { var riko: SKSpriteNode! override func sceneDidLoad() { super.sceneDidLoad() riko = childNode(withName: "//riko") as! SKSpriteNode } }

Slide 29

Slide 29 text

class GameScene: SKScene { override func sceneDidLoad() { // Use likes viewDidLoad } override func didMove(to view: SKView) { // Use likes viewWillAppear } override func update(_ currentTime: TimeInterval) { // Executed every frame. (1/60s) } }

Slide 30

Slide 30 text

class GameScene: SKScene { var riko: SKSpriteNode! override func touchesBegan(_ touches: Set, with event: UIEvent?) { for touch in touches { let position = touch.location(in: self) if riko.frame.contains(position) { explode(riko) break } } } private func explode(_ target: SKNode) { // Remove from scene target.removeFromParent() // Add effect(Particle) if let explode = SKEmitterNode(fileNamed: "explosion.sks") { explode.position = target.position addChild(explode) } } }

Slide 31

Slide 31 text

class GameScene: SKScene { var riko: SKSpriteNode! override func touchesBegan(_ touches: Set, with event: UIEvent?) { for touch in touches { let position = touch.location(in: self) if riko.frame.contains(position) { explode(riko) break } } } private func explode(_ target: SKNode) { // Remove from scene target.removeFromParent() // Add effect(Particle) if let explode = SKEmitterNode(fileNamed: "explosion.sks") { explode.position = target.position addChild(explode) } } }

Slide 32

Slide 32 text

class GameScene: SKScene { var riko: SKSpriteNode! override func touchesBegan(_ touches: Set, with event: UIEvent?) { for touch in touches { let position = touch.location(in: self) if riko.frame.contains(position) { explode(riko) break } } } private func explode(_ target: SKNode) { // Remove from scene target.removeFromParent() // Add effect(Particle) if let explode = SKEmitterNode(fileNamed: "explosion.sks") { explode.position = target.position addChild(explode) } } }

Slide 33

Slide 33 text

class GameScene: SKScene { var riko: SKSpriteNode! override func touchesBegan(_ touches: Set, with event: UIEvent?) { for touch in touches { let position = touch.location(in: self) if riko.frame.contains(position) { explode(riko) break } } } private func explode(_ target: SKNode) { // Remove from scene target.removeFromParent() // Add effect(Particle) if let explode = SKEmitterNode(fileNamed: "explosion.sks") { explode.position = target.position addChild(explode) } } }

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

Other Game Related Frameworks SceneKit 3D game engine ReplayKit Provides a framework that lets players record their gameplay GameKit Provides Leader Board, Achievements and PvP game logics GameController CollecBon of physical game controller APIs er Framework me controller

Slide 36

Slide 36 text

cocos2d-iphone cocos2d-x

Slide 37

Slide 37 text

// cocos2d-iphone (Objective-C) CCSprite *sprite = [CCSprite spriteWithFile:@"riko.png"]; sprite.position = CGPointMake(100, 100); [self addChild:sprite]; // cocos2d-x (C++) auto sprite = cocos2d::Sprite::create("riko.png"); sprite->setPosition(cocos2d::Point(100, 100)); this->addChild(sprite); // SpriteKit (Swift) let sprite = SKSprite(imageNamed: "riko") sprite.position = CGPoint(x: 100, y: 100) addChild(sprite)

Slide 38

Slide 38 text

Level up your !

Slide 39

Slide 39 text

GameplayKit β€’ Provide collecBon of essenBal game algorithms / design paJerns. β€’ Since iOS 9 β€’ Available on iOS, macOS and tvOS β€’ Introducing GameplayKit β€’ hJps:/ /developer.apple.com/videos/play/wwdc2015/608/

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

DemoBots β€’ Apple Official sample project using GameplayKit β€’ Currently, you need patch to build β€’ hJp:/ /bit.ly/2ortMku β€’ Deeper into GameplayKit with DemoBots β€’ hJps:/ /developer.apple.com/videos/play/wwdc2015/609/

Slide 42

Slide 42 text

Bringing game ideas to life Entities & Components Pathfinding Agents MinMax AI Rule Systems Random Sources State Machines

Slide 43

Slide 43 text

State Machine

Slide 44

Slide 44 text

class FleeState: GKState { override func update(deltaTime seconds: TimeInterval) { if player.hp <= 0 { // If you are dead. // Enter to GameOver State stateMachine?.enter(GameOverState.self) } } } class ClearState: GKState { override func didEnter(from previousState: GKState?) { let gameOverLabel = SKLabelNode(text: "Game Over") addChild(gameOverLabel) } } class GameScene: SKScene { private var stateMachine: GKStateMachine! override func didMove(to view: SKView) { super.didMove(to: view) stateMachine = GKStateMachine(states: [ ReadyState(), FleeState(), ChaseState(), ClearState(), ]) stateMachine.enter(MainState.self) } }

Slide 45

Slide 45 text

Component Oriented Design

Slide 46

Slide 46 text

Component Oriented Design β€’ GKComponent β€’ Reusable funcBons β€’ Movement, Input, AnimaBon etc… β€’ GKEnBty β€’ Container of components β€’ Player, Enemy, Item etc…

Slide 47

Slide 47 text

class InputComponent: GKComponent { override func update(deltaTime seconds: TimeInterval) { // handle input if isRightKeyPressed { isWarking = true velocity = CGPoint(x: 10, y: 0) } else { isWarking = false velocity = CGPoint.zero } } } class AnimationComponent: GKComponent { override func update(deltaTime seconds: TimeInterval) { // handle animation let inputComponent = entity?.component(ofType: InputComponent.self)! if inputComponent.isWarking { playWalkingAnimation() } else { playIdleAnimation() } } } class Player: GKEntity { init() { super.init() addComponent(InputComponent()) addComponent(AnimationComponent()) } }

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

Pathfinding

Slide 50

Slide 50 text

Agents

Slide 51

Slide 51 text

Other Features β€’ Rule Systems β€’ Rule based decision logics β€’ MinMax AI β€’ Minimax strategy for compeBBon games β€’ Random Source β€’ Random generators (like Mersenne twister)

Slide 52

Slide 52 text

! meets Reactive Extension

Slide 53

Slide 53 text

RxSwift

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

rx.update .scan(0) { count, _ in count + 1 } .bind(to: riko.rx.zRotation) .disposed(by: disposeBag)

Slide 56

Slide 56 text

rx.touchesBegan .subscribe(onNext: { touches, _ in for touch in touches { let riko = SKSpriteNode(imageNamed: "riko") riko.position = touch.location(in: self) self.addChild(riko) } }) .disposed(by: disposeBag)

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

class Player: GKEntity { let vitality = BehaviorRelay(value: 100) } player.vitality .map { CGFloat($0) / CGFloat(self.player.maxVitality) } .bind(to: vitalityGauge.rx.xScale) .disposed(by: disposeBag) player.vitality.accept(10) // Hadouken

Slide 60

Slide 60 text

giginet/RxSpriteKit

Slide 61

Slide 61 text

Available on watchOS

Slide 62

Slide 62 text

! beyonds the platform

Slide 63

Slide 63 text

SpriteKit βœ… βœ… βœ… βœ…

Slide 64

Slide 64 text

SpriteKit Unity 3D βœ… βœ… βœ… βœ… βœ… βœ… βœ… ❌ ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ…

Slide 65

Slide 65 text

SpriteKit Unity 3D βœ… βœ… βœ… βœ… βœ… βœ… βœ… ❌ ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ… ❌ βœ…

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

s1ddok/Fiber2D

Slide 68

Slide 68 text

No content

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

!PRESS START