Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
👾
Search
giginet
PRO
March 01, 2018
42k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
👾
try! Swift 2018
giginet
PRO
March 01, 2018
More Decks by giginet
See All by giginet
🀄️ on swiftc
giginet
PRO
0
590
15年メンテしてきたdotfilesから開発トレンドを振り返る 2011 - 2026
giginet
PRO
2
490
Claude Codeログ基盤の構築
giginet
PRO
7
4.7k
Inside of Swift Export
giginet
PRO
1
3.5k
Swiftビルド弾丸ツアー - Swift Buildが作る新しいエコシステム
giginet
PRO
0
3k
SwiftでMCPサーバーを作ろう!
giginet
PRO
3
490
Creating Intuitive Developer Tool in Swift
giginet
PRO
0
1.7k
Mergeable Libraryで 高速なアプリ起動を実現しよう!
giginet
PRO
2
8.5k
5分でわかるExplicitly Built Modules
giginet
PRO
2
1.9k
Featured
See All Featured
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
510
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Docker and Python
trallard
47
4.2k
How Software Deployment tools have changed in the past 20 years
geshan
2
34k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Embracing the Ebb and Flow
colly
88
5.2k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Marketing to machines
jonoalderson
1
5.8k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
Designing for Timeless Needs
cassininazir
1
510
Ruling the World: When Life Gets Gamed
codingconduct
0
370
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.4k
Transcript
@giginet
None
None
None
None
None
!
IDE
IDE Game Development Tool
None
None
None
None
None
None
Let’s make your !
SpriteKit
SpriteKit • Apple official game engine for 2D games •
Since iOS 7 • Available on iOS, macOS, tvOS and watchOS • Similar API with cocos2d-iphone
None
None
• RepresentaBon of each game screens SKScene TitleScene GameScene
• Rendered objects in scenes • Tree hierarchy SKNode
class GameScene: SKScene { override func sceneDidLoad() { super.sceneDidLoad() let
sprite = SKSpriteNode(imageNamed: "riko") addChild(sprite) } }
SKNode • SKSpriteNode • SKLabelNode • SKEmiJerNode • SKTileMapNode •
and more…
None
None
None
class GameScene: SKScene { var riko: SKSpriteNode! override func sceneDidLoad()
{ super.sceneDidLoad() riko = childNode(withName: "//riko") as! SKSpriteNode } }
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) } }
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) } } }
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) } } }
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) } } }
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) } } }
None
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
cocos2d-iphone cocos2d-x
// 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)
Level up your !
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/
None
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/
Bringing game ideas to life Entities & Components Pathfinding Agents
MinMax AI Rule Systems Random Sources State Machines
State Machine
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) } }
Component Oriented Design
Component Oriented Design • GKComponent • Reusable funcBons • Movement,
Input, AnimaBon etc… • GKEnBty • Container of components • Player, Enemy, Item etc…
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()) } }
None
Pathfinding
Agents
Other Features • Rule Systems • Rule based decision logics
• MinMax AI • Minimax strategy for compeBBon games • Random Source • Random generators (like Mersenne twister)
! meets Reactive Extension
RxSwift
None
rx.update .scan(0) { count, _ in count + 1 }
.bind(to: riko.rx.zRotation) .disposed(by: disposeBag)
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)
None
None
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
giginet/RxSpriteKit
Available on watchOS
! beyonds the platform
SpriteKit ✅ ✅ ✅ ✅
SpriteKit Unity 3D ✅ ✅ ✅ ✅ ✅ ✅ ✅
❌ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅
SpriteKit Unity 3D ✅ ✅ ✅ ✅ ✅ ✅ ✅
❌ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅ ❌ ✅
None
s1ddok/Fiber2D
None
None
!PRESS START