ロールプレイングゲーム(RPG)は、シューティングゲームやアクションゲームと並んで定番のゲームジャンルの1つです。
RPGにはおおまかに「フィールド画面」と「バトル画面」があります。また、ゲームの全体の流れはギミック(仕掛け・からくり)で制御したりしますので、他のジャンルのゲームに比べると大掛かりで複雑なプログラムになる傾向があります。
そのような複雑なプログラムですが、今回からRPGのバトル画面のScratchプログラミングについて、テーマやテクニック別に解説するシリーズをやっていきます。
このプログラムで使用する画像や音声は、これまでの記事でもたびたび紹介している『無料で使えるスーパーパワーアセットパック(CC0)』にRPGの戦闘シーン向けの素材があるので、それを使用します。
今回はまず、RPG戦闘シーンの第1回目として「登場キャラクターの配置とそれぞれのキャラクターが行うアニメーションブロックの作成」について説明します。
この記事では、ロールプレイングゲーム(RPG)の戦闘シーンにおけるキャラクターの配置とそれぞのキャラクターの動きをアニメーションするScratchプログラミングを紹介します。
完成品
この章の内容をご自身のScratch環境に反映すれば、同じ動きを再現することができます。
完成した動き(この記事のゴール)
プレイヤー側のキャラクター3体(ステージ右側)と敵側のキャラクター3体(ステージ左側)をそれぞれ配置しています。
アニメーションの種類は、「待機」「攻撃パターン①」「攻撃パターン②」「魔法」「防御」「ダメージ」とあります。
すべてのキャラクターに共通のアニメーションは「待機」「攻撃パターン①」「ダメージ」の3種類で、その他の「攻撃パターン②」「魔法」「防御」はすべてのキャラクターが使えるわけではなくキャラクターによって「使える/使えない」は違っています。
今回はアニメーションを見せることが目的なので、スタートボタンを押すだけで一定の時間間隔で、そのキャラクターが使えるアニメーションを順番に実行するようにしています。
完成した動き(最終形態)
最終形のイメージをつかんでもらうために、すべてのプログラムを結合して実装した最終形態のアニメーションの序盤部分を載せておきます。GIF画像なので音声は聞こえませんが、実際にプレイするとBGMが流れます。
使用したスプライト
スプライトは「初期設定」「背景」「ステータスバー」「warrior2」「Wizard」「bowman」「giant」「mushroom」「mimic」の9つです。
アクションゲーム用の背景・キャラクター・アイテム等の画像や音声は、パブリックドメインである「スーパーパワーアセットパック(CC0)のrpg-battle-system」を使っています。
【初期設定のスプライト】
「初期設定」スプライトはプログラム専用なのでコスチュームはありません。
【背景のスプライト】
「背景1」スプライトは、「rpg-battle-system\backgrounds」フォルダに入っている画像ファイルをコスチュームにアップロードして使用します。
【ステータスバーのスプライト】
「ステータスバー」スプライトは、「rpg-battle-system\HUD」フォルダに入っている「black-strip.png」ファイルをコスチュームにアップロードして使用します。
【warrior2のスプライト】
「warrior2」スプライトは、「rpg-battle-system\char\warrior2」フォルダ内にある「attack.gif」「guard.gif」「hit.gif」「idle.gif」ファイルをコスチュームにアップロードして使用します。
拡張子「.gif」のファイルはGIFアニメーション形式になっているので、このファイルを直接コスチュームにアップロードすると、Scratch側で自動的に1枚1枚の画像に分割して展開してくれるので便利です。コスチューム名には自動的に連番が付加されます。
【Wizardのスプライト】
「Wizard」スプライトは、「rpg-battle-system\char\Wizard」フォルダ内にある「attack.gif」「attack2.gif」「hit.gif」「idle.gif」ファイルをコスチュームにアップロードして使用します。
拡張子「.gif」のGIFアニメーション形式のファイルを直接コスチュームにアップロードすると、Scratch側で自動的に1枚1枚の画像に分割します。コスチューム名には自動的に連番が付加されます。
【bowmanのスプライト】
「bowman」スプライトは、「rpg-battle-system\char\bowman」フォルダ内にある「attack.gif」「attack2.gif」「hit.gif」「idle.gif」ファイルをコスチュームにアップロードして使用します。
拡張子「.gif」のGIFアニメーション形式のファイルを直接コスチュームにアップロードすると、Scratch側で自動的に1枚1枚の画像に分割します。コスチューム名には連番が自動的に付加されます。
【giantのスプライト】
「giant」スプライトは、「rpg-battle-system\monster\giant」フォルダ内にある「attack.gif」「attack2.gif」「hit.gif」「idle.gif」ファイルをコスチュームにアップロードして使用します。
拡張子「.gif」のGIFアニメーション形式のファイルを直接コスチュームにアップロードすると、Scratch側で自動的に1枚1枚の画像に分割します。
コスチューム名はあとでプログラムしやすいように自分で命名しています(アニメーションの順番がくずれないように注意)。
【mushroomのスプライト】
「mushroom」スプライトは、「rpg-battle-system\monster\mushroom」フォルダ内にある「attack.gif」「attack2.gif」「hit.gif」「idle.gif」ファイルをコスチュームにアップロードして使用します。
拡張子「.gif」のGIFアニメーション形式のファイルを直接コスチュームにアップロードすると、Scratch側で自動的に1枚1枚の画像に分割します。
コスチューム名はあとでプログラムしやすいように自分で命名しています(アニメーションの順番がくずれないように注意)。
【mimicのスプライト】
「mimic」スプライトは、「rpg-battle-system\monster\mimic」フォルダ内にある「attack.gif」「attack2.gif」「hit.gif」「idle.gif」ファイルをコスチュームにアップロードして使用します。
拡張子「.gif」のGIFアニメーション形式のファイルを直接コスチュームにアップロードすると、Scratch側で自動的に1枚1枚の画像に分割します。
コスチューム名はあとでプログラムしやすいように自分で命名しています(アニメーションの順番がくずれないように注意)。
完成したスクリプト
完成したスクリプトの全体です。
【初期設定のスクリプト】
画面に登場しているプレイヤーの名前を「プレイヤー種類」リストに、敵キャラクターの名前を「エネミー種類」リストに登録します。
それぞれのキャラクターが使うことができるコマンドを「~有効コマンド」リストにそれぞれ登録します。
それぞれのキャラクターのHP(ヒットポイント)やMP(マジックポイント)を変数に格納します。
- warrior2のHP:すべてのスプライト用
- warrior2のMP:すべてのスプライト用
- WizardのHP:すべてのスプライト用
- WizardのMP:すべてのスプライト用
- bowmanのHP:すべてのスプライト用
- bowmanのMP:すべてのスプライト用
- giantのHP初期値:すべてのスプライト用
- giantのHP:すべてのスプライト用
- mushroomのHP初期値:すべてのスプライト用
- mushroomのHP:すべてのスプライト用
- mimicのHP初期値:すべてのスプライト用
- mimicのHP:すべてのスプライト用
- プレイヤー種類:すべてのスプライト用
- エネミー種類:すべてのスプライト用
- warrior2有効コマンド:すべてのスプライト用
- Wizard有効コマンド:すべてのスプライト用
- bowman有効コマンド:すべてのスプライト用
- giant有効コマンド:すべてのスプライト用
- mushroom有効コマンド:すべてのスプライト用
- mimic有効コマンド:すべてのスプライト用
【背景のスクリプト】
背景画像は、Scratchのステージの大きさに合わせるには150%にする必要があります。
【ステータスバーのスクリプト】
【warrior2のスクリプト】
「warrior2」のステージ上の初期位置とそれぞれのアニメーションを定義ブロックにまとめます。
HPが0以下になったら「プレイヤー種類」リストから名前を削除するようにします。
- move:このスプライトのみ
- i:このスプライトのみ
【Wizardのスクリプト】
「Wizard」のステージ上の初期位置とそれぞれのアニメーションを定義ブロックにまとめます。
HPが0以下になったら「プレイヤー種類」リストから名前を削除するようにします。
- move:このスプライトのみ
- i:このスプライトのみ
【bowmanのスクリプト】
「bowman」のステージ上の初期位置とそれぞれのアニメーションを定義ブロックにまとめます。
HPが0以下になったら「プレイヤー種類」リストから名前を削除するようにします。
- move:このスプライトのみ
- i:このスプライトのみ
【giantのスクリプト】
「giant」のステージ上の初期位置とそれぞれのアニメーションを定義ブロックにまとめます。
HPが0以下になったら「エネミー種類」リストから名前を削除するようにします。
- move:このスプライトのみ
- i:このスプライトのみ
【mushroomのスクリプト】
「mushroom」のステージ上の初期位置とそれぞれのアニメーションを定義ブロックにまとめます。
HPが0以下になったら「エネミー種類」リストから名前を削除するようにします。
- move:このスプライトのみ
- i:このスプライトのみ
【mimicのスクリプト】
「mimic」のステージ上の初期位置とそれぞれのアニメーションを定義ブロックにまとめます。
HPが0以下になったら「エネミー種類」リストから名前を削除するようにします。
- move:このスプライトのみ
- i:このスプライトのみ
スクリプトの作り方
ここからはプログラムを作っていく中でポイントとなる部分を説明します。
ポイント①:アイドル状態とそれ以外のアニメーションをフラグ変数で制御する
アイドル状態のアニメーションとは「待機」定義ブロックの部分のことをいいます。
「warrior2」を例にとると「待機」のアニメーションは下の図のような動きになっています。その他のキャラクターの「待機」定義ブロックもほとんど同様の動きをします。
「待機」定義ブロックが実行される条件は、「move」変数の値が「0」のときだけです。このように変数の値を使い分けてスイッチを切り替える変数を「フラグ変数」と呼んだりします。
そのため、下の図のように「待機」以外のアニメーションを実行するときは「move」変数の値を「0以外」にすると、「待機」アニメーションが停止してその他のアニメーションにスムーズに切り替わります。
なお、「warrior2」以外のすべてのキャラクターにも同じ構造でスクリプトを作ります。
ポイント②:キャラクターの死活状態をリストで管理する
キャラクターがダメージを受け続けてやられたら画面から消す必要があります。言い換えると、何らかの方法でキャラクターの生死について管理する必要があるということです。
今回は、「プレイヤー種類」リストと「エネミー種類」リストで管理するようにしています。
これらのリストにキャラクターの名前が存在するときは生きている状態を表し、リストから名前が消えた瞬間が死んだ状態ということにしています。
リストからキャラクターが消える条件は?というと、それはそれぞれのキャラクターのHPが0以下になったときです。
「warrior2」と「giant」のHPが0になった瞬間の画面上のキャラクターとリスト内の状態を下の図(アニメーション)で確認してみてください。HPが0になった瞬間に画面からキャラクターが、そしてリストから名前が消えることが分かると思います。
ここまでのポイントを押さえれば、ロールプレイングゲーム(RPG)の戦闘シーンにおいてキャラクターのアニメーションを実行するスクリプトを完成させることができると思います。
失敗しやすいポイント
フラグ変数を使わなかった場合
下図のスクリプトでは、フラグ変数である「move」変数を削除しています。このスクリプトを実行したときのアニメーションの切り替わりに注目して見てみてください。
ちょいちょい挙動不審のような余計な動きが差し込まれているのが分るでしょうか?これは「待機」ブロックが実行中に、その他のアニメーションを無理やり実行しようとしているためです。
これを改善するには「待機」ブロックのアニメーションを止めてから、その他のアニメーションを実行するようにしてあげればOKです。フラグ変数はそれを簡単に行うために使用します。
応用編
———
まとめ
今回の記事で説明した『ロールプレイングゲーム(RPG)の戦闘シーンにおいてキャラクターのアニメーションを実行するプログラミング』のポイントをまとめます。
- ポイント①:アイドル状態とそれ以外のアニメーションをフラグ変数で制御する
- ポイント②:キャラクターの死活状態をリストで管理する
今回は第1回目なので、まずは背景などとキャラクターの配置、キャラクターごとに用意されているGIFアニメーションの定義について説明しました。
今後の記事ではどんどん機能を追加していくので徐々に複雑になって難易度も上がっていきます。追加するゲーム機能ごとに解説していくので、どのような考え方でどのような点に注意すればきちんと動作するゲームになるかが分かるような説明を心掛けています。
最終的には、すべてのプログラムをつなげると1つのプロジェクトが完成するようにしていきます。
どうでしたか?上手く再現できたでしょうか?
他にも役に立つTips(ティップス)記事をたくさん書いてますので、ぜひ見てみてください。(記事のタイトルに「Tips」と書いていたり「Tips」タグを貼ってあります)