Upgrade to Pro — share decks privately, control downloads, hide ads and more …

👾

giginet
March 01, 2018
40k

 👾

try! Swift 2018

giginet

March 01, 2018
Tweet

Transcript

  1. !

  2. IDE

  3. SpriteKit • Apple official game engine for 2D games •

    Since iOS 7 • Available on iOS, macOS, tvOS and watchOS • Similar API with cocos2d-iphone
  4. class GameScene: SKScene { override func sceneDidLoad() { super.sceneDidLoad() let

    sprite = SKSpriteNode(imageNamed: "riko") addChild(sprite) } }
  5. class GameScene: SKScene { var riko: SKSpriteNode! override func sceneDidLoad()

    { super.sceneDidLoad() riko = childNode(withName: "//riko") as! SKSpriteNode } }
  6. 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) } }
  7. class GameScene: SKScene { var riko: SKSpriteNode! override func touchesBegan(_

    touches: Set<UITouch>, 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) } } }
  8. class GameScene: SKScene { var riko: SKSpriteNode! override func touchesBegan(_

    touches: Set<UITouch>, 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) } } }
  9. class GameScene: SKScene { var riko: SKSpriteNode! override func touchesBegan(_

    touches: Set<UITouch>, 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) } } }
  10. class GameScene: SKScene { var riko: SKSpriteNode! override func touchesBegan(_

    touches: Set<UITouch>, 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) } } }
  11. 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
  12. // 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)
  13. 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/
  14. 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/
  15. Bringing game ideas to life Entities & Components Pathfinding Agents

    MinMax AI Rule Systems Random Sources State Machines
  16. 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) } }
  17. Component Oriented Design • GKComponent • Reusable funcBons • Movement,

    Input, AnimaBon etc… • GKEnBty • Container of components • Player, Enemy, Item etc…
  18. 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()) } }
  19. Other Features • Rule Systems • Rule based decision logics

    • MinMax AI • Minimax strategy for compeBBon games • Random Source • Random generators (like Mersenne twister)
  20. rx.update .scan(0) { count, _ in count + 1 }

    .bind(to: riko.rx.zRotation) .disposed(by: disposeBag)
  21. 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)
  22. class Player: GKEntity { let vitality = BehaviorRelay<Int>(value: 100) }

    player.vitality .map { CGFloat($0) / CGFloat(self.player.maxVitality) } .bind(to: vitalityGauge.rx.xScale) .disposed(by: disposeBag) player.vitality.accept(10) // Hadouken
  23. SpriteKit Unity 3D ✅ ✅ ✅ ✅ ✅ ✅ ✅

    ❌ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅
  24. SpriteKit Unity 3D ✅ ✅ ✅ ✅ ✅ ✅ ✅

    ❌ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