ゲーム開発で学ぶSwift
入門
株式会社BizReach
プロダクトマーケティング本部
山下大輔
自己紹介
・山下大輔(やました だいすけ)
・2015年1月よりビズリーチのiOSエンジニア
・@daisuke0131
・http://www.facebook.com/daisuke0131
・https://github.com/daisuke0131
https://itunes.apple.com/jp/app/haikurasu-ren-cainokyaria/id972002786?mt=8
おしながき
・SpriteKitについて・・・30min
・ハンズオン・・・60min
SpriteKit
・iOS7からサポートされた2Dゲーム用標準framework
->外部のライブラリを入れる必要がない、すぐに使える。
・普通のview(UIView)と組み合わせて使える
->普通のアプリを作っている時にも、目を引くエフェクトなどのちょっとしたところに
も使えるかも
SpriteKit
・以下の4つの構成要素からなる
ノード(SKNode)・・・表示される個々のパーツ
アクション(SKAction)・・動きを表すもの
シーン(SKScene)・・・ゲームの画面(ノードのサブクラス)
ビュー(SKView)・・・アプリ上でSpriteKitを表示するView(UIViewのサブクラス)
シーン
ノード
ノードA
ノードB
ノードの階層関係
シーンをビューに
紐付けることで描画
SpriteKit
・座標系
x
y x
y
(x,y)
(x,y)
SpriteKit 普通のアプリ(UIKit)
・位置の指定方法
(0,0)
(0,0)
SKNode
・ゲーム要素を作るSKNodeのサブクラス
->何かしらを表示する時に元の素材毎に使うクラスを選ぶイメージ。
SKSpriteNode・・・画像を描画。一番便利なやつ
SKEmitterNode・・・パーティクルを表示。面白いやつ。
SKShapeNode・・・図形を描画。
SKVideoNode・・・動画を描画
SKLabelNode・・・文字を描画
SKCropNode・・・子ノードにマスクを適用して切り出す
SKEffectNode・・・子ノードにCore Imageフィルタを適用
SKAction
・SKNodeの動きを作るやつ
->ノードの移動、回転、拡大縮小などの変化を作ることができる
・使い方は、作ったActionをnodeの持つrunAction
 メソッドに渡すだけ
・連続的なActionも渡せるよ!
let action = SKAction.moveByX(…)
node.runAction(action)
let action1 = SKAction.moveByX(…)
let action2 = SKAction.moveByX(…)
let sequenceAction = SKAction.sequence([action1,action2])
node.runAction(sequenceAction)
SKScene
・ゲーム画面。
 ->スタート画面、ゲーム画面、終了画面の単位でSKSceneを作るイメージ
SKView
・SpriteKitを表示するView。
 ->UIViewのサブクラスであることがポイント。普通のアプリの中で普通にView
  として扱える。
ハンズオン
クソゲーハンズオン
ぶどう汁ブシャーッ
要件
・ボール、バー、グレープの要素からなる
・グレープは5回ぶつかると「ブシャーッ」
・グレープ全部「ブシャーッ」するとクリア
・ボールが下に落ちちゃうとゲームオーバー
・ボールは等速運動をする
・ボールはバー、グレープ、画面の端とは完全弾性衝突
物理エンジンの使い方
・SKNodeに定義されているphysicsBodyを設定する
->衝突、重力加速度などの物理効果が有効化
衝突の検出
・検出したいノード同士のphysicsBodyの 
  contactTestBitMaskに0以外の値をセットする。
 ->didBeginContactが呼ばれるようになる
※contactTestBitMaskとcategoryBitMaskの論理積が0以外の
値になると衝突判定
完全弾性衝突ってなんぞや??
・運動エネルギーが保存される衝突
v
v
衝突前 衝突後
・physicsBodyのrestitutionに1.0を設定すればいい
node.physicsBody?.restitution = 1.0
例えば
Step1 プロジェクトの作り方
https://github.com/daisuke0131/GrapePinBall/blob/
master/resources/resources.zip?raw=true
Step2 リソースの登録
https://github.com/daisuke0131/GrapePinBall/blob/
master/resources/resources.zip?raw=true
drag&drop
Step2 リソースの登録
https://github.com/daisuke0131/GrapePinBall/blob/
master/resources/resources.zip?raw=true
Step3 GemaSceneの登録
let scene = GameScene()
let view = self.view as! SKView
view.showsFPS = true
view.showsNodeCount = true
scene.size = view.frame.size
view.presentScene(scene)
・GameViewControllerのviewDidLoadに
Step4 ノードの表示と物理効果
let ball = SKSpriteNode(imageNamed: “ball”)
ball.physicsBody = SKPhysicsBody(texture:
SKTexture(imageNamed:"ball"), size: ball.size)
ball.position = CGPoint(x:100 ,y:100)
self.addChild(ball)
・GameSceneのdidMoveToViewに
ボール、バー、ボードを表示するように設定していきます。
Step5 Swiftのちょっとした文法
class Grape:SKSpriteNode {
var hitCount:Int = 0
}
・クラスの継承
・データ構造
let grapesPosition:[(x:CGFloat,y:CGFloat)] = [(60.0,500.0),
(160.0,500.0),(260.0,500.0),(110.0,400.0),(220.0,400.0)]
配列、タプル
・繰り返し
//グレープの配置
for pos in grapesPosition{
makeGrape(pos)
}
Step6 physicsBodyのプロパティ設定
restitution・・・反発係数(ぶつかった時の跳ね返り率)
linearDamping・・・移動時の減衰率(空気抵抗的なやつ)
friction・・・摩擦係数
affectedByGravity・・・重力の影響を受けるかどうか
dynamic・・・動くようにするかどうか。(falseだと衝突も無視)
applyImpulse()・・・衝撃を与えることができる。
Step7 タッチ系イベントハンドリング
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
if let touch: AnyObject = touches.first {
let location = touch.locationInNode(self)
let action = SKAction.moveTo(CGPoint(x: location.x, y: 100), duration: 0.2)
self.board.runAction(action)
}
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
if let touch: AnyObject = touches.first {
if !isStarted{
startBall()
isStarted = true
}
}
}
Step8 衝突判定
self.physicsWorld.contactDelegate = self
extension GameScene:SKPhysicsContactDelegate{
func didBeginContact(contact: SKPhysicsContact) {
}
}
delegateの設定
以下のメソッドを追加することで衝突時に呼ばれる
※contactTestBitMaskとcategoryBitMaskの論理積が0以外の
値になると衝突判定
Step9 パーティクル
Step9 パーティクル
let particle = SKEmitterNode(fileNamed: "MyParticle.sks")
self.addChild(particle)
let removeAction = SKAction.removeFromParent()
let durationAction = SKAction.waitForDuration(1)
let sequenceAction = SKAction.sequence([durationAction,removeAction])
particle.runAction(sequenceAction)
particle.position = CGPoint(x: g.position.x, y: g.position.y)
particle.alpha = 1
おしまい

Introduction of Swift from Game Development