こんにちは、13の折重です。今回はrogy Advent Calendar 2016の16日目として記事を書きます。
凄い更新が遅くなってしまって申し訳ないです。アドベントカレンダーは日付が変わった瞬間に投稿するのが普通っぽいですよ奥さん

 screenshot
こんな感じのを作ります

の前に宣伝とか

Advent Calenderに登録した時書くことが決まってなかったので記事概要みたいなところに超ナメたこと書いてますね、すいません。実際何も考えてなかったわけではなく逆に色々考えてて、一回書く内容変えたりしてます。じゃあ前まで何書こうと思っていたのかというと、今までのゲーム制作についての色々です。それは結局別の機会に書くことにしたので今回はこっちを書くことにしました。

とここで宣伝。
来るコミックマーケット91にて、我々ロボット技術研究会もサークルとして参加し、有志による記事をまとめた部誌を発行することにしました。そしてそこに僕も「学園祭におけるゲームプレイの観察」と題して寄稿しております。興味がある方は是非買って読んでみてください。スペースは木曜日(12/29) 西地区 "ほ"ブロック41bです。

ここから本題

今回の記事について

今回はシューティングゲームを作る過程で、RPGツクールMVの仕様とプラグイン作成について紹介していこうと思います。
RPGツクールMVはRPGツクールシリーズの最新版で、誰でも気軽にRPGを制作することができます。更にMVからはHTML5をベースにすることによりブラウザで動作するゲームを簡単に作れるようになりました。また、今回扱ったようにプラグインによる拡張でシューティングゲームを作成できるなど、非常に広い汎用性を持ちます。
ゲームエンジンならばUnityなど他のものもあるのではないかと言われるかもしれませんが、RPGツクールはRPGであれば特別な知識などなくても簡単に作成できますし、先ほども言ったようにHTML5がベースなのでwebなどでの公開も簡単で迅速(当然公開場所は自分で用意しなくても公式に用意されています)、更にJavaScriptでプラグインが作成できるため拡張性も高くweb関係の機能の実装とも親和性が高い、という利点があります。今回のようなシューティングゲームを作るようなのはできなくもないだけで極端な使い方ですが、基本普通のRPGを作りそこに独自の機能を追加したいというのには非常に向いていると思います。
シューティンゲームにした理由ですが、バイトでRPGツクールを使って色んなものを動的に生成したり意味不明な使い方を色々したんで、もしかしたらシューティング作れるんじゃないのかって思ったことと、僕が好きなジャンルだからなのと、なんとなくゲーム制作初心者向けってイメージがあるからです。シューティング作れればあらゆるジャンルのゲームが作れますよ、多分。

前述したように筆者はRPGツクールMVを使用しはじめたのが今年の4月から(しかもバイトは月数回)、ついでにJavaScript経験もそれに毛が生えた程度なので不格好なコードもあるかもしれませんが、これからRPGツクールを使いたい人、現在使っている人の助けに少しでもなれれば幸いです。あとバイトを引き継ぐ人が決まったら読んでもらいたいです(主目的)

前提

前置きが多いですね、申し訳ないです。
今回の記事ではJavaScriptについての説明はしません。必要なJavaScriptの知識は各自で勉強してください。すいません。
またクラスがどうとか言っていますがprototypeを使用してクラスっぽい実装をしています。継承って言ったらプロトタイプチェーンを利用してメソッドを親クラスから引き継いでるんだと思ってください。なんか最近JavaScriptにclass構文が実装されたそうですが、RPGツクールでの実装が全てprototypeになっているのでそれに倣います。もしかしたら次のRPGツクールでは実装が変わっているかもしれませんね。というかクラスに限らずRPGツクールの元からの実装に倣っている部分が結構あります。

オリジナルシーン、ウインドウの作成

シーンは、RPGツクールではrpg_scene.js内で定義されており、Scene_TitleやScene_Map、Scene_Battleなどがあります。今回はシューティングゲームということでScene_Shootinを作成したいのですが、基本的にはRPGでのマップ画面とあまり変わらないのでScene_Mapを継承したScene_Shootingクラスを作成することで実装します。
Scene_Shooting.jsとうファイルをpluginsフォルダの中に作り、以下を記述します。

Scene_Shooting.jsに追加

