チュートリアル: 「0からはじめるACTION GAME MAKER」第四章

第四章:「ゲーム」として成立させよう

前回は弾を発射して敵を倒す、というゲームの基本動作まで完成させました。

今回は「実際にゲームとして遊べる」ところまでを解説します。

ゲームとして何が不足しているかを考える。

現在のバージョンではプレイヤーの動きや敵ができましたが、不足しているものがいくつもあります。

まず、ステージが狭すぎるので広くする必要がありそうです。

また、プレイヤーにはダメージリアクションがありますが「やられない」状態です。現在のHPがいくつあるかもわからないのでわかるようにする必要があります。

最後にゲームの「目的」がありません。本来はボス戦などをいれたいところですが、今回はシンプルに「敵を5体倒せばクリア」ということにしましょう。

完成イメージ

Stage1を拡張しよう

まずは、タイルをぬり広げてステージを広くしましょう。ステージが広くなるとカメラの範囲の外にでてしまうので、カメラがプレイヤーについていくようにする必要もありそうです。

タイルをぬり広げよう

タイルは、Base(TileMapLayer)ノードで作成しています、このノードを使って広げましょう。

1. stage1シーンタブに切り替えます。

2. シーンウィンドウでBase(TileMapLayer)ノードを選択します。

3. 下部の「タイル配置」ウィンドウでタイルを選択します。

4. 右方の空間にタイルを自由に配置してみましょう。簡単に飛び越えられるように、空中の足場や壁の高さは4マス以内、落とし穴の幅も4マスくらいにしておきましょう。

ある程度制作できれば次のステップにいきます。

カメラがプレイヤーを追従するようにしよう。

カメラの追従は、「ターゲットID」というシステムで行います。プレイヤーの作成時に、「CameraTargetSettings」ノードを作成したのを覚えているでしょうか?こちらにはプロパティで「ターゲットID」というものを設定できます。

ACTION GAME MAKERのカメラノード「ZoomCamera2D」にも、同じく「ターゲットID」というものを設定でき、同じ「ターゲットID」を持つゲームオブジェクトを追従するように設計されています。

それでは、「ZoomCamera2D」と「CameraTargetSettings」に「ターゲットID」を設定しましょう。

IntialCamera(ZoomCamera2D)ノードにターゲットIDを設定しよう。

1. Stage1のシーンタブにあるInitialCamera(ZoomCamera2D)ノードを選択します。

2. インスペクターのターゲットIDのArray…を展開します。

3. 「+要素を追加」ボタンをクリックします。

4. という文字列が出現するので、文字を消して「player」と入力しましょう。

Playerの「CameraTargetSettings」ノードにターゲットIDを追加しよう。

1. シーンタブを「player」に切り替えます。

2. 「CameraTargetSettings」ノードを選択します。

3. インスペクターの「ターゲットID」に「player」と入力します。

広くなったステージをテストプレイしてみよう。

テストプレイで正常に動くか、ステージの右端までたどり着けるかを試しましょう。

正常にできていれば、カメラがプレイヤーを追いかけるはずです。

チェックリスト

追従しないとき:stage1のInitialCameraとplayerのCameraTargetSettingsをチェックしましょう。

ステージの右端にたどり着けないとき:Base(TileMapLayer)で落とし穴のサイズや壁の高さを調整しましょう。

プレイヤーに「やられ」を追加しよう:パーティクルの作成

敵と同じく、プレイヤーもHPが0になったらやられるようにしましょう。見た目としては、やられ状態にちょうど良いフレームがないようなので、「パーティクル」を使って演出をつけてみましょう。

「パーティクル」とは?

パーティクルとは、日本語にすると「粒子」です。小さな画像を沢山ばらまくことで演出を作ります。紙吹雪のようなイメージをしていただくとわかりやすいかもしれません。紙吹雪でいうところの、紙の見た目や飛び方などを自由に調整することができます。

Godot Engineでは、「GPUParticle2D」「CPUParticle2D」というノードを使って実現することができます。ACTION GAME MAKERでは、「ParticleObject」というノードで扱うことができます。

さらに、「ParticleObject」では20種類以上のパーティクルテンプレートを扱うことができます。

パーティクルオブジェクトを作ろう。

作り方はゲームオブジェクトと全く同じです。

1. 新しいシーンタブを作成します。

