こんばんは。
ピクセルアニメクリエイターのおかか容疑者でございます。
GDevelopでゲームを作ろう企画。
前回「GDevelopで簡単なゲームを作ろう・17 ~ゲームオーバーの実装、エフェクトについて~ 」では、ゲームを遊ぶ上で必要な最後の部分であるゲームオーバーの処理についてをお話しました。
画面の見栄えをよくするためのエフェクトの話も併せてしております。
前回まででゲーム全体を通して遊べるようになりましたので、ここからはさらにゲームの完成度を高めて少しでも面白くなるように改良を加えてまいりましょう。
今回はだいぶ重要だけど話していなかった「Timedelta」のお話と、敵の攻撃についてのちょっとしたお話をいたしますね。
※GDevelopのバージョンは5.3.201です。
TimeDelta(タイムデルタ)とは
それで本題なのですが、今回はまず謝罪から入らないといけません。
サーセンシタッッッ!!!
というのもこの企画、「まずはごくシンプルなところからスタートしていこう」という気持ちで始まっておりますので、少々手間がかかる部分は端折ってお話ししておるのですね。
ですので割と重要な部分を省いていたりします。ここまで進んでこられたアナタにはその点までしっかりお話しておかねばなりません。
そうなると、過去に作ったイベントにちょっとだけ手直しを加える必要がございます。
一緒に説明しておけば手間がかからなかったんですけどね。手間をかけさせるという点について謝っておきます。
では、表題の「Timedelta」についてお話ししましょう。
これについては実は公式もこのページでしっかりと書いてくれております。
一部引用させていただきましょう。
この問題を解決するために、GDevelop には TimeDelta() 式が用意されています。この式は直前のフレームからの経過時間を秒単位で返します。これを使って、フレームレートが変動しても予定通りにゲームを実行することができます。
イベント – GDevelop documentation
ということです。
ですのでアナタもこのTimedelta()をどんどん使って
……え?わからん??
とりあえず、文面から何となく大事なものだということはおわかりいただけたのではないかと思います。
これが何なのかと申しますと。
ワタシも実はキッチリと理解しているわけではないのですが、「移動するもの」や「変化するもの」にこのTimedelta()を乗算(かけ算)してやることで、どんなスペックの端末で動かしてもほぼ同じ動きをさせることが可能なのです。
再度、先ほどの公式サイトから引用しましょう。
このアクションは毎フレームごとに変数をインクリメントします。もしゲームが秒間 60 フレームで実行されていたら、10 秒後の変数値は 18,000 になるでしょう。一方、もしゲームが秒間 25 フレームで実行されていたら、10 秒後の変数値は 7,500 になります。この非一貫性は、ゲームプレイ体験に重大な問題を引き起こしかねません。
イベント – GDevelop documentation
GDevelopはフレームごとにゲームを更新していくとのことですが、この「フレーム」というのがPCのスペック等々に影響されるのです。
考えていただければおわかりでしょうが、「パソコンというものが登場したての頃のパソコン」と「現代のパソコン(PC)」とはスペックが段違いなわけです。
最初期のパソコンでこのGDevelopのゲームを動かしてみようとしても容量不足で動かないか、動いたとしても処理速度が凄まじく遅くなるであろうことは想像できるでしょう。
そういった低スペックのPCではフレーム数というものが低くなります。上の引用ですと「秒間25フレームで~~」と書いてあるものにあたります。
そして現代のPCであれば比較的早く動きますので、上の引用の「秒間60フレームで~~」のものにあたるわけですね。
上の例をそのまま使わせていただくと、「高スペックのPCならばキャラクターが10秒間に18000マス分の移動ができるのに、低スペックのPCだとキャラクターが10秒間に7500マス分の移動しかできない」などという状況が発生してしまいます。
これは由々しき事態。
これまでこの企画はご自身のPCでのみ動かしておりますので特に問題はないはずですが、これを多くの人に遊んでもらうために公開する場合はこういった部分まで配慮する必要があるのですね。
そこでTimedelta!!!
コイツは何なのかと調べてみたところ、「前のフレームと今のフレームとの間の時間」を拾ってくれる式のようです。
これを乗算してやることでどんなスペックの端末でも(例外もあるのかもしれませんが…)同じ動作をしてくれるのです。
【ゲームプログラミング】「速度」を使う時は必ずdeltaTime
を使ってください #初心者 – Qiita
こちらはUnityで同じ機能を持つ「deltatime」についてわかりやすく書いてある記事です。参考として貼らせていただきます。
「Timedelta」で書かれるプログラミング言語はPythonくらいしかないっぽいですね。CF2.5も確かTimedeltaだった覚えがあるのでちょっと意外。
(この記事のコメント欄によるとこれはこれで問題もあるようですが、その辺はガチ学習したいときに学ぶとよいのではないでしょうか。ワタシはわかりません!!)
ですのでこれまでのイベントで必要な部分にTimedelta()を掛けていこう、という話なのですが、公式サイトのTipsに「一度きりのアクションであれば不要」と書かれております。
ですので移動などのアクションにこれを掛けてまいりましょう。
・Playerの移動イベント(4つ)
・Shotの移動イベント
・ShotBの速度減少イベント
・Skeleton(スケルトン)の移動イベント
・EnemyShotの移動イベント
・JackOLantern2(カボチャ)の角度変更イベント
これらにTimedelta()を掛けるようにします。
「* TimeDelta()」をコピーして該当箇所の後ろに貼り付けていくとラクです。
ちなみにPlayerの移動イベントを4つ手直しする中で感じるかと思いますが、こういう時に関数として一括で変更できると抜けもなくなるし、かなりラクなんですよね。
実際のゲーム開発ではこういう事態がおそらく頻発しますので、関数であれグループであれ「似たものをまとめる意識」は持っていた方がよいなと思います。
それでは問題がないかプレビューして動作確認してみましょう。
おっそ!!!!!
「問題がないかどうか」どころの話じゃありませんでした。
良い子のみんなはちゃんとTimedeltaを掛けてから確認をしようね!
…テストしてみたところ、だいたい元の数値の50倍するといい感じのスピードになりました。
多分ワタシのPCは60fpsで動いてくれているんじゃないかと思いますので60倍が正しいような気もしますが、細かいことはいいでしょう。
ただ、ShotBの減速の変数だけは50倍でも全然足りてなかったのでむっちゃ増やしました。
・Playerの「speed」…400
・ShotAの「speed」…50000
・ShotBの「speed」…200000
「speed_minus」…1000000
・Skeletonの「speed」…2500
・JackOLantern2の「speed」…150
・Cleaver(スケルトンショット)の「speed」…15000
・Crate(カボチャショット)の「speed」…10000
に変更しました。
わかりやすくするためにカボチャも追加しておきました。
(スケルトンを速攻で倒してしまっていますが)これでだいたい元通りのスピードにできました!
手間はかかりましたが、これで異なる端末への対応ができましたね。
敵の攻撃前に予兆を作る
これだけの話だとちょっと尺が中途半端ですので、もう一つカンタンに実装できる別のお話を加えておきましょうか。
このゲームは敵がショットを撃ってきます。
それはよいのですが、何も予備動作がないため、プレイヤーからすると「急にショットが来たので…」という感じになってしまいますね。
そういうゲームだと割り切れればよいのですが、大半のプレイヤーは理不尽さを感じる部分だと思います。悪い意味でストレスが溜まるゲームは遊ばれるわけがありませんね。
というわけで、敵がショットを撃つ前に「これから攻撃しますよ」という予兆を作ってあげるとかなり遊びやすくなります。
一番わかりやすいのは「キャラクターが力を溜めるような絵に変わる」でしょうか。
ただそんな素材がアセットにありませんしそんなに難しいことをするつもりもございませんので、今回は「ショットを撃つ少し前からキャラクターの色が変わる」という仕様を作っていきます。
敵に関するイベントですので、「敵」のイベントグループの一番下に新規イベントを作りました。
条件を「Enemygroupのタイマー”s”(ショットのタイマーですね)が、ショット発射タイムの半分を切ったとき」という設定にしております。
単純にショット発射タイムを2で割れば(/2)、半分の時間となりますね。
そしてアクション。
「Enemygroup」の「色合いを変更する」というものを選びましょう。
「色合いの項目」の右にある四角を押すとグラフィカルに色を選ぶことができます。
項目に直接RGBを書いていってもよいのですが、おそらくこうやって色を見ながら決めた方がよいでしょう。
今回はこのウインドウの下に並んでいる色から赤色を選択しました。
これで敵が攻撃前に赤色になる、というイベントができました。
そして忘れちゃならないのが「色を元に戻す」というイベント。
このままですとショット発射後も敵が赤色のままになってしまいますので、ショットを撃ったときに色が元に戻るイベントを作る必要がございます。
敵のショットの発射については関数で作りましたね。(過去記事・GDevelopで簡単なゲームを作ろう・13 ~敵の作成(3・敵の攻撃イベントを関数にする)~)
この「EnemyShot_action」をプロジェクトマネージャーからまた開きまして。
ショットを撃つイベントの一番下に「Enemyの色合いを白色に変更」というアクションを追加しましょう。
「色合いを変更する」の解説文にも書かれておりますが、デフォルトが白色ということになっております。
ここで白色に設定することで元の色合いに戻る、というわけです。
これで敵が赤く光ったらヤバいぞ、とプレイヤーに知らせることができました!
あらかじめプレイヤーが動きを考える時間を与える、そしてプレイヤーがこれから起きる出来事に介入する余地を作ることで、より満足感が高まると思います。
今回はショット発射時間の半分とざっくり決めましたが、もちろんアナタの考える難易度に応じて時間は好きなように変えていくとよいでしょう。
今後の話でも触れるかと思いますが、敵に攻撃するまでのタイムゲージを設定して、より視覚的にわかりやすくしたりするのもイイですね。
まとめ
・Timedeltaで端末ごとの動きの差をなくそう!
・攻撃前に予兆を作ってより親切なゲームに!
今回はとりあえずこのあたりで。
こういったやや細かい部分はGDevelopに限らずどんなゲームでも考慮すべき部分だと思いますので(というか今まで作ってきた部分全般もそうだと思いますが…)、何かのお役に立ちましたら幸いでございますね。
今後はこういったTips的な話になるのでたぶん話が毎回いろんな方向に飛ぶかと思われますが、そのあたりは親御さんにヨロシク!ということでひとつ。
次記事→GDevelopで簡単なゲームを作ろう・19 ~敵のランダム出現と数の表示~
さて…そろそろお時間です。
またのご面会、心よりお待ちしております。
この記事がお気に召したなら、
◎ギャラリーからワタシの作品を見ていただいたり、
☆Misskeyアカウント(@daidaimyou)
☆Caraアカウント
☆X(旧Twitter)アカウント(低浮上)(@daidaimyou)
をフォローいただけますと脱獄の励みになります。よろしくお願いいたします。
ドット絵(一枚絵・アニメーション)制作のお仕事も承っております。
お仕事依頼ページよりご連絡くださいませ。(現在受付停止中)
コメント