ここまでで保存し、いったん動かしてみます。プラグインを使うにはRPGツクールのエディタ側でツール→プラグイン管理からプラグインを追加しなければならないので忘れないようにしましょう。動かしてもScene_Mapと全く同じ機能を持ったScene_Shootingが代わりに呼ばれるだけなので見た目は全く変わりません。
では少し変更を加えていきます。まず既存の関数をオーバーライドし書き換えることで不要な画面遷移やウインドウ表示などをしないようにしてしまいましょう。

Scene_Shooting.jsに追加 

ここで実行してもまだWindow_SideMenuクラスを作成していないためエラーが出ます。
というわけでウインドウを作っていきます。シューティングゲームにおいてスコアや残機を表示するウインドウです。
ウインドウはrpg_window.jsというファイル内にたくさん定義してあり、それをシーンに追加していく形で表示します。ウインドウ自体が表示する画像や文字などの内容や大きさの情報を持っており、シーンからはウインドウ作成時に表示位置を指定するのみです。新しいウインドウを作成したいと思ったらそれを実現するウインドウクラスを新しく作成してあげましょう。場合によってはそのウインドウを表示する用の新しいシーンも必要になるかもしれませんね。
rpg_window.jsには色々なウインドウのベースとしてwindow_BaseやWindow_Selectableなどがあります。今回は選択肢は必要ないのでWindow_Baseを継承し新たにWindow_SideMenuクラスを作成していきます。

Scene_Shooting.jsに追加

というわけでここまでで自作のシーンとウインドウを追加することができるようになりました。これだけでもかなり制作の自由度は上がるかと思います。

自機の作成とSpriteの追加

次はプレイヤー周りをいじっていきます。と言ってもやることはあまり変わらないです。 
プレイヤーに関する記述はrpg_object.js内に書かれています。rpg_object.jsはその名の通りゲーム内に出てくるオブジェクトについての記述がなされています。マップに表示されるプレイヤーに関してはGame_Playerクラスに書かれています。

まずGame_Player.jsというファイルを作成します。この中でGame_Playerクラスの関数を改変していきます

Game_Player.jsに追加 

RPGでの移動はマス目単位ですがシューティングではその必要はないので毎フレーム移動し進行方向のマス目の状態を確認する部分なども削ります。これだけだと超高速移動をしてしまうので移動距離の計算部分も変更します

 Game_Player.jsに追加 

これでシューティングゲームのように動きました。最後に向きを上向きに固定します。移動処理を書き換えたタイミングでキャラの向きの更新の処理も消してしまったので初期化する時方向を上向きにしてあげれば大丈夫です。

Game_Player.jsに追加  

これで自機を動きはできました。え、なんかデフォルトだと仲間が3人くらい表示されてる?忘れるなかれこれはRPGツクール、そこらへんの設定はエディタ側でできます。ツール→データベース→システムから初期パーティを変更してしまいましょう。

自機をシューティングっぽく動かすことができたので、次は弾を出せるようにしていきたいと思います。ですがその前に、ここでRPGツクールの描画の仕組みについて少し触れます
RPGツクールは画像の描画にpixi.jsというライブラリを使用しています。rpg_core.js内のSpriteというクラスがpixi.jsを用いた画像描画を行う上でのラッパーのような役割をしており、rpg_sprite内にあるSprite_CharacterやSprite_ActorクラスなどがSpriteクラスにゲーム内で扱う上で必要な機能や情報を目的ごとに追加したものになっています。更にrpg_sprite.js内にはSpritesetというSpriteをまとめて管理するためのクラスがあります。各シーンはこのSpritesetを持っており、ここにSpriteを追加していくことで画面に描画するものを管理しています。
実はRPGツクールはマップのロード時に必要なオブジェクトの画像なんかは全てロードしてしまい、まだ発生しないイベントなんかも画像非表示になっているだけでマップには存在していたりします。RPGなので当然と言えば当然なのですが、そのためオブジェクトの動的生成は少しやりずらかったりします。色々がんばるとできます。 
今回Scene_ShootingはScene_Mapを継承して作成したため、Spriteset内のtilemapにSpriteを加えていきます
 
Scene_Shooting.jsに追加

これを呼ぶことによって描画対象を追加することができます。

弾と弾幕の作成

弾クラスと、それを管理する弾幕クラスを作成することにより実装することにします。自機や敵キャラはそれぞれ1つの弾幕クラスを持つようにします。弾については、Game_CharacterBaseクラスを継承したGame_Bulletクラスを弾クラスとして作成します。RPGツクールではマップに表示されているキャラや扉なんかのオブジェクトは基本的にrpg_objectにあるGame_CharacterBaseというクラスを継承しています。Game_CharacterBaseでは画像や座標などの情報を持っており、座標を変更すると勝手に描画位置も変わるなど、ゲーム中の視認できる物体を扱いやすくしています。弾には無駄な情報も多いですが楽なので利用します。
まずGame_Bullet.jsを作成しクラスを作成します。プラグイン追加も忘れずに。