2. ルートノードを作成:で「ゲームオブジェクト」を選択します。

3. オブジェクト名を「やられパーティクル」テンプレートを使用を「パーティクル」と設定して「作成」を押しましょう。

4. 作成された「やられパーティクル」ノードをシーンウィンドウで選択します。

5. インスペクターのパーティクルテンプレートを「なし」から「花火※パーティクル多め」にしましょう。

6. GPUParticles2Dというノードが自動で追加されます。

7. GPUParticles2DのインスペクターのEmittingをチェックしてみましょう。これは、パーティクルの放出を行うプロパティです。

8. シーン画面でパーティクルが放出され、花火がでるはずです。シーンタブの[未保存](*)を右クリックしてやられパーティクル.tscnを保存しておきましょう。

プレイヤーのヴィジュアルスクリプトに「やられ」を追加しよう。

「やられ」状態の検討

HPが0になったときに、動けなくなり、「やられパーティクル」を放出する、という設定をするのが良さそうです。リンクはAnyStateからつなぐのが良さそうですが・・・それだけは一つ問題があります。以下のような図になるのですが、「どのような状態」でも「攻撃にあたる」と「被ダメージ」ステートに遷移するようになっています。

HPが0になったということは敵の攻撃を受けているわけですから、「やられ」ステートからでも攻撃にあたって「被ダメージ」に遷移してしまうことがあります。

なので、以下のように「被ダメージ」へのリンク条件に「HPが0ではない」を追加して遷移を防ぎましょう。

「やられ」ステートをつくろう

アニメーションはちょうどよいものがないので「被ダメージ」を再利用しますが、全く同じだとやられ状態かどうかの判断ができませんので、オブジェクトの見た目を変更する「フィルター」機能で見た目もかわるようにしましょう。

1. Playerシーンを開きます。

2. 2DからScriptにエディター画面を変更します。

3. 「被ダメージ」の情報の空間に「ステートを追加」します。

4. ステート名を「やられ」に変更します。

5. アニメーションカテゴリ名を「被ダメージ」に設定します。

6. 「アクション設定」を展開します。

7. 「動作中の移動の入力を受け付けない」プロパティをオンにします。

8. 「+実行アクションの追加」ボタンを選択します。

9. 「パーティクルを表示」アクションを選択します。

10. パーティクルオブジェクトのパスの:page_with_curl:マークをクリックし、先ほど作成した「やられパーティクル.tscn」を選択します。

11. 「追加」ボタンを選択します。

12. 再び、「+実行アクションの追加」ボタンを選択します。

13. 「フィルターを設定」を選択します。

14. フィルタータイプを「透過」完了までの時間(秒)を3.0秒に変更します。これで、3秒かけて徐々に透明になります。

15. 「追加」ボタンを押し、以下のようになっていればステートは作成完了です。

AnyStateから「やられ」ステートへのリンクを作ろう

1. AnyStateを右クリックして「リンクを追加」し、「やられ」とつなぎます。

2. 「+その他条件の追加」ボタンをクリックします。

3. 「HPが0になった」条件を選択して「追加」します。

「被ダメージ」への遷移条件を追加しよう。

最後に「被ダメージ」への遷移条件を追加します。共通設定の「条件を反転させる」を有効にすることで、条件を逆にすることができます。つまり、「HPが0になった」条件はこの設定で「HPが0ではない」とすることができます。

1. AnyState→「被ダメージ」のリンクを選択します。

2. 「その他条件の追加」ボタンを選択します。

3. 条件「HPが0になった」を選択します。

4. 「条件を反転させる」をオンにして追加します。

5. その他条件欄が以下のようになっていればOKです、「反転」オプションが有効な場合は「≠」のアイコンが白くなるので正しく反転が有効かチェックしておきましょう。

「やられ」をテストプレイしてみよう。

テストプレイをしてみましょう、現在HP初期値のままで1しかないので、1回敵の攻撃にあたれば「やられ」になるはずです。

うまくできていれば、敵にあたればパーティクルが表示され、徐々にプレイヤーが薄くなっていきます。なお、やられたあとは「F5」キーを押すことでリセットできます。

うまくいかない時のチェックリスト

花火のパーティクルがでない: 「やられパーティクル」オブジェクトの内容と「パーティクルを表示」アクションを見直しましょう。

