👾

011714704c4a925e542d426d4cdaa4e3?s=47 giginet
March 01, 2018
36k

 👾

try! Swift 2018

011714704c4a925e542d426d4cdaa4e3?s=128

giginet

March 01, 2018
Tweet

Transcript

  1. @giginet

  2. None
  3. None
  4. None
  5. None
  6. None
  7. !

  8. IDE

  9. IDE Game Development Tool

  10. None
  11. None
  12. None
  13. None
  14. None
  15. None
  16. Let’s make your !

  17. SpriteKit

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

    Since iOS 7 • Available on iOS, macOS, tvOS and watchOS • Similar API with cocos2d-iphone
  19. None
  20. None
  21. • RepresentaBon of each game screens SKScene TitleScene GameScene

  22. • Rendered objects in scenes • Tree hierarchy SKNode

  23. class GameScene: SKScene { override func sceneDidLoad() { super.sceneDidLoad() let

    sprite = SKSpriteNode(imageNamed: "riko") addChild(sprite) } }
  24. SKNode • SKSpriteNode • SKLabelNode • SKEmiJerNode • SKTileMapNode •

    and more…
  25. None
  26. None
  27. None
  28. class GameScene: SKScene { var riko: SKSpriteNode! override func sceneDidLoad()

    { super.sceneDidLoad() riko = childNode(withName: "//riko") as! SKSpriteNode } }
  29. 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) } }
  30. 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) } } }
  31. 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) } } }
  32. 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) } } }
  33. 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) } } }
  34. None
  35. 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
  36. cocos2d-iphone cocos2d-x

  37. // 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)
  38. Level up your !

  39. 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/
  40. None
  41. 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/
  42. Bringing game ideas to life Entities & Components Pathfinding Agents

    MinMax AI Rule Systems Random Sources State Machines
  43. State Machine

  44. 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) } }
  45. Component Oriented Design

  46. Component Oriented Design • GKComponent • Reusable funcBons • Movement,

    Input, AnimaBon etc… • GKEnBty • Container of components • Player, Enemy, Item etc…
  47. 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()) } }
  48. None
  49. Pathfinding

  50. Agents

  51. Other Features • Rule Systems • Rule based decision logics

    • MinMax AI • Minimax strategy for compeBBon games • Random Source • Random generators (like Mersenne twister)
  52. ! meets Reactive Extension

  53. RxSwift

  54. None
  55. rx.update .scan(0) { count, _ in count + 1 }

    .bind(to: riko.rx.zRotation) .disposed(by: disposeBag)
  56. 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)
  57. None
  58. None
  59. 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
  60. giginet/RxSpriteKit

  61. Available on watchOS

  62. ! beyonds the platform

  63. SpriteKit ✅ ✅ ✅ ✅

  64. SpriteKit Unity 3D ✅ ✅ ✅ ✅ ✅ ✅ ✅

    ❌ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅
  65. SpriteKit Unity 3D ✅ ✅ ✅ ✅ ✅ ✅ ✅

    ❌ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅
  66. None
  67. s1ddok/Fiber2D

  68. None
  69. None
  70. !PRESS START