こんにちは、仕事が修羅場ってて今日も圧倒的に成長を続けるgomachan_7です。最近の癒しはアニメNEWGAME!を見て青葉ちゃんが闇を抱える妄想をすることです。その合間にも脱クソゲークリエーターを目指すべく本プロジェクトの進捗を生み出していました。
さて、今回はゲーム開発日誌第2回目ということもあり、本格的な音ゲー制作というよりは前回ゲームエンジンとして紹介したSpriteKit
の扱い方を理解し、今後スムーズに開発を進めていくための土台を作る作業をおこないます。今回も専門的な内容は控えめに、誰でも読み物として読めるよう編集しました。
前回の終わり(参照:第一回・ごま男のゲーム開発日誌:Sprite KitではじめるHello World)に、今回までにやるべき内容として
- SpriteKitを勉強する
- 見た目を構築していき、SpriteKitに慣れる
という目標を設定しました。
本記事では、SpriteKitの肝である「スプライト」によるゲームUIの作り方に慣れていくため、ゲームプレイに必要な「譜面が流れるレーン」と「鍵盤」と「ターンテーブル」の部分を構築して紹介しようと思います。
僕がこのプロジェクトで目標にしているゲーム「LunaticRave2」の画面でいうと以下ので示した部分ですね。
ちなみに、スプライトを活用することで1枚の画像ファイルに大量のUIパーツを並べて効率的な画像を作ることもできますが、今回はUIの試作ということもあり、一枚一枚画像を用意して読み込ませる単純な方法を採用しています。
ゲームUI素材の用意は泥臭く
一見一枚の絵にみえるゲームのプレイ画面ですが、内部的には小さなパーツの組み合わせで構築されていることを想像することができるでしょうか?
例えば、レーンの上から降ってくる各種ノート、白鍵4つ、黒鍵盤3つなどが挙げられます。UIを構築する際には、感覚的にこれらのパーツを各種1つ作り、あとはコピペして適切な場所へ配置していく作業が必要になります。プログラム的にも同じで、まずそれぞれのUIパーツの雛形を1つづつ作り、各種雛形から同じ性質をもったUIパーツを必要なだけ生成し、位置をずらして配置していくことで画面を構成していきます。
それでは、画面の構成単位の雛形を作っていきたいのですが、まずは今回作っていくレーンと鍵盤部分に必要と思われる構成UIパーツを列挙していきます。
- 白鍵
- 黒鍵
- ターンテーブル
- 判定ライン
- 白ノート
- 青ノート
- 赤ノート
- レーンの背景(灰色)
- レーンの背景(黒)
- レーンのボーダーライン
こんなところでしょうか。レーンの背景とボーダーラインは一緒に組み合わせて作った方がよさそうですが、最小構成単位を挙げさせていただきました。
UI素材の作り方なのですが、レーンの背景や判定ラインは単純な単色矩形なので、プログラムで色と大きさを指定して簡単に生成することが可能です。
こんな感じで一行で生成できます。(ね、簡単でしょう?)
let sprite = SKSpriteNode(color: NSColor.redColor(), size: CGSize(width: 40, height: 10))
白鍵や黒鍵、各種ノートはテカりが表現されているので、このような複雑な表現は、実際にPhotoshopを開いてPNGファイルを作り、それを利用することで実現します。ターンテーブルも絵そのものですので、同様に画像で表現します。このプロセスは「スプライト」の本領ですね。以下のようすると white_key.png
という画像を使ってUIパーツが生成できます。プログラムを1行書くだけで簡単に生成できるということだけイメージできれば良いと思います。
let sprite = SKSpriteNode(imageNamed: “white_key")
以下は、作ったPNGです。
以下はプログラムで完全に生成できる単色スプライトです。
これを組み合わせるとこうなります。
一気に様になりました。UI構築における見た目の大部分はPhotoshopとの戦いになるでしょう。。。デザインセンスも求められるのは心がしんどい面もありますが、ゲームっぽい画面が一気に仕上がるので楽しい部分でもあります。
おさらいになりますが、UI構築におけるプログラム側の役割は、スプライトの生成、スプライトのサイズや位置、他のスプライトとの重なり具合を変えたり、用意したPNGを読み込むという部分です。
華やかになったけど…なんか足んねぇよな?
それっぽい見た目ができたのはいいのですが、もうちょっとこう、動きのあるゲームっぽい画面を見たくないですか? 僕は見たいです。鍵盤を押したときに光る表現を入れていきましょう。
画像が光る表現は、プログラム側の処理で鍵盤の画像が表示されたスプライトに対して単色を加算することができるので、それを利用して擬似的に表現します。
同時に、特定のキーを押したときに「特定の鍵盤が光る」というイベントを入れてあげます。これもプログラムでやることは簡単で、「特定のキーが押されたとき」、「特定の処理(色を乗算する)を実行」という対応関係を記述すると実現できます。
更に、LR2では鍵盤を押したときにレーンに向かってビームが発光する表現が採用されているので、以下のようなビームの素材を新たに用意してスプライト化しておきます。
すると、以下のように光りました。
おお…すばらしい。
ついでに、用意したノートのスプライトもランダムなタイミングで生成して、降らせましょう。
詳細は割愛しますが、ゲームプレイ中に先ほど用意したUIの雛形からコピーを動的に生成したり、削除することができます。そうすることで、ランダムなタイミングでコピーしたノートのスプライトをレーンの上に配置し、そのスプライトのy座標を一定間隔で徐々に下げていき、上から下に降らせることができます。次に、そのスプライトがレーンの判定ラインまで到達したら、画面から削除すればいいわけです。
すると、こうなります。
うん、いい感じです。
ここにさ、鍵盤あるんだけど、弾いていかない?
ここまで来てしまったら、実際にタイミングよく叩けたかどうかの判定も入れたいですね? といわけで入れていきます。
タイミング良く叩けたときは「Great」と「コンボ数」、タイミングがずれていた場合には「Poor」と表示するようにしましょう。
また、判定が「Great」のときだけ,判定ラインに光るエフェクトを表示させるようにします。これはパーティクルシステムという技術を利用して表現します。SprtiteKitにあらかじめ入っていたパーティクルのテンプレートを少し加工して、スプライトと同じ理屈で表示/非表示させています。
判定方法の詳細なのですが、キーボード入力によって鍵盤が光ったタイミングで、判定ラインとノートの位置関係を調べて閾値内の距離だった場合には「Great」判定にしています。また、鍵盤を叩かずに見逃した場合は、ノートが判定ラインを超えてしまうので、その時点で「Poor」になります。これを実装した結果、以下のようになりました。
ゲームになっちゃったよ…。Sprite Kitすごい。
今更ですが、ゲームエンジンを利用するメリットとしてこんな風に低コストでそれなりのものが作成できるということがわかっていただけたと思います。
ちなみにタイミング判定の実装ですが、現時点では厳密なものではありません。それっぽく見せるためのものであるので、今後実装方法を考えちゃんとしたものに修正していく必要があることに注意したいです。それでも十分遊べるレベルのものになっていると思います。
ゲームっぽい画面を作る方法はわかった。次は?
今回、Sprite Kitを使うことで想像以上に簡単にゲームのUIを構築できることがわかりました。
音ゲー制作において、UI構築の他にやらなければいけないことはまだまだ数多くあります。(想像)
次回以降取り組んでいくタスクとして
- タイミング判定の実装を詰める
- 譜面データを読み込む仕組みを作る
- 譜面データを再生する仕組みを作る
- 音声/映像を再生する仕組みを作る
- ゲームバランス調査、適用
などが挙げられると思います。
次回は「タイミングを厳密なものにする」、「譜面データを読み込めるようにする」あたりに進捗があればいいなと思っております…!
連載目次:ごま男のゲーム開発日誌
- 第一回・ごま男のゲーム開発日誌:Sprite KitではじめるHello World
- 脱クソゲークリエーター生活、はじまりました