透明にならない:「フィルターを設定」の内容を見直しましょう。

被ダメージのリアクションが出る:リンク条件を見直してみましょう。

「HPバー」をつくろう

さて、1回当たれば即アウトは厳しいので、HPの値を増やしましょう。そうすると、HPがいまいくつ残っているのか?がわかる必要があります、なのでHPバーを作りましょう。

ACTION GAME MAKERでは、SimpleGauge、ImageGaugeというノードを使ってゲージを表示することができます、今回はSimpleGaugeを使いましょう。

しかし、カメラが移動するようになっているのでプレイヤーと同じレイヤーに配置すると、HPバーがおいていかれてしまいます、HPバーのような常に表示をしたいものは、「UI」レイヤーを使います。

「UI」レイヤーについて

以前の説明を覚えているでしょうか?ACTION GAME MAKERのレイヤーは以下のような構成になっており、UIレイヤーと画面効果レイヤーは、「カメラに影響されない特殊なレイヤー」です。つまり、このレイヤーに配置されたノードは常に表示されますので、HPバーを配置するにはピッタリです。画面効果レイヤーは「画面効果」アクションに使う特殊なレイヤーなので、UIレイヤーに配置しましょう。

プレイヤーの「体力」「最大体力」の値を10にしよう。

1. プレイヤーのBaseSettingsノードを選択します。

2. インスペクターで「体力」「最大体力」の値を1から10に変更しましょう。

「SimpleGauge」ノードを追加・設定しよう。

1. シーンタブをstage1に切り替え、エディター画面をScriptから2Dに戻しましょう。

2. UIノードを選択します。

画像151

3. シーンウィンドウ左上の+(子ノードを追加)ボタンをクリックします。

4. SimpleGaugeを選択して「作成」します。

5. まずは位置を調整します。現在は以下のように潰れた状態になっているはずです。

6. オレンジの点をドラッグして画像くらいのサイズにまで拡大してください。

7. UIレイヤーの表示範囲は、以下の細い青い線に囲まれた範囲です。範囲内の左上のあたりにゲージを移動しましょう。

8. 続いてこのゲージがプレイヤーのHPを表示するようにします。インスペクターウィンドウの変数タイプを「指定のオブジェクト」にしてください。

9. 新しく出現する「対象オブジェクトのパスを指定」の:page_with_curl:マークをクリックしてください。

10. player.tscnを選択して「開く」をします。

11. 「変数名」欄はデフォルトでhpが入るはずなので変更不要です。この欄は「現在値」として使用する変数を指定する欄です。

12. 続いて、「最大値として変数を使用」のチェックをオンにしてください。

13. 9~10の手順を繰り返し、player.tscnを指定してください。

14. 最大値とする変数はobject_idというものが入っているはずなので、クリックしてmax_hpに変更します、これでゲージの最大値として最大HPが指定されました。

「HPバー」をテストしよう

テストプレイボタンを押してテストしてみましょう。うまく設定できていれば、敵にあたればダメージリアクションをしてHPバーが現象するはずです。

うまくいかないときのチェックリスト

ゲージが見えない:正しくSimpleGaugeがUIレイヤーの子になっているか、青い線の範囲内に配置されているか確認しましょう。

HPが最初から少ない: PlayerのBaseSettingsの「体力」の値が10に直してあるか確認しましょう。

HPが最大なのに一撃で0になる:BaseSettingsの「最大体力」の値が10になっているか、SimpleGaugeの「最大値とする変数」が正しく指定できているか確認しましょう。

「落下やられ」を設定しよう。

テストプレイで気付いた方もいるかもしれませんが、現在落とし穴に落ちると落下しつづけてしまいます。落とし穴でやられるようにしましょう。

カメラが動ける範囲を制限して無限に追いかけないようにし、カメラの外にでると「やられ」となるように設定すればよさそうです。

InitialCamera(ZoomCamera2D)の移動範囲を制限しよう

1. InitialCameraノードを選択してください。

2. インスペクターの「制限値」を展開します。

3. 制限値の「下」の値を10000000から500にしましょう。これで、赤い線から下方向に500pixelまでしかカメラが動かなくなりました。

4. テストプレイをしてみましょう。うまく設定できていれば、カメラは左右方向や上方向には追従しますが、下方向には一定の位置から追従しないようになっているはずです。

