SpriteKit でゲームを作ってみる

動機

iOS7 Tech Talks に当選したので、いそいそとお出かけしたら、ゴイスーなホテルでランチまでごちそうになってしまった。その割にアウトプットも無い自分なので、これは申し訳ないなと思い、 Apple 社激推しの SpriteKit でも使ってゲームでも作ってみるかと思ったのだが、例によって締切がないと動かない体質が邪魔をしたので、 Advent Calendar に登録して退路を断ってみた次第('ω`)

偶然にも、本日 iOS7 Tech Talks のビデオ が公開されたらしいので、是非そちらも(要 Developer アカウント)。

最初に書いておきますが、最後まで出来ませんでした……('A`)

SpriteKit とは?

  • iOS7 より利用できる Apple 社謹製の 2D 描画& 2D 物理シミュライブラリ
  • OS(SDK) に最初から含まれるので、利用が簡単
  • UIKit に似た実装で、利用が簡単
  • 描画部分と物理シミュ部分が最初から統合されているので、扱いが簡単
  • パーティクルエフェクトが利用可能。パラメータを Xcode 上でプレビューしながら編集できる
  • 性能について書くと炎上するので、そこは割愛
  • OSX でも使えるので、マルチプラットフォーム(と言っていいのだろうか)

この記事では、SpriteKit を使って、ゲームを作ろうと思います。

どんなゲームを作ったか

  • SpriteKit は 2D ゲームのためのライブラリである -> 2D のゲーム……? -> 2D シューティングだ!

Screen Shot 2013-12-24 at 20.29.27.png

というわけで、懐かしいキャラバンシューティングを作ることにしました。

縛り

  • 描画周りは SpriteKit 以外利用しない
    • 大前提
  • なるべく Objective-C のみで作成する
    • Objective-C 歴自体は iPhone3G の頃からだけど、記述時間的にはさっぱりなので、 Objective-C 的にヌルい部分もあるけど、そこは目を瞑る('A`)
  • ちゃんと遊べるものにする
    • すみませんすみません('A`)

作っていく

色々書こうと思ったんですが、そもそも完成しておらず、予定していたソースの公開もままならぬ故、実際に SpriteKit でゲームを作る上で気になった点などを記していこうと思います。

SKView

SpriteKit で表示をするために必要な専用の View です。

ほぼ通常の UIView と同じですが、表示内容については、SKScene という別のクラスを渡します。この SKScene を継承してゲーム独自の処理を加えていきます。

SKScene

その名の通り、SpriteKit において、ゲームのシーン(舞台)を表します。

これに後述する SKNode を子供として追加していくことで画面を作ります。この辺は UIView の仕組みと似ていると思います。

またこのクラスは、ゲームフレーム単位で update: というメソッドが OS から呼ばれます。通常のアプリと違い、ゲームの場合、入力があって初めて処理が呼ばれるのではなく、常に処理を行っておきたいため、このような仕様になっていると思われます。

SKNode

SpriteKit における画面作りの基本になるクラスです。

UIKit では、UIView を基本として画面を構成しましたが、SpriteKit では同じように SKNode をツリー状に構成していくことで画面を作ります。実は SKSceneSKNode を継承しています。

1
2
3
4
5
SKScene* scene = [[SKScene alloc] initWithSize:CGSizeMake(320, 480)];
SKNode* node0 = [SKNode node];
[scene addChild:node0];
SKNode* node1 = [SKNode node];
[node0 addChild:node1];

このように、SKNodeSKNode の子供になることができます。UIView 等と同じく、座標系は親の影響を受けます。

派生クラス

SKNode は、それ単体では凝った何かを表示することが出来ません。

何かを表示したりする際は、SKNode の派生クラスを使います。色々ありますが、今回は SKSpriteNode のみ簡単に説明します。

SKSpriteNode は、SKNode に一枚の絵を表示する機能を追加したものです。一枚の絵は、単色の矩形か、SKTexture で指定するイメージになります。

SKTexture

SKTexture は SpriteKit におけるイメージ全般を取り扱うクラスです。UIImageView 等のように簡単にイメージを取り扱うことができます。

Xcode でいわゆるテクスチャアトラスを簡単に作ることが出来るのですが、実はこれが少し罠で、しばらくハマってた時期がありました。

SKTexture は画像一枚だけでなく、画像一枚の一部分(サブテクスチャといいます)を扱うことが出来ます。サブテクスチャは、既にある SKTexture から切り出す部分を指定することで作ることが出来ます。これは Xcode によって作られたテクスチャアトラス中のテクスチャを使う場合もそうなります。

しかし、サブテクスチャからサブテクスチャを作ることは出来ません。これが地味に困る場合があります。

具体例を挙げます。

人が歩くアニメーションパターンを用意したとしましょう。同じキャラクタなので、一枚のイメージファイル(a)に複数のパターンを追加します。そして、それをテクスチャアトラス(b)にします。

実際に使用する際、a を呼び出すことは可能です。

1
SKTexture* tex = [SKTexture textureWithImageNamed:@"a"];

で呼び出せるはずです。

ですが、ここから a 中の歩きパターンを個々に取り出そうとすると、上手くいきません。

これは、tex が既にサブテクスチャになってるためです。テクスチャアトラスからテクスチャを取り出した際には、自動的にサブテクスチャになってしまうようです。

色々試したのですが、 SKTexture がサブテクスチャなのかどうかを判定も出来ませんし、ましてや UV を書き換えることも出来ないようなので、これはプログラムというよりデータを作る段階で意識しておく必要があることになります。

簡便なのはいいのですが、UV くらい書き換えられてもいいのではないかと思います。iOS8 に期待です。

最後に

本当は他にも色々あるのですが、時間がなくて、こんな中途半端で終わって申し訳ないです。せめて、動く状態のプロジェクトを年内にはアップしたいと思いますので、興味があれば見てやってください。

ちなみに、動画はこの辺にあります

そういや、今日はクリスマスイヴですね('ω`;)

追記

すっかり忘れてましたが、ソースをアップしました