2015年12月17日,スパイクチュンソフトからゲーム作成ツール「RPGツクールMV」(PC / Mac:以下ツクールMV)が発売された。RPGツクールというものについて聞いたことのある人は多いと思う。RPGツクールは昔懐かしい感じの2Dスクロール型RPGを手軽に作れるというゲーム作成ツールだ。「MV」は,バージョンアップを重ねたその最新版である。
ゲーム業界的に一つのトピックではあるとはいえ,RPGツクールというと,もっぱら“ああいったゲーム”を作るものであって,長年使ってきたツクラー勢以外はほぼスルーしてしまう話題かもしれない。それでも今回のアップデートに注目したほうがいい理由がいくつかある。
まず,HTML5出力によりスマートデバイスでもゲームの実行ができるようになった。以前紹介されていたPliCyもツクール系のゲームをHTML5に変換してスマートフォンで実行できたのだが,正式に本家も対応してきたわけだ。
さらに,実行部がHTML5化されたことに関連しているのだが,プラグインによってさまざまな拡張が行えるようになった。シナリオやグラフィックスは違ってもシステムは同じというワンパターンなゲームから脱却する可能性が出てきたわけだ。
かなりモダンな方向への転換であり,とくに「スマートフォン用のゲームを簡単に作れないだろうか」といろいろ探していた人には見逃せないものといえるだろう。
体験版も公開されているので,早速確認してみよう。
リンク:RPGツクールMV30日間体験版はこちら
リンク:
Amazonで買う 体験版のダウンロード前にはライセンスを確認しておくようにしたい。この手のツールでは手を出す前に確認しておかないと無駄足を踏むことも多いのだ。さて,作成したゲームについては,ツクールMVの正規ユーザーであれば作成したゲームの公開は問題なく行える(素材や内容で著作権的に問題があるものは除く)。基本素材については,配布時にライセンステキストを入れておくだけで大丈夫だ。追加素材では記入するライセンスの量が増えていく感じだ。最低限,KADOKAWAのライセンス表記は必要になる。
なお,体験版は1か月の使用期限がある以外,製品版とできること自体は変わらないが,作ったゲームなどの公開は禁止されている。公開したい人は素直に製品版を購入しよう。製品版にはいろいろオマケがついているようだが,以下で説明する作業はすべて体験版と同じバイナリをインストールして製品版のライセンスをもらった状態,つまり実質,体験版と同じ環境で行っているので体験版でも問題なく実行できる。
■さっそく触ってみよう
ダウンロードしてインストールして起動するまではとくに説明する必要もないだろうから,公式サイトに行ってささっと進めておいてほしい。
とりあえずなにか作ってみよう。
ファイルメニューから新規プロジェクト作成を選ぶと,最初に聞かれるのが,
「名前」と「ゲームタイトル」
だ。
「なんの名前だよ?」という感じだが,ここではそれぞれプロジェクト名とゲームのタイトルを入れる。プロジェクト名を入れると,自動的にゲームタイトルが書き換えられるのがちょっとナンだが,通常はプロジェクト名とゲームタイトルは変えておいたほうが分かりやすいと思う。
これらを入力してOKボタンを押すとエディタが起動して,緑の芝生上にキャラクターらしきものが立っているのが分かる。とりあえずこのまま実行してみよう。上段にあるメニューの右端に実行ボタンが付いているので,それを押す。
とくに面白いことが起きるわけではないが,選んだ覚えもない起動画面に先ほど入力したゲームタイトルが表示されるので,ニューゲームを選択しよう。すると,エディタで見かけた緑のフィールドが表示される。とりあえず,キーボードやマウスクリックなどでキャラクターを動かせるのを確認できるはずだ。
いったんゲームを閉じて,中身を作っていこう。マップの作り込みは,やり始めるとキリがないので,ここでは適当に要点だけ押さえていくことにする。
まず,マップに街を作ろう。エディタのチップパターンを眺めていると街っぽいパターンも見つかるはずだ。パターン一覧の下のタブでBかCに切り替えて適当に探し,とりあえず,それを配置する。
街の中も必要になるだろう。ツールの左下にあるツリービューのところ(まだほとんどツリーにはなっていないが)でMAP001にマウスカーソルを合わせて右クリックメニューを開く。ここで「新規..」を選択すると,そのメニューを開いた階層の下にマップが作られる。名前やマップの大きさなども指定できるが,そのままOKを押してマップを作成してみる。
すると,いかにも「なにも作成されていません」といった風体の画面が開かれる。とりあえず,パターンを適当に選んでぐりぐりとマウスを動かし,マップを埋めてみよう。上のメニューバーには塗りつぶし機能もあるので活用したい。とにかく,いじっていればなんとなく地形エディタの挙動も分かるだろう。縁取りや継ぎ目などは結構が細かい処理がされていることも分かる。
ここではマップを作り込むことが趣旨ではないので,適当に埋めたら,建物的なものがほしかったので適当に塔っぽいものを置いてみることにした。
さらに室内のマップを作っていく。このマップの階層のところからメニューを開いて新規マップを追加する。適当に床っぽいパターン(ないな……。設定でタイルセットを切り替え)で四角を埋めるだけにしておこう。
これで,
MAP001 フィールド
MAP002 街?
MAP003 部屋
の3つのマップができた。
このまま動作確認してもいいのだが,まだマップ間を移動する処理を加えていないので,街が追加された草原にしかならない。移動処理を加えよう。
ツクールのエディタは,地形パターンをエディットするモードとイベントをエディットするモードの2種類の動作モードがある。上のメニューからオレンジ色のコケシのようなアイコンを選択するとイベントモードに切り替えができる。
切り替えた状態でMAP001に追加した街のパターン上をダブルクリックしてみよう。ここでは4パターンサイズの街を置いてしまっているが,まあここはサンプルなので左隅だけで勘弁してほしい。
これでイベントエディタが起動され,出現条件だとか画像や実行内容だとかいったものを指定できるようになる。このあたりからヘルプだけではまったく手に負えなくなってくるのだが,考えても分からない種類のものなので,とりあえず先に進めたい。
出現条件などは無視して,実行内容の最上段をダブルクリックしてみよう。イベントコマンドの一覧が表示されるので,だいたいどんなことができるのかは分かってくる。今回やりたいのはタブの2ページめの先頭にある「場所移動」だ。
場所の直接指定でマップのところをクリックすると,マップ一覧とマップが表示される。MAP002を選んで移動したい地点を指定して,OKで終了する。実行内容を指定したら,トリガーの部分を「決定ボタン」から「プレイヤーから接触」に変更しておく。
当然,MAP002から室内のMAP003へも同様に移動を指定する。
次にMAP003だが,室内でなにも起きないのは寂しいので,モンスターを置いてみよう。マップのイベントモードで適当な場所をダブルクリックし,先ほどはスルーしていた「画像」の部分(空き欄)をダブルクリックしてみる。すると画像一覧が表示されるので,Monsterの項目から適当に選ぼう。
続いて実行内容の最上段をダブルクリックし,今度はタブの3ページめの先頭にある「戦闘の処理」を指定しておこう。登場させる敵グループはデフォルト状態だと種類が少ないので,先ほど指定したモンスターがいないかもしれないが,適当になにか代わりを指定しておく。トリガーを接触にしておくのはこれまでと同じだ。
この状態で実行してみると,マップ→街→街の中→塔→室内と移動でき,モンスターのところまで行くと戦闘が開始されるはずだ。
なにも作っていないが,戦闘処理はデフォルトキャラクターの設定でちゃんと進められていく。キャラクター名まで勝手に決まっていることが分かる。もちろんこのあたりは自由に変更が可能なのでご安心を。
なんとなく簡単にゲームが作れそうな気はしてきただろうか。
■難しくはないが分かりやすくもない?
とはいうものの,このツクールMV,長年続いているツールであるためか,そこかしこに「一見さんお断り感」が漂っており,正真正銘の一見さんである私としては,一見さんにお勧めしていいのかどうか悩むところではある。正直に言えば,「一見さんには地雷」である可能性が高い案件という認識だ。
ツクールMVは,ぱっと見では,「2Dスクロール型の定形RPGが作れますよ」というシステム&ツールなのだが,いろいろ見ていくと結構いろんなシステムが搭載されていることも分かる。ただ,情報への導線が少ないのだ。
このツールを使うために用意されている情報というと,非公式なものを除くと,
体験版に付属するPDFマニュアル
体験版に付属するヘルプファイル
公式サイトの情報
ツール内のツールチップ
ということになる。ただし,これらだけでは機能が網羅されているとは言いがたい。公式サイトなどはいきなり上級編の内容だ。
加えていうと,体験版にはサンプルプロジェクトが付属していない。ドキュメントによれば製品版には大量についてくるらしいのだが,試しに体験版を落としてみたという人相手にはかなり不親切な感じではある。ヘルプを見ても「TPってなに?」といった情報すらまったくないまま話が進んでいたりする(※TPはタクティカルポイント。戦闘中に溜まり,超必殺技的なスキルの起動に必要となる)。一見さんは相手にされていない感がアリアリである。
今回の記事作成にあたって「サンプルはないんですか?」と問い合わせてもらったところ,「公式サイトにありますよ」という回答だった。しかし,当時公式サイトにあったのはサンプルの実行リンクだけであって,ダウンロードリンクは製品発売時点でようやく追加されていた。うーん,知りたいのはどういうことができるのかではなく,どういうふうにやればいいのかで,それは実例を見るのが手っ取り早いのだが。
昔話になるが,ボーカロイドの初音ミクが発売された直後に,早速入手したものの,サンプルがまったく用意されていないのを見て速攻でアンインストールしたときのことを思い出す。一般的でないツールでサンプルを用意しない開発者が作ったツールなど使いやすいわけがない。
とはいえ,そう愚痴ばかりも言っていられない。いろいろ探してみたのだが,結局,ゲーム作成の部分は旧製品とあまり変わらないということで,RPGツクールVX Aceの公式サイトにある講座の部分を見るのが一番参考になりそうだと分かった。ツールの使い方,ゲームの作り方についてはこちらを見るのが一番だ。というか,これがないと話にならない。早く講座もバージョンアップしてほしいものである。
リンク:RPGツクールVX Ace初心者向け講座
なお,ツクールMVではツールのほとんどの部分でツールチップが出るようになっており,非常に役立つ。ただし,ツールチップはやや開きにくい感じだ。Windowsのたいていのツールではリージョン内にマウスカーソルが載っていればツールチップが開くのだが,本作では完全静止で一定時間置かないといけないようなので少し意識しておくとよいだろう。
ということで,以下では体験版を試そうと思っている一見さんのために,基本的な操作を具体的に交えつつツールの可能性についてまとめてみたいと思う。
なお,ちらっと書いてあるとおり,私はツクールを使うのは初めてであり,基本的に「一見さん」の域を出ていないので,すでにツクラーな人にはいまさらな話も多いと思うが,そういった部分は華麗にスルーしておいていただきたい。今回の対象読者は,「ツクールってあるのは知ってるけど……」と興味は持っていたものの手を出しそびれていた人や「簡単にスマホのゲームができるなら」と興味を持った人が中心である。
■イベントとスイッチの処理
以下では,とくに分かりにくいと感じたイベント周りを,実際の手順を中心に紹介してみたい。分かりにくいとはいっても,「難しい」というより概念が分かりにくいとか,どこでなにをするとどんなことができるのかが把握しにくいという感じではある。
イベント処理でまず理解する必要があるのが,イベントの出現条件とイベントの実行条件が独立していることではないだろうか。当然ながら,出現していないイベントは発動できない。実行条件だけにまとめられそうな気もするが,イベントが多くなるとこのような分け方のほうが処理が軽くなるのだろう。
ちなみに,
公式サイトで公開されているサンプルの「LivingShipCowboy」では出現条件はあまり使わず,実行内容の部分で条件分岐を行っているものが多いようだ。まあ,そういう実装方法もできるということだ。
●出現条件
イベントモードにしてマップのマスをダブルクリックするとイベントエディターが起動する。そこの「出現条件」のところには6個のチェックボックスがあり,複合した条件を指定することができることが分かる。
最初は分からないであろう概念の一つ「スイッチ」がここで登場する。これは,ツールチップなどを見ると,いわゆる「フラグ」であることが分かる。直後に「変数」というものがあって「どっちも変数だろ?」と思わなくもないのだが,boolean型(ブーリアン型,論理型:真と偽のどちらかの値しかとらない変数)のものはスイッチとして分離しているようだ。とにかく,2個のフラグを複合して使えることが分かる。
そして次に「変数」だが,これはシステムが管理する変数エリアを順に使っていく感じのグローバル変数となる。伝統的に整数を使うようだ。
設定できる条件は定数との比較,それも「以上」の場合のみと限定的で,「変数0001がAからBの範囲」といった場合は,多少複雑な感じになる。
次に出てくる「セルフスイッチ」というのも謎な単語なのだが,これは,そのイベントだけで使えるboolean型の変数を意味しており,一つのイベントで4個まで使うことができるとされている。いわゆるローカル変数というものともちょっと違う気がするのだが,操作できる範囲を考えると,EVページ(後述)を駆使する際に活用されるものなのだろう。
続く,「アイテム」と「アクター」は分かりやすい。特定のアイテムを持っている場合と,パーティに特定のキャラクターがいる場合に発動されるイベントを記述するためのものである。
●トリガー(実行条件)
出現条件はかなり細かく設定できるものの,トリガー,つまり実行条件の設定は簡素である。基本的には,プレイヤーキャラクターがぶつかるか,その場所で決定ボタンが押されるかといったゲーム内の直接的な行動が実行条件に設定されるようになっている。細かい条件は出現条件で指定していくのが基本的な使い方といえそうだ。
選択できるのは以下の5種類。
決定ボタン
プレイヤーから接触
イベントから接触
自動実行
並列処理
「決定ボタン」と「プレイヤーから接触」はほぼ言葉そのままの動作だ。イベントを設置した位置かそれに隣接する位置で,決定ボタンを押すか,その場にあるオブジェクトの方向に進んだときに発動する。
実行条件でちょっと分かりにくい「イベントから接触」というのは,動き回るモンスターがキャラクターに接触したときに起きるもので,戦闘などで使われるらしい。内容的にキャラクターからの接触と同じではないかという気もするのだが,メッセージや先制攻撃の有無などを変えたいこともあるのだろう。
自動実行や並列処理はトリガーなのかといわれると微妙だが,出現条件が成立した途端に実行されるという意味では実行条件を示しているといえなくはない。出現条件,実行条件,動作モードといった分け方にしたほうが適切ではないかという気はするが。
自動実行の場合はプレイヤーの処理ができなくなるが,並列処理の場合は動き回ることもできる。
なお,ツールチップでは,自動実行の場合は1回のみの実行で並列処理の場合は繰り返し実行されるような記述になっているが,自動実行の場合でも出現条件が成立している間は処理が繰り返されるようだ。つまり,イベント処理中に出現条件を消さないと無限ループでハングアップする。強制イベントなど以外では並列実行のほうが使いやすいだろう。
こういった変数的な条件で起動する自動実行や並列処理の場合,設置場所を問わないものがあるが,イベントシステムは場所に紐付いているので,マップ内のどこかのチップに埋め込んでおく必要がある。「じゃあすべてのマスでイベントを使っているとどうなるのか?」と心配する向きもあるかもしれないが,そういった場合でもEVページを使えば対応できるので問題ない。ちゃんと,砂漠マップの全マスでダイヤを探すようなゲームも作れるので安心してほしい。
■イベント処理の実際
では,いくつか実際にありそうな処理を作ってイベントの動作を確認してみよう。
なお,先ほどはマップ内に塔を置いて,その一部にイベントを埋め込んだわけだが,マニュアルを読む限り,イベント側でグラフィックスを指定するのが筋ではあるようだ。動的なオブジェクト以外はマップに直接書き込んでも問題はなさそうに思われるが,一応留意しておこう。
●オブジェクトに触れると現れるオブジェクト
マップ上にあるものに触れると登場するオブジェクトを実装してみよう。今回作るのは,一度触れると現れ,もう一度触れると消えるという仕様だ。
マップ内の任意の地点をダブルクリックしてイベントを埋め込んでいく。場所はどこでもかまわない。
まず,ON/OFFを切り替えるためにスイッチを使用する。スイッチはどこで設定するのかというと,あらかじめ20個ほど作成されているので,どれかを使えばよい。番号で0001〜0020まで用意されているのだが,それぞれにラベルを付けることもできる。分かりやすい名前をつけておこう。
イベントの実行内容をダブルクリックしてイベントエディタを起動しよう。今回は,ON/OFFの切り替えなのでフロー制御のところにある「条件分岐」を利用する。
ここでスイッチの選択が出てくる。0001番を選び,適当な説明をつけておこう。ここでは「表示制御」としたが,ゲームが複雑になってくるとマップ名なども書き添えておくのがよいかもしれない。
さらに一番下ある「条件を満たさないときの分岐を作成」をチェックしたうえでOKを押す。
ここで指定するのは,
・スイッチがONならOFFに
・スイッチがOFFならONに
切り替えるという内容だ。
次に出現するオブジェクト側の処理を実装する。ここでようやくイベントの「出現条件」を使うことになる。スイッチで0001を指定すると,0001がONになったときにイベント自体が有効になる(イベントの内容が実行される条件ではないので注意)。
ここで画像を指定しておけば,先ほどのオブジェクトに触れるたびに,こちらの表示/非表示が切り替えられることになる。
●スイッチの切り替え
先ほどのは接触時のリアクションのないイベントだったが,今度は,左側に倒れているレバーを右に入れるなど,ゲーム内にあるスイッチをビジュアルに切り替える処理を実装してみよう。
さて,イベントエディタから選択できる処理には,なぜかグラフィックスの書き換えや表示指定がない(1枚絵用ならあるが)。では画像で指定されたイベントオブジェクトをほかの画像にしたいときにはどうすればいいのだろうか。
ここで使うのが「EVページ」だ。イベントの2ページめを作成して,2ページめの画像を別のものにしてやればよい。ページの切り替えは,イベントの「出現条件」で制御する。ここは接触ではなく,ボタン操作をトリガーにするのがいいだろう。
使用する画像は,タイルセットの!Switch1にあるレバーを右向きと左向きで選択した。EVページ1でスイッチ#0002をONにし,EVページ2でスイッチ#0002をOFFにするのだが,出現条件はEVページ2だけに指定しておけばよい。#0002がONなら右向きのレバーが上書きで表示される指定になるので,OFFのときはEVページ001のものがそのまま表示されることになる。
●追加のグラフィックス切り替え
これでボタンを押すたびにカチカチとレバーを切り替えることができるようになった。ついでに,スイッチを押すと入り口をふさいでいたものが消えるような仕様にしてみよう。ただ,前述のようにイベントエディタのコマンドでは画像の表示などは指定できないため,レバー切り替えで操作されたスイッチの状態を見て表示/非表示を切り替えるオブジェクトを置くことにする。
次のマップへの入り口で立て札のような障害物を設置し,イベントページの2ページめになにもない画像を指定して(=画像を指定せずに),障害を回避できるようにしよう。
先ほどと同様に,EVページ2の出現条件に0002を指定してやればよい。さらに,通路が開いた状態では次の部屋への移動も行うので,接触条件でマップ移動を指定しておこう。これでスイッチで通路が開き,先のマップに進めるようなイベントが構築できた。
なお,EVページ2に立て札を置いて,EVページ1側に出現条件を指定した場合はまったく動作しなかった。なぜかと調べると,条件が両方とも成立する場合はページ数の大きなものが実行されるとあった。
つまり,
a) 1× 2× どちらも実行されない
b) 1× 2○ 2が実行される
c) 1○ 2× 1が実行される
d) 1○ 2○ 2が実行される
のようになるため,上記のb)の状態からd)の状態にしても1が実行されることはないわけだ。
■超入門プラグイン作成編「左にちょっと寄せる」
さて,デフォルトの戦闘画面では正面にモンスターが現れ,パーティが正対して戦っているような構図になっている。これはツクールシリーズではお馴染みのものらしいが,今回のMVではサイドビュー戦闘が搭載されたこともトピックの一つになっている。簡単に切り替え可能なので,そちらも確認してみよう。
上にあるメニューの歯車のアイコンから(またはツール→データベース→システム→オプション)見ていくと,「サイドビュー戦闘を使用」というチェックボックスが目に入るだろう。これをチェックすると戦闘画面が変更されるわけだ。
ただ,実際にやってみるとプレイヤー達はきちんと右側に列を成しているものの,モンスターが画面の真ん中にでんと居座っており,バランスがよくない。とりあえず,これを少し左側に寄せてみたい。
とはいえ,そのような指定ができるシステムではないようなので,プラグインを作って対応することにする。いきなり内容が初級編から離れてしまうが,こういったプラグインが簡単(?)に作れることが今回のMVの最大の特徴でもあるのだ。本稿は基本的に一見さん向けの記事ではあるが,一見さんといってもほかでの開発経験がある人もいるだろう。ツクールMVのプラグイン機能に興味を持つ人も結構いると思われるので,少々技術的なところにも踏み込んでみたい。
まず,モンスターの表示をどこでやっているのかを調べる必要がある。
実行部のJavaScriptコードはすべてプロジェクトごとにあるjsフォルダ内に格納されているので,その中を探せばよい。
いちばんサイズの大きなrpg_objects.jsを開いてつらつらと眺めてみれば,なんとなく敵の処理でのキーワードは「Enemy」であることが分かるだろう。Windowsであれば,jsフォルダを開いてフォルダ内検索(Ctrl+[F]キー)で「Enemy」を探すと,6ファイルが関連していると分かる。
ついでながら,スクリプトを眺めていれば,登場キャラクターは敵味方すべて含んで「Actor」で,プレイヤー側の集団は「Party」,モンスター側の集団は「Troop」といったキーワードで表されていることも分かる。
目的の部分は,結論から言えば,前述のrpg_objects.js内なのだが,このファイルはゲーム内で使用するオブジェクトとメソッドをまとめて定義してあるような部分なので,ゲーム内容に関する部分を操作するプラグイン作成では多用するファイルになるだろう。
rpg_objects.jsをテキストエディタで開いて具体的にどこでどのように「Enemy」が使われているのかを見てみると,初期化している場所,設定している場所,表示している場所などが目当ての場所らしいと見当がつく。Enemyにx座標を与えている部分だからだ。
試しに,Game_Enemy.prototype.setupの,
this._screenX = x;
の部分を,
this._screenX = x - 150;
と書き換えて実行してみると,ちゃんと左側に寄せて表示され,攻撃エフェクトなどもズレずに実行されていることが分かる。
正直,「プロジェクトごとにスクリプトは別管理だし,このままでもよくね?」という気もしないではない。
ツクールMVではゲームの実行部分がすべてJavaScriptで記述されており,利用規約を見ても「改変すんな」的な記述がない点が素晴らしい。そのままガリガリ書き換えてもOKなのではあろうが,非常に拡張しやすく作られているのもまた特徴である。必要に応じて機能をオーバーライドしてプラグイン化する方向が推奨されているので,この機能をちゃんとプラグイン化してみよう。
ちなみにオーバーライドとは,元からあったオブジェクトを上書きで置き換えるような処理のことだと思っておけばよいだろう。今回書き換えるのは,Game_Enemyオブジェクトのsetupメソッドだ(※prototype云々はややこしい話になるので,とりあえず定義するときはprototypeをつけて,使うときは抜いて使うものだと思っておこう)。
Game_Enemy.prototype.setup = function(enemyId, x, y) {
this._enemyId = enemyId;
this._screenX = x;
this._screenY = y;
this.recoverAll();
};
上記のように関数を抜き出しておき,js/pluginフォルダ内にSideShift.jsというテキストファイルを作成して,
(function() {
var shift = -150;
Game_Enemy.prototype.setup = function(enemyId, x, y) {
this._enemyId = enemyId;
this._screenX = x + shift;
this._screenY = y;
this.recoverAll();
};
})();
というコードに書き換えて保存する。ざっと見ただけでも書き換え前のコードとほとんど同じだということは分かるだろう。ここでは「書き換えたい部分を抜き出してこんな感じにする」ということだけ覚えておいて,気になったらオブジェクト指向の本をなにか読むのがよいだろう。
このように関数を丸ごと抜き出せばかなり大胆な変更もできそうだということは分かるだろうが,ちょっとした変更でいい場合には,かなり大仰な書き方になってしまう。今回の例でも,実質1行書き換えるために関数を丸ごと再定義するのは効率が悪いと考える人もいるかもしれない。
ツクールのプラグインを見ても多用されているのが,元の処理に戻す形のプラグインだ。今回の例だと以下のようになる。
(function() {
var shift = -150;
var _Game_Enemy_prototype_setup = Game_Enemy.prototype.setup;
Game_Enemy.prototype.setup = function(enemyId, x, y) {
_Game_Enemy_prototype_setup.call(this, enemyId, x+shift, y);
};
})();
もはやなにがどうしてこうなるのか説明が難しいのだが,書き換える前の処理を行うオブジェクトを先に呼び出しておいてから中身を書き換え,その途中で元の処理を呼ぶという感じになっている。変数名の付け方を含めて,ツクールMVでのプラグイン作成ではこういうふうにするものだと思っておこう。
面倒な書き方だが,コードを書き換える部分を最小にすることで,ほかのプラグインとの競合を少なくするという意味もある。同じようなところを個別でハックしていると予想外の動作になってしまうというのは容易に想像できるだろう。ツクールMVではプラグインの導入が手軽にできるようになっているが,プラグインの原理上,運用には注意が必要になることを覚えておこう。
ところで,これらの処理では単純に敵の出現位置を左にずらしているだけなので,たくさんの敵が出てきたら画面外にはみ出したり,サイドビューをやめたときに左寄せの表示になることが考えられる。
ゲーム中でフロントビューとサイドビューを混在できるかは不明だが,標準ではできそうにない。ツクールに付属のSimpleModeSideView.jsでは,向きを判定した処理が入れられているのだが,本当に必要なのか判断に困るところだ。フロントビューへの切り替えを考慮しない場合,そもそも正面向き仕様のゲームで横向き専用のプラグインを入れるのが間違いなので,プラグインを入れないようにするのが正しい対応のような気はする。今回は非対応でいこう。
さて,これまでのコードで一応所定の動作はしてくれるのだが,ツクールMVに標準で付いてくるプラグインのコードを見るといろいろと違いも見えてくるだろう。
var parameters = PluginManager.parameters();
といったプラグイン管理用コードや,注釈部分がプラグイン管理に使われていることなどが分かるはずだ。とりあえず,同じように書けばよいだけなので適当に加えておこう。
●SideShift.js(末尾にダウンロードリンクあり)
//=========================================================
// SideShift.js
//=========================================================
/*:
* @plugindesc Plugin sample to set monsters left-side.
* @author aueki
*
* @param shift
* @desc Value to add x.
* @default -150
*
*
* @help This plugin does not provide plugin commands.
*
*/
/*:ja
* @plugindesc サイドビューバトル時に敵を左にずらします。
* @author aueki
*
* @param shift
* @desc x軸方向の移動量
* @default -150
*
* @help このプラグインには、プラグインコマンドはありません。
* サイドビューバトル時に敵を左にずらします。
*/
(function() {
var parameters = PluginManager.parameters('SideShift');
var shift = Number(parameters['shift'] );
$dbgTracer ="test";
var _Game_Enemy_prototype_setup = Game_Enemy.prototype.setup;
Game_Enemy.prototype.setup = function(enemyId, x, y) {
_Game_Enemy_prototype_setup.call(this, enemyId, x+shift, y);
};
})();
ここではshiftをパラメータ化したので,コードをいじらなくてもずらす量を調整できるようになった。
とりあえず,今回はこれで完成としておく。このようにプラグイン化したことでメンテナンス性が多少は上がったはずだ。
と,プラグインを作ったあとで判明したのだが,戦闘時の敵表示位置は,データベースの「敵グループ」で設定できるとのこと。え? と思って見直したのだが,プレビュー画面のモンスターを直接マウスで個別に移動できるようだ。……まあ,いちいち設定するのが面倒な人は使ってみてほしい。
■どこを書き換えればいいのか?
プラグインによって,さまざまな部分の機能を書き換えたり付け加えたりができることは分かった。問題は,どこをどういじればいいのかという部分だろう。ツールに付属のヘルプファイルにはJSライブラリのリファレンスもあるのだが,どうにも低位の関数が多くて,そのあたりはあまりいじれる感じではない。それになんというか,もっとゲームに関連する部分をいじりたいわけだ。
結局はコードを探っていくしかないわけだが,これは完全に手探りでやるしかない。先に述べたキーワードを検索していく方法とは別のアプローチも紹介しておこう。
とりあえず,ゲームを実行してF8キーを押してみよう。開発者用ツールが出てくるのでこれを活用していく。ざっと見てもなんに使えるツールなのか分からない人が多いと思うので軽く説明しておこう。
まず,タブは「Sources」のところを開いておく。この状態で適当にゲームを進めて,右上あたりにある一時停止ボタンらしきものを押してみよう。
すると画面にJavaScriptのコードが表示されたことと思う。たいていは,
SceneManager.update
のところで止まっているのではないだろうか。
ここがおそらくメインループだ。一時停止の右隣にあるステップ実行のボタンを押していくと関数内を循環するのが分かると思う。
ステップ実行のさらに右隣にある下矢印のボタンがメインで使っていくボタンで,違う階層の関数まで順に追ってくれる機能となっている。完全に処理を追ってくれるわけではないのだが,普通のステップ実行よりは細かく見てくれる。
60分の1秒かからないような処理でも,関数ごとにポチポチとボタンを押して眺めていくと数十分はかかるかもしれない。とくに表示周りを見ると非常に多機能なのがよく分かる。正直に追っていると時間がかかるので,明らかに追いたい処理でない部分では先ほどのステップ実行ボタンをうまく組み合わせよう。
以上,手間はかかるが,処理の流れを追う意味ではこちらのツールが有用である。行番号のところをクリックするとブレイクポイントを設定できるほか,デバッグ機能でFPS表示などもできるので,F8キーで開く開発者ツールは触っておいて損はない。
英語版がSteamで先行発売されていたこともあって,すでにプラグインは数多く発表されている。同じ部分を拡張したプラグインを2種類使うとちょっと困ったことになると思われるのだが,それらは必然的にソースコードの形で提供されているので,提供される機能と書き換えられる部分をよく確認してから導入するようにしたい。可能なら機能を自分でまとめてしまうのがよいだろう。
■自動戦闘処理を実装する
さて,公式サイトで公開されているツクールMVのサンプルのゲームをつらつらと眺めていると,工夫次第でいろんな表現方法があるということが分かる。参考にはなるのだが,正直に言えば,わりとタルいものが多い。今回はほぼマウスだけで操作していたのだが,キーボードやゲームパッドであれば勝手にカーソルが動くので「ok」を連打すれば済むようなものが,明確に位置を指定しないといけないポインティングデバイスだとちょっと面倒なこともあるのだ。
ツクールMVが新たにターゲットとしている(というか,今後市場を拡大すべき)スマートフォンやタブレットは,タッチスクリーンなどのポインティングデバイスで操作するのが普通だ。そもそもスマートフォンでは,かったるい操作などはやってもらえないと思ったほうがよい。PCゲームでもカジュアル寄りのものは操作を極力簡単にすべきだろう。
ということで,プラグインで自動戦闘モードを追加してみたい。
とはいえ,AI的なものを導入するのは手間がかかるので,今回はキーボードやゲームパッドでできる「ok連打」を行うモードを追加するだけだ。大方は殴るだけになるので,戦略だなんだと言い始めるとキリがないが,こういうものを実装する場合は,それを前提としたゲームバランスにしておこう。
まず,どのあたりをいじる必要があるかだ。結果から遡って書いていくと,
・戦闘メニューに自動戦闘の選択肢を加える
・戦闘メニューの判定部分に分岐先を加える
・メニュー処理で自動戦闘モードであることを示すフラグを立てる
・自動戦闘モードの場合に入力を置き換える
・戦闘が終了したときに自動戦闘フラグを下げる
といったものが必要になる。いろいろ探していくと,順に,
Window_PartyCommand.prototype.makeCommandList(rpg_window.js)
Scene_Battle.prototype.createPartyCommandWindow(rpg_scene.js)
Scene_Battle.prototype.commandAuto(新規制作)
Input.update(rpg_core.js)
BattleManager.endBattle(rpg_manager.js)
のようになる。
複数箇所の変更になるが,プラグインとしては,一つにまとめることが可能だ。
どうやって探してどう書き換えたかについては,もう試行錯誤の末としか言いようがない。探す手法はすでに述べたとおりだが,今回の場合,ほとんどはソースリストのサーチで,入力部分については実行時のトレースが起点となった。
新規作成部分はrpg_scene.jsに入るべき内容だが,プラグイン側で新たに用意することにした。このほかに,フラグ用のグローバル変数$autoModeを用意している(最初はゲーム内変数でやってみたが,うまくいかなかった)。
●メニュー項目の追加
rpg_window.jsを見ると,fight,escapeなどが並んだ部分があり,戦闘前のコマンドリストを作っていることが分かる。その並びに自動戦闘のコマンドを入れよう。
Window_PartyCommand.prototype.makeCommandList = function() {
this.addCommand(TextManager.fight, 'fight');
this.addCommand(TextManager.escape,'escape', BattleManager.canEscape());
};
この末尾に,
this.addCommand('自動', 'auto');
を加えるだけである。ほかのコマンドはテキストマネージャで文字列を管理しており,カスタマイズしてコマンド名を変更可能になっているのだが,独自に加えるメニューではそのようなことはできないので,文字列を直接埋め込んでいる。
行数も短くならないので関数をそのまま抜き出して該当箇所だけ書き加えている。同じタイミングで別のコマンドを追加したい場合はここを使うことになるだろう。
●メニュー処理に分岐先を追加
コマンドハンドラでの処理先の指定は,ほかのコマンドをまねたものを書き加えている。
this._partyCommandWindow.setHandler('fight', this.commandFight.bind(this));
this._partyCommandWindow.setHandler('escape',this.commandEscape.bind(this));
同じ並びにある「戦闘」と「逃げる」が上記のようになっているわけだから,
this._partyCommandWindow.setHandler('auto',this.commandAuto.bind(this));
のようなものを加えている。この時点では「commandAuto」といった関数は存在しないが,これは次で作成することにする。
追加部分を処理の途中に挟み込む形になるので,ここも関数を丸ごと抜き出してプラグインに書き加えている。
●コマンドの処理
上記では存在しない関数を指定しているので,その実体を作成しよう。処理内容としては,$autoModeのフラグを立てるだけだ。一応,$autoModeになっているときに呼ばれた場合はフラグを降ろすようにしている。「ok」の処理が行われていることも明示しておく。
if($autoMode==0){
$autoMode=1;
Input._currentState='ok';
}else{
$autoMode=0;
}
ほかのコマンドを見ると,
this.selectNextCommand();
が実行されているので,その処理を加えておこう。
そのほか,デバッグ用にコンソール出力なども加えているが,プラグインの処理には影響しない。開発者ツールでは実行を一時停止すれば全変数の内容を見ることができるのだが,実行を止めずに確認したいなら開発者ツールのコンソールも有用だ。
●キー入力の差し替え
今回一番苦労したのはキー入力をフックして代わりの入力に差し替える処理だった。結果だけ見れば「そりゃそうだよね」という単純なものなのだが,あちこちいじって結局ここに落ち着いた感じだ。
キー入力やゲームパッドからの入力は内部コマンドに置き換えられるので,そのコードである「ok」を入力内容として指定し,通常の入力処理を行っている。
this._latestButton = 'ok';
this._pressedTime = 0;
this._date = Date.now();
現状では連打を前提とした「ok」相当のボタン入力をシミュレートしているわけだが,AI処理(体力なくなると回復するとかTPが溜まるとスキルをぶっ放すとか)などを追加で実装する場合には,入力コマンドをパラメータとして渡すようにしたほうがよいだろう。
●自動戦闘の停止
戦闘が終了した場合には自動戦闘のフラグを降ろしてやる必要がある。その処理を行っているBattleManager.endBattleの部分に処理を追加している。
$autoMode=0;
●おまけ:アニメーションの高速化
すでに自動戦闘はできるようになっているのだが,試してみるとサクサク感が足りないので,戦闘時の速度アップを図ってみよう。まず,エフェクトアニメーション速度を上げる処理を加えておく。
rpg_sprite.jsから,
Sprite_Animation.prototype.setupRate = function() {
this._rate = 4;
};
の部分を書き換える。
ついでながら,プラグインのパラメータとして値を渡せるようにしておこう。値は小さいほど高速で,0の場合はアニメーションがキャンセルされる。
ムービー(※4Gamerへジャンプします)
ムービー
(※4Gamerへジャンプします)ムービー
(※4Gamerへジャンプします) 次にサイドビュー限定となるが,武器使用時のアニメーション速度を上げてみよう。
rpg_sptite.jsにある,
Sprite_Weapon.prototype.update = function() {
Sprite_Base.prototype.update.call(this);
this._animationCount++;
if (this._animationCount >= this.animationWait()) {
this.updatePattern();
this.updateFrame();
this._animationCount = 0;
}
};
の部分で_animationCountを余分に進めてみる。ここもパラメータ化すると,
this._animationCount+=step;
のような感じになる。
ムービー(※4Gamerへジャンプします)
以上をまとめると次のようになる。
●AutoBattle.js(末尾にダウンロードリンクあり)
/*:
* @plugindesc Auto battle mode
* @author aueki@4Gamer
*
* @param speed
* @desc Battle effect wait rate.(original=4:smaller is faster)
* @default 1
*
* @param step
* @desc Battle animation rate.(original=1)
* @default 3
*
* @help This plugin does not provide plugin commands.
*
*/
/*:ja
* @plugindesc 戦闘時に自動戦闘モードを追加します。
* @author aueki@4Gamer
*
* @param speed
* @desc 戦闘時の武器エフェクト速度を指定します(original=4:小さいほど高速)
* @default 1
*
* @param step
* @desc サイドビュー戦闘時の武器モーション速度を設定します(original=1)
* @default 3
*
* @help このプラグインには、プラグインコマンドはありません。
*
* 戦闘時に「ok」ボタンを連打するモードになります。
*/
var $autoMode = 0;
Scene_Battle.prototype.commandAuto = function() {
if($autoMode==0){
$autoMode=1;
Input._currentState='ok';
}else{
$autoMode=0;
}
this.selectNextCommand();
console.log("auto :"+$autoMode);
};
(function() {
var parameters = PluginManager.parameters('AutoBattle');
var speed= Number(parameters['speed'] );
var step= Number(parameters['step'] );
var Input_update=Input.update;
Input.update = function() {
if($autoMode==0){
this._pollGamepads();
if (this._currentState[this._latestButton]) {
this._pressedTime++;
} else {
this._latestButton = null;
}
for (var name in this._currentState) {
if (this._currentState[name] && !this._previousState[name]) {
this._latestButton = name;
this._pressedTime = 0;
this._date = Date.now();
}
this._previousState[name] = this._currentState[name];
}
} else{
this._latestButton = 'ok';
this._pressedTime = 0;
this._date = Date.now();
}
this._updateDirection();
};
Window_PartyCommand.prototype.makeCommandList = function() {
this.addCommand(TextManager.fight, 'fight');
this.addCommand(TextManager.escape, 'escape', BattleManager.canEscape());
this.addCommand('自動', 'auto');
};
Scene_Battle.prototype.createPartyCommandWindow = function() {
this._partyCommandWindow = new Window_PartyCommand();
this._partyCommandWindow.setHandler('fight', this.commandFight.bind(this));
this._partyCommandWindow.setHandler('escape', this.commandEscape.bind(this));
this._partyCommandWindow.setHandler('auto', this.commandAuto.bind(this));
this._partyCommandWindow.deselect();
this.addWindow(this._partyCommandWindow);
this._waitCount = 2;
};
BattleManager.endBattle = function(result) {
$autoMode = 0;
this._phase = 'battleEnd';
if (this._eventCallback) {
this._eventCallback(result);
}
if (result === 0) {
$gameSystem.onBattleWin();
} else if (this._escaped) {
$gameSystem.onBattleEscape();
}
};
Sprite_Animation.prototype.setupRate = function() {
this._rate = speed;
};
Sprite_Weapon.prototype.update = function() {
Sprite_Base.prototype.update.call(this);
this._animationCount+=step;
if (this._animationCount >= this.animationWait()) {
this.updatePattern();
this.updateFrame();
this._animationCount = 0;
}
};
})();
とりあえず作ってはみたものの,rpg_core.jsまでいじっていたり,いろんな部分に副作用が発生することも考えられるので,ほかのプラグインと組み合わせる場合は問題が要注意だ。単体で動かなくはないのだが,今回はあくまでサンプルということで,このまま実用にするのはお勧めしない。
なお,これに限らず今回掲載しているプラグインについては,メーカーから推奨されているようにMITライセンスとするので,参考になる部分があったら使ってみてほしい。
■手軽に綺麗なマップを作る:小さなマップ
さて,戦闘がタルいこと以外に感じるのは「移動がタルい」ということだろうか。これも連続的な指定ができるキーボードやゲームパッドと違って,細切れに指示が必要なポインティングデバイスでは煩雑になりがちな操作だ。スクロールすることに意義があるといわんばかりに,画面端まで行って,あとちょっとスクロールして外に出るといったマップ構成が多いのはなぜだろうか。ポインティングデバイスでは,マップはスクロールよりもページ切り替えのほうが快適になる。
マップが広いことに意味はあるのだろうかと,つらつらと考えると,
・表現力が上がり世界観を表しやすくなる
・画面が単調ではなくなる
・長距離を旅している感が出る
などといったメリットが挙がってくる。その半面,
・制作労力がかかる
・移動がタルい
・データ量が増える
といったデメリットもあるだろう。双方を勘案して判断すればよいのだが,私の場合は「個々のマップは狭いほうがいい」という結論に落ち着いた。
小さなマップ,それもスクロールが発生しない大きさとなると,情報量と表現力が限られることが最大の問題となる。ゲームマップなどのグラフィックスには,ゲーム内での記号的な意味とビジュアルでの美術的な意味の両面があるが,明らかにこのようなタイルチップタイプのマップでは記号的意味のほうが強い。今回はミニマルな表現を目指していくことにする。そのうえでどうやって美術的価値を高めるかというテクニック的な話もあるのだろうが,今回は置いておこう。
以下では,マップは1枚あたり1画面で収めることを基本に,できるだけ簡単に作成する方法を検討してみたい。自動移動での経路探索アルゴリズムは12マス先までしか見ないので,本当なら12マス範囲に抑えたいところだが,ここではデフォルトのサイズである17×13マスで考えていく。
前述のようにマップが小さいと,当然ながら表現力は下がりがちになる。ただでさえチップで組み立てていく背景は慣れないと作りにくいものであり,ちょっとゲームを作ってみようとしても多くの人がつまずくところではないだろうか。
一般的な話として,ツクールMVには多くのマップが付属しているので,それらをそのまま使ったり,ベースにしていくことが効率のよい手法となるだろう。一流のマップ職人さんが作ったものを見ていけば,それなりにノウハウも見えてくるかもしれない。
問題は,サンプルマップが1画面サイズで作成されていないことだ。そこで適当に切り取ってくることを考えよう。やり方は簡単で,適当に新しいマップにサンプルマップを読み込んで,右クリックからのドラッグで範囲指定をして,そのまま移したいマップに持っていけばいい。
なお,新しいマップは右クリックしたところの下の階層に作成されるので,慣れないと望まぬ階層に新しいマップを作ってしまうことも多いのだが,ドラッグ&ドロップで階層を変えられるのでどこにできても大きな問題にはならない。
この方法だと中程度の家でほぼマップいっぱいを占めてしまう。これはこれで使えるのだが,村や街を表現するにはちょっと苦しい。そこで小さな家をさらに削ってミニマムサイズの家を作ってみる。やろうと思えば2×3マス以下でもいけなくはないが,さすがにどうよという表現になるので,実用上は3×3マスが限界だろうか。
ここでは多少は飾り付けの余地がある3×4マスを採用して小家屋ライブラリを適当に作ってみた。屋根と壁を組み合わせれば基本形が出来上がり,飾り付けや看板で個性を出すような感じだ。
とりあえずマップに家とイベントなどを配置して,作り込みはあとで行うスタイルがよいだろう。
しかし,これだけでは外観しかないうえ,バリエーションが足りなくなるおそれがある。公式サイトからリンクされているサンプルゲームのいくつかのマップを見てみたのだが(ファイル名がだいたい固定なので,マップファイルの直接ダウンロードは難しくない),マップ数が100を遥かに超えていたりした。
この手のゲームでは室内やダンジョンも大きなウェイトを占めてくるのはいうまでもない。
室内マップの作成には「ダンジョン生成」が便利だ。タイルセットとしてフィールド以外のものを指定しておく必要があるが,壁と床を指定するだけでそれっぽい部屋をいくらでも生成してくれる。もちろん室内だけでなくダンジョンも作成できる。
使い方は簡単で,マップを指定して,右クリックメニューからダンジョン生成を選択し,各項目を指定するだけだ。部屋タイプの場合は生成パターンが少ないが,あくまでベースとして扱い,好みで手を加えていくのがいいだろう。
下は,迷路を指定して生成したものだが,迷路は部屋を指定するよりもいろんなパターンが現れ,周囲に余白も多いのでいじる余地も大きい。
生成して,なんとなくいじってみたものが下だ。
が,機能的に部屋としておかしいので,さらにいじってみる。
これなら階段ホールからの3室振り分けで機能的におかしくはない。右の出っ張りはパイプスペースで上の端は北側斜線規制かなといった合理的な推測もつく。とにかく,パターンだけだと「どれが壁でどれが床か」も判断が難しいので,その組み合わせが簡単に指定できる機能は非常にありがたい。
■自動移動を賢くするには
さて,こうして小さなマップを作ってみたのだが,やはり自動移動で引っかかることがあるのが気になる。
自動移動処理もJavaScriptで実装されているので,プラグインでちょっと賢くしてみよう。といっても,処理内容をいじる必要はない。最大探索範囲の指定部分を書き換えるだけである。アルゴリズムに興味のある人は「A*」(エースター)で検索してみよう。
今回いじるのは,rpg_object.jsにある,
Game_Character.prototype.searchLimit = function() {
return 12;
};
の部分だ。処理内容はこれだけなのでプラグイン化はまったく簡単だ。
探索範囲を拡大すると,それまでつっかえていた自動移動が非常にスムーズになる。
ただ,PCで実行している分にはまったく問題がないのだが,ここを大きくすると指数関数的に処理量が増えるおそれがある。たぶんメモリも食うことになるのでスマートフォンでは注意が必要だ。
ということで,探索範囲のパラメータをマップの複雑さに応じて指定ができるようにプラグインコマンド形式に仕上げてみた。プラグインコマンドの作り方については,ヘルプファイルとサンプルプラグインを見るのがよいだろう。そこに書かれたとおりにしておけば,ゲーム内から利用できるようになる。
このように,拡張した部分をプラグインコマンドにしておけば,イベント処理などでプラグインの機能を利用可能になる。つまりゲームの内容を記述する部分で表現力が上がるわけだ。ツクールMVの可能性を大きく広げてくれるものになりそうだ。
●ExtendSearchLimit.js(末尾にダウンロードリンクあり)
/*:
* @plugindesc Extend Search Limit
* @author aueki@4Gamer
*
* @param searchDistance
* @desc search distance for a*.
* @default 17
*
* @help plugin command: searchDistance param
* This plugin sets search distance parameter of A* at auto move path finding.
*/
/*:ja
* @plugindesc 自動移動時の探索範囲を拡張します。
* @author aueki@4Gamer
*
* @param searchDistance
* @desc 経路検索でa*に与える探索範囲を指定します(ノーマル版=12).
* @default 17
*
* @help プラグインコマンド:searchDistance param
*
* A*アルゴリズムによる自動移動での探索範囲を指定します。
*/
(function() {
var parameters = PluginManager.parameters('ExtendSearchLimit');
var searchDistance= Number(parameters['searchDistance'] );
var _Game_Interpreter_pluginCommand =
Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
_Game_Interpreter_pluginCommand.call(this, command, args);
if (command === 'searchDistance') {
searchDistance=Number(args[0]);
}
}
Game_Character.prototype.searchLimit = function() {
return searchDistance;
};
})();
ゲーム内で使っている様子とこの処理のサンプルムービーを作成したので,検索範囲の拡大がどういった内容の処理なのかを確認しておいてほしい(実はこのサンプルムービーを撮るためにプラグインコマンド化したわけだが)。
ムービー(※4Gamerへジャンプします)
なお,単体であれば,
_Game_Interpreter_pluginCommand.call(this, command, args);
の部分はなくても動くのだが,ほかのプラグインコマンドが動かなくなってしまうので注意。プラグインコマンドの場合は,ほかのコマンドと一緒にうまく動くことを確認しておこう。
■モバイル時代に向けて可能性は無限だが,立ち位置は微妙
そんなこんなでいくつか機能をピックアップして取り上げてみたが,全体を網羅するにはまだまだ足りない。JavaScriptにあまり明るくないので,あちこちとコードを眺める日が続いたためゲーム自体を作るには至らなかった。
ちなみに,今回の原稿は体験版の試用期間が10日を切ったくらいの時点でまとめている。通常の仕事をしながらなので毎日触っていたわけでもないが,だいたい15日間くらいでの作業だろうか。防具の耐性などにしても「炎耐性が上がる」ではなくて「炎属性攻撃の有効度が下がる」といったクセのある感じなので,ゲームシステムやコードにしても「なにを意味しているのか」の検証だけで終わった感じではある(まだまだ全貌は見えないのだが)。
結論めいたところをまとめておくと,ツクールMVは「こんなストーリーのゲームを作りたい」という人には向いているツールである。多くの機能があり,多少工夫は必要かもしれないが,いろんな表現ができる。基本的には標準機能の範囲で作り込んでいくことが可能だ。
半面「こういうシステムのゲームを作りたい」という人にはあまり向いていない。プラグインでそれなりに作り込めることも確かだが,労力に見合わないだろう。ツールの性格を考えると,ある意味当然な結論ではあるが,今回,拡張性を中心に見て再確認した感じだ。
使ってみるといろいろな機能があり,さらに拡張できることは分かったが,それでもベース自体が古いことは否めない。機能的にも継ぎ接ぎ感があって把握しづらい。多くの革新が図られたツクールMVは,システムを整理しなおす絶好の機会だったろうにと思うとちょっと残念だ。個人的に感じているのはトリガー条件が少ないことや,戦闘時のスキル発動率などの扱いの低さなどだ。ダメージ計算に関しては細かいのだが,発動率や副作用についてはかなり大雑把な感じだ。プラグインで拡張できなくはないだろうが,ツール上のUIに統合できないので使い勝手まで考えると実用的とはいえそうにない。
ツクールMVは従来のツクールの最新版と考えると非常によくできた製品といえる。コンセプトまで含めるとかなり凄い。その結果,スマートフォンという大きな市場を狙えなくもない位置につけている。この立ち位置が微妙で,「狙えなくもない位置」は「狙った位置」ではない。現在の展開は「狙うかのような」ものとなっているが,冒頭から愚痴っているように実態が伴っていない。
今回は,「スマートフォン用のゲームをツクールMVで作ろう」というあたりが裏テーマとなっていたわけだが,ツクールMV自体は「旧来のゲームをスマートフォンでも動くようにした」というもの以上でも以下でもないという印象が強い。システム的な拡張やタッチデバイスを前提とした仕様などを取り入れれば,もっと先を狙えるところまでいけるのではないだろうか。逆に,仕様的にはほとんど拡張はないのに,データレベルでの互換性が切り捨てられているのもどうかとは思う。
プラグインによって,さまざまな機能が手軽に扱えるようにはなるものの,JavaScriptをまったくいじらずにいろんなことができるようになるかというと,ちょっと疑問もある。
数週間触ってみての感想をまとめてみたが,わりと「惜しい」と思う点が多い印象だった。いろいろできそうなことが多いだけに,もっと新しい人向けに売ればいいのにとか,もう少し仕様を拡大しておけばいいのにと思う部分が出てくるのだ。実行部のコードとデータ形式が公開されているので,今後ユーザーレベルでの環境構築が進んでくればできることは大きく広がり,作成環境を改善するような外部のサポートツールなども作られてくるだろう。将来に期待といったところか。
とりあえず,将来的にもう1段階化ける可能性もあり,従来形式の「ツクールな感じ」のゲームは現状でも十分簡単に作成できるので,正月休みを利用して体験版に触れて慣れておくのはいかがだろうか。
リンク:今回作成したプラグインのダウンロードはこちら
リンク:
「RPGツクールMV」公式サイト―――――――――――――――――――――――――――――
記事URL:http://www.4gamer.net/games/312/G031261/20151217069/
→この記事を4Gamerで読む(※画像などがすべてある完全版です)―――――――――――――――――――――――――――――
関連タイトル:
・PC
RPGツクールMV・MAC
RPGツクールMV・HARDWARE
ミドルウェア/開発ツール―――――――――――――――――――――――――――――
(C)2015 KADOKAWA CORPORATION./YOJI OJIMA
―――――――――――――――――――――――――――――
Copyright (C) 2000-2015 Aetas, Inc. All rights reserved.