うまくいかないときのチェックリスト

カメラに何も映らなくなってしまった: タイルが原点(赤い線と緑の線が交わる位置)からずれてしまっている可能性があります。カメラの制限値を1000,2000と変更してみて、ちょうどよい値を探してみましょう。

プレイヤーのヴィジュアルスクリプトに落下やられを追加しよう。

「やられ」ステート自体はすでにあるものが使えるので、リンクに新しい条件「カメラの範囲外になった」を追加しましょう。

1. シーンタブをプレイヤー、エディター画面をScriptに切り替えます。

2. AnyState→やられのリンクを選択します。

3. 「+その他条件の追加」をします。

4. 条件「カメラの範囲外になった」を選択します。

5. データタイプを未設定から「自分自身」に変更します。

6. 「前の条件との論理条件」をORに変更して追加します。

7. 以下のようになっていればOKです、カメラの範囲外になったが「OR」になっていることを確認してください。

「落下やられ」をテストしよう

テストプレイをして落下しましょう、落とし穴に落下して、範囲外になったときに花火パーティクルが見えれば成功です。

うまくいかない時のチェックリスト

AnyState→やられのリンクの条件が正しく「HPが0」「OR」「カメラの範囲外」になっているかチェックしましょう。

「敵を5体倒せばクリア」を考えよう:変数の扱い方

何らかの方法で「5」という数字を数える必要があります。この数字が、敵を倒した時に減少していき、数字が0になるとクリアの演出がでる、というところが目指すところになりそうです。こういった場合、ゲーム制作では「変数」というものを扱います。

「変数」とは?

「変数」とは、値を入れておく容器のようなものです。先程扱った体力(HP)も実際は変数になっており、「敵の攻撃にあたる」と体力容器の中の値が1つ減る、という処理が行われています。

ACTION GAME MAKERで変数を設定する方法は大きく2つあります、1つがオブジェクトのVariableSettingsノードを使う方法と、もう1つがデータベースの「プロジェクト変数」を使う方法です。先程扱った「体力」は前者になります。

「VariableSettingsの変数(オブジェクト変数)」と「プロジェクト変数」の違い

「オブジェクト変数」はオブジェクトが持つ専用容器、「プロジェクト変数」はどこでも、誰でも扱える共通の容器という違いになります。

大きな違いは、「オブジェクト変数」はオブジェクトに付属しているものなのでオブジェクトが消えると消えてしまうが、「プロジェクト変数」は同じプロジェクト内であれば利用できるという点です。「体力」や「攻撃力」といったオブジェクトに紐づくデータはオブジェクト変数、「最高スコア」などのセーブデータを切り替えても保存しておきたいデータや、「コイン数」「残機数」などのステージをまたいで保持したいデータは「プロジェクト変数」を扱うことになります。

では、「残りの敵の数」はどちらの変数を使う?

本来はどちらでも良い数値ですが、複数のオブジェクトから操作する可能性があるので今回は「プロジェクト変数」で作ってみましょう。

敵が「消滅」ステートになると、「残敵数」を1減らす。「残敵数」が「0」になるとクリア演出を行う。ということで実現できそうです。

クリア演出の実現方法

残敵数のチェックを行う専用のゲームオブジェクトを作り、常に表示するUIレイヤーに配置するのが良いでしょう。そのオブジェクトで、HPバーのように現在の撃破カウントを表示するようにすれば、後何匹倒せばいいのかわからない、という問題も解決できそうです。それでは、「プロジェクト変数」「残敵数」を作り、「enemy」の「消滅」ステートに撃破カウントを追加するアクションを追加、最後にクリア演出オブジェクトを配置、という手順で作りましょう。

「プロジェクト変数」に「残敵数」を追加しよう。

「プロジェクト変数」はデータベースの中にあります。早速追加しましょう。

1. 画面左上のメニューより「データベース」ボタンをクリックします。

画像168

2. データ管理ウィンドウという新しいウィンドウが開きます。

3. 「ユーザーデータベース」というタブが開くので、「プロジェクト変数」タブに切り替えましょう。

4. ウィンドウ左上の「+」ボタンをクリックしましょう。

5. ウィンドウ下部に「variables1」という新しい行ができるので、「残敵数」とリネームしましょう。