Game_Bullet.jsを追加 

基本的には初期化関数やアップデート関数をオーバーライドしているだけですが、initialize()内でsetParams()を、refresh()内でsetImageData()を読んでいます。これらは弾の当たり判定の範囲や画像データなど弾固有の情報を初期化するものです。後ほどGame_Bulletクラスを継承して新たにクラスを作成する時にまた説明します。

これで一応弾を出すことができるようになりましたが、まだ生成部分の処理を作っていないので画面は何も変わっていません。試しに入力をされたらプレイヤーが弾を出すようにしてみましょう。

Game_Player.jsに追加
 
既存のupdate関数を以下のように変更

これでZキーを押すとなんか変な光みたいな画像が表示されたと思います。まだ移動処理なども書いてないのでその場から動きませんが。SceneManagerはRPGツクールのシーンを管理しており、グローバルに定義されているのでどこからでもアクセスできます。内部に現在のシーンを保持しているのでそこからAddSprite関数を呼び出しましょう。
次はこれらの管理をする弾幕クラスを作成していきます。これは特に実体もなく画像もいらないので全て自作してしまいます。ひとまずの実装を書きます。プラグイン追加も忘れずに。

Shot.jsに追加 


addBullet関数でShotクラス内のArray配列であるbulletsに弾を入れ、同時にスプライトも登録してしまいます。
これは弾幕全体のスーパークラスであり、これを継承して更にPlayer_ShotクラスとEnemy_Shotクラスを作成します。generate関数やcollide関数、controlBullet関数は継承した先でオーバーライドします。
というわけで、Player_Shotを作成して自機についての処理を完成させてしまいましょう。

Game_Player.jsに追加


update関数を以下のように書き換え

これで先ほど表示された光が前方に向かって飛んでいくようになったと思います。ただし弾が画面外に行くようになってしまいました。現状画面外にある弾がいつまでも表示されているので、これを削除するようにしたいと思います。

Scene_Shooting.jsを変更
update関数に以下を追加

これで弾が消えるようになりました。以降衝突などで弾を消したいときは弾のqctiveの値をfalseにしてあげれば勝手に消えます。
 
現状Game_Bulletクラスに書いたてきとうなパラメーターの弾を生成していますが、自機用にGame_PlayerBulletクラスを作成しそれを生成するようにしましょう

Game_Bullet.jsに追加

Game_Player.jsを変更
generateEvent関数を以下のように書き換え

はい、画像が変わったと思います。弾の種類を増やす時はsetImageData()で弾の画像を、setParams()で弾の情報を書き換えるだけで増やすことができます。

ここまでで自機の実装と、基本的な機能の実装ができました。

次は敵と敵弾幕を実装...と言いたいのですがぶっちゃけここからはただのゲーム作りになってしまうので説明は割愛します。時間もないですし......
せっかくなので実装した部分までのソースコードはgithubに公開しておきます、記事の最後の方にあります。微妙にブログ用に修正したのと違いますが。敵の実装とかがすでに適当なのであまり参考にしない方がいいです。あとあくまで説明用に作ったものなのでゲーム部分はかなり適当です。当たり判定とかもっと色々できそうですね。関数は用意してありますしシューティング作りたいと思った方は自分で実装してみてください。
あとはエフェクトとかもつけてもいいかもしれませんね。弾から当たり判定抜いたものを作るだけで実装できそうです。というか弾のrangeを0にするだけでエフェクトと言い張れなくもなさそうです。

補足

RPGツクールはF2キーを押すことでFPSを表示させることができます。デフォルトは50FPSでいじる方法があるのかは知りませんが、それで見た感じかなり弾を出してもFPSは維持されていました。画像にこだわったりしたらブラウザで動作するかなり本格的なシューティングゲームが作れるのではないでしょうか。
他にもデバッグ用の機能が色々あるっぽいのでとりあえずファンクションキーとか押しまくってみるといいと思います。

では結構な長さになってしまいましたが読んでいただきありがとうございました。
明日はJpREOTTOくんによるまったり🍵とした内容を書くばい(放課後~)です。
 
Github
https://github.com/OrishigeMasato/RPG_ShootingPlugins