6. 敵の数は5にするので「値」を5.0にします。

7. OKを押してウィンドウを閉じれば完了です。

「いいね!」 1

「enemy」オブジェクトの「消滅」ステートにアクションを追加しよう。

ACTION GAME MAKERでは、変数を操作するのに「プロパティを変更」というアクションを使います。そこで、四則演算(足す、引く、かける、割る)を使って変数を変更できますので、「残敵数」「引く」「1」とすると実現できます。

1. シーンタブ「enemy」を開き、エディター画面を「Script」に切り替えます。

2. 「消滅」ステートを選択して「+実行アクションの追加」をしましょう。

3. 「プロパティを変更」アクションを選択します。

4. 以下のように設定します。

対象オブジェクトの種類:プロジェクトデータベース

データベースの種類:プロジェクトの変数

レコード名:残敵数

計算式:―=

定数値:1

設定項目が5箇所と多いので注意してください。

これで、このアクションを実行すると、プロジェクトの変数「残敵数」がー=1されます。

5. 最後に、実行アクションの順番を入れ替えましょう。現在は、以下のような表示順になっているはずですが、実行アクションは「上から順」に実行されるため、このままでは「プロパティを変更」する前に「消滅」してしまい変更が不発になります。

「プロパティを変更」アクションの横にある三本線のアイコンをクリックしてドラッグし、順番を入れ替えて「プロパティを変更」が最初にくるようにしましょう。

補足:なぜ、単なる「―」ではなく「―=」という書き方なのか?

こちらの記述はプログラムでは一般的な記述なのですが、この「―=」というのはある式の省略系となっています。

「以前の残敵数の値」―「1」=「新しい残敵数の値」という式のーと=を省略して記述しています。

もし、この=がないと「以前の残敵数の値」から「1」を引いたものをどの変数に保存するのか、という指定がない状態になってしまいます。

UIオブジェクト「残敵数管理」を作ろう

残敵数を管理するUI用オブジェクトを作ります。

このオブジェクトは、「現在の残敵数の値」を表示し、値が0になるとクリアの演出を行うようにします。わかりやすく、Sprite2Dで表示した「敵のアイコン」の横に、変数「残敵数」をアクションで表示するようにしましょう。敵のアイコンの画像としてはそのまま敵のスプライト画像が使えそうです。

1. エディター画面を「2D」に切り替えておきます。

2. 新しいシーンタブを開き、ルートノードを作成:で「ゲームオブジェクト」を指定します。

3. オブジェクト名を「残敵数管理」、テンプレートを使用を「UI」、タイプ(型)を「空」にして作成ボタンを押しましょう。

4. 作成したら保存しておきましょう。

5. 敵のスプライト画像に使っている「enemy.png」を「ファイルシステム」からエディター画面の原点(赤い線と緑の線が交わる点)の左の空間にドラッグ&ドロップしましょう。

6. 自動でEnemyという名前のSprite2Dが追加されます。Godot Engineでは画像ファイルをエディター画面に直接配置すると、Sprite2Dノードを自動で生成し、テクスチャーとして自動で設定してくれます。

「残敵数管理」のヴィジュアルスクリプトを設定しよう。(変数表示編)

まずは、変数表示だけを考えます。変数「残敵数」を表示するステート「カウント」だけあれば良さそうです。

変数の表示には「テキストを表示」というアクションを使います。

「カウント」ステートの作成

1. シーンウィンドウの「:page_with_curl:+」でスクリプトをアタッチします。

2. 残敵数管理.vsを作成します。

3. デフォルトのステート001を「カウント」にリネームします。

4. 実行アクション「テキストを表示」を選択します。

基本設定は以下のように設定します。

テキストの種類:変数

変数のソース:データ管理

データベースのタイプ:プロジェクト変数

レコード名:残敵数

5. 「配置とアクション」の分は以下のように設定します。

永続化:オン

フォント:新規SystemFont

フォントサイズ:64

表示領域:x=80,y=80

上(左、右、下)方向マージン:すべて0

水平方向整列:中央

垂直方向整列:中央

補足:「テキストを表示」アクションの配置について

このアクションは基準点を中心とした指定サイズのテキストボックスを作成し、その中にテキスト(変数)を指定の時間表示する、というものになっています。表示基準点の「このオブジェクトの中心」は原点(赤と緑の線が交わるポイント)のことです。

この場合は、原点を中心とする80x80pxのテキストボックスを作り、中央配置で変数を表示する、その表示時間は永続、となっています。

「カウント」のテスト

カウントが正しく表示されるかシーンに配置してテストしてみましょう。常に表示したいので、配置レイヤーはUIレイヤーです。

1. シーンタブをstage1に切り替え、エディター画面を2Dに切り替えます。

2. UI(CanvasLayer)にあるSimplaGaugeノードを選択した状態にします。

3. ファイルシステムの「残敵数管理.tscn」を選択し、UIレイヤーの表示域(青枠)の右上あたりにドラッグ&ドロップしましょう。

4. テストプレイを行い、残敵数5が正常に表示されること、敵を倒すと数字が4にかわることを確認しましょう。

うまくいかない時のチェックリスト

アイコンも数字も表示されない:正しくUIレイヤーに配置されていること、青枠の範囲内に配置されていることを確認してください。

アイコンはあるが数字が表示されない:残敵数管理オブジェクトで、アイコンが正しく原点の近くに配置されているか、「カウント」ステートのテキストを表示アクションの内容が正しいか確認してください。

敵を倒しても数字が変わらない:enemyオブジェクトの消滅ステートの処理順が正しく「プロパティを変更」、「自身を消滅」の順になっているか確認をしてください。

クリア演出を作ろう

続いては、クリア演出です。これにも「テキストを表示」アクションを使いましょう。

画面の中央に大きく「STAGE CLEAR」と表示すればクリアらしく見えそうです。

遷移条件は、変数「残敵数」が0になった、とすればよさそうです。

1. シーンタブを残敵数管理、エディター画面をScriptに変更します。

2. カウントステートの近くで「ステートを追加」します。

3. タイトルをステージクリアにリネームします。

4. 「+実行アクションを追加」します。

5. 「テキストを表示」アクションを選択します。

6. 以下のように設定します。(設定項目が多いのでご注意ください。)

本文:「STAGE CLEAR」

永続化:オン

フォント:新規SystemFont

フォントサイズ:96

表示領域:x=1200,y=120

水平方向整列:中央

垂直方向整列:中央

表示基準点:シーンを基準にする

アンカー:中央

表示基準点のシーンを基準にするとは?

このゲームオブジェクトの位置ではなく、ゲームシーン全体、つまりカメラで表示されている領域を基準にします。この場合であれば、シーンの中央から幅1200高さ120の領域に中央揃えでSTAGE CLEARの文字が表示されます。

7. カウントステートを右クリックして「リンクを追加」し「ステージクリア」ステートに繋ぎます。

8. 「+その他条件の追加」ボタンを選択します。

9. 「スイッチ・変数が変化した」条件を選択します。

10. 変数タイプ:変数

データタイプ:プロジェクトの変数

データベースのレコード名:残敵数

変数演算子:=

と設定しましょう、これで残敵数が0の際に遷移するようになります。

クリア演出のテストをしよう

まず、敵の数が足りないので5体まで増やします、その後クリア演出が正しくでるかテストしましょう。

1. シーンタブをstage1、エディター画面を2Dにします。

2. BaseLayerの子ノード、enemyノードやplayerノードなどを選択した状態にします。

3. ファイルシステムからenemy.tscnをステージにドラッグ&ドロップで配置します。

4. 1~3を繰り返し、enemy5まで配置できればOKです。

5. テストプレイをしてみましょう。

うまく設定できていれば、敵をすべて倒すとSTAGE CLEARの文字がでるはずです。

うまくいかない時のチェックリスト

5体おいたはずの敵がいない:落下して画面外に移動してしまっている可能性があります。正しく床の上に配置できているか、テンプレート移動の段差から落下しないがオンになっているかチェックしましょう。

カウントが0になっても何もおきない:ステージクリアステートの内容と、遷移条件が正しいか確認してみましょう。

第四章の振り返り

さて、今回は、「カメラの追従の仕組み」「パーティクル」「UI」「変数」について学ぶことで、実際にゲームとして機能するようになりました。

しかし、現状ではまだまだ演出が地味ですし、音もありません。

次の第五章では、「音の設定」「背景の設定」などを行いゲームとしての完成度を高め、誰でもプレイができるように出力してみましょう。