投稿

ラベル(知っておくべきこと)が付いた投稿を表示しています

実は奥(闇)が深い「真のあいだ一度だけ実行(一度だけ実行する)」条件を使いこなそう【GDevelop】

イメージ
便利すぎてついついお世話になってしまう「真のあいだ一度だけ実行」条件ですが、使い込んでいくと「あれ?この場合どうなるの?」という状態におちいりやすい条件でもあります。 そこで、このページでは「真のあいだ一度だけ実行」条件が、実際にはどのように機能しているのか、例をまじえて解説します。 ※ 執筆時点の GDevelop バージョンは 5.4.213 です。 ※ 以降「真のあいだ一度だけ実行」だと長いので「一度だけ実行する」と表記します。 よくある勘違い「インスタンスごとにチェックしてる」 例えばこのようなイベントを組んだとき↓ 各戦車が一度だけX方向に100px動く X座標は0で配置されている戦車はプレビューすると…… 3両全て一度だけ100px移動します。 このことから「一度だけ実行する」条件はインスタンスごとにチェックしてる、 と思ってはいけません! 偶然それっぽく機能しているだけです。 では、今度はこのようなイベントを試してみます↓ 3回、Y座標が100の戦車を一度だけX方向に100px動かす 3回&一度だけ、というちょっと意味不明なイベントですが、プレビューした結果はこのようになります↓ 「一度だけ実行する」条件が設定されているにも関わらず、Y座標が100の戦車(つまり一番上のみ)が、3回100px移動しています。 もしインスタンスごとにチェックしているのであれば、一度しか移動しないはずですが、そうはなりませんでした。 ちょっと何が言いたいのか分からないから早く結論(仕組み)を言え! はいごめんなさいw😅 「一度だけ実行する」条件は、インスタンス単位ではなくイベント単位でチェックされています。 このことは 公式ドキュメント(英語) にも記載されています。 いやいやちょっと待て!イベント単位ならさっきの例の結果はおかしいだろ! 確かに上記の例は、どちらもイベント単位でチェックしているとは思えない結果になっていますが、これは繰り返しを利用しているからそのような印象になるだけです。 繰り返しを個々のイベントに分解してみると分かりやすくなります。 まず最初の例は、以下のように分解することができます↓ 各インスタンスの判別にはY座標を利用 これなら3両全てが一度だけ移動したことにも、納得がいくかと思います。 続いて2つ目の例も分解してみましょう↓ まったく...

【GDevelop】条件の並び順による落とし穴

イメージ
イベントやアクションと同じように、 条件 も上から順に評価されるので、並び順はとても重要です。 特に、 評価された条件の絞り込みはすぐに効果を発揮する 、という点に注意する必要があります。 例えば、次の画像の条件 A と B は順番が逆なだけですが、異なる評価をします。 A の方は、衝突している戦車とミサイルに絞り込んでから、戦車の数をチェックしているのに対し、B の方は、まず戦車の数をチェックしてから、衝突している戦車とミサイルに絞り込んでいます。 つまり…… A は「ミサイルと衝突している戦車が 1 つの時」 B は「(絞り込まれた)戦車が 1 つだけの時、衝突している戦車とミサイルに絞り込む」 という全く異なる意味を持つ条件になります。 複数の条件を組み合わせた場合は AND で評価されますが、上記の通り 条件の絞り込みはすぐに効果を発揮する ので、並び順には注意しましょう。 (AND または AND 演算子とは、どちらも真の場合のみ真を返す演算子です) それと余談ですが、実は B の条件が真と評価されることはありません。 それについては 【GDevelop】「現在選択されているオブジェクトの数」について のページをご覧ください。

【GDevelop】「条件を反転」した時によくある勘違いと「ではない」の使い方

イメージ
GDevelop のイベントでは条件の結果を反転させることができます。 これはプログラミングで言うところの NOT 演算子と同じ、と思いがちですが、GDevelop の条件は単なる真偽値(True / False)の評価だけではなく、オブジェクトが絞り込まれる、という特徴があることを忘れてはいけません。 (NOT 演算子とは真偽値を真なら偽に、偽なら真に反転させる演算子です) 例えば、次の画像のようにイベントが組まれていたとします。 条件が反転されていることに注意してください。 これを見た時に「なるほど、条件は反転されているから、カーソルが WoodCrate 上にない時だけ Tank が移動して、逆に カーソルが WoodCrate の上にある時は実行されないんだな。 完全に理解した!」 などと思ってはいけません。 実はこのイベントのシーンはこうなっています↓ なんと WoodCrate は複数あったのです!😅 よく訓練された GDevelop ユーザーであれば、この時点で WoodCrate の上にカーソルがあっても、先程のイベントは 実行されてしまう ことに気が付くはずです。 どういうことかと言うと、実は先程のイベントは…… 「カーソルが WoodCrate 上にない時に Tank が移動する」 という事ではなく、 「カーソルが上にない WoodCrate に絞り込んで Tank を移動する」 という解釈が正解になります。 つまり、条件の最終的な結果が反転するのではなく、 反転しているのは個々のインスタンスの評価 である点に注意してください。 これは「カーソル/タッチはオブジェクト上にある」条件だけでなく、他の条件でも同様です。 そのため、実際にはどちらかの WoodCrate 上にカーソルが乗っていても、他にカーソルが乗っていない WoodCrate があるので、このイベントが偽(False)になる事はありません。(スマホであればマルチタッチで条件を満たすことができますが……) 条件を反転させた時どのような効果に変化するか、よく確認してから反転を利用するようにしましょう。 単に結果を反転させたい場合は? では、上記のように絞り込みを反転するのではなく、単に結果を真偽値として反転させたい場合は、どうしたら良いの...

【GDevelop】「オブジェクトを生成する」アクションだけが持つ唯一の例外について

イメージ
「オブジェクトを生成する」アクションには、他のアクションには無い、次のような特徴があります。 それは、 「オブジェクトを生成する」アクションは、生成するオブジェクトが同じイベント内で既に参照されていたかどうかで、生成後の絞り込みが変化する。 です! は?🤔 はい、文字だけだと意味不明ですよね。 分かりやすい例を用意したので、それで説明します。 ↓次のイベントでは、1秒毎に Tank_A と Tank_B を生成しています。 ただし、Tank_A と Tank_B は、生成する前に参照されたかされていないかの違いがあります。 具体的には赤線の箇所で、Tank_A の方はその数を調べるために Count() で Tank_A を参照しています。 対して Tank_B の方は参照していません。 それ以外の、対象を移動させるアクションなどは同じです。(出現位置は違いますが……) 一見すると、Tank_A と Tank_B は同じように生成されて移動する結果になると思われがちですが、実際には違います。 このイベントの結果が、これです↓ 明らかに、Tank_A と Tank_B の進み方に違いがあります。 Tank_A の方は加速しているのに対して、Tank_B は等速で移動しています。 この謎を解く鍵は、表示されている After の値です。 この After の値は、イベントで対象となっているオブジェクト(インスタンス)の数です。 Tank_A は After の値が 5 なのに対し、Tank_B は 1 です。 つまり、Tank_A のイベントでは 生成済みの Tank_A もアクションの対象 となっているのに対し、 Tank_B では生成したばかりの Tank_B ひとつだけが対象 となっていることが分かります。 そのため Tank_A は移動させるアクションが生成済みの Tank_A に対しても実行され、どんどん加速していく結果になります。 対して Tank_B は、それが生成された時だけ、移動させるアクションの対象となるため、ずっと同じ速度で移動しています。 このように 「オブジェクトを生成する」アクションは、生成するオブジェクトが同じイベント内で既に参照されていたかどうかで、生成後の絞り込みが変化する。 という、ちょっと意味不明な特徴があります。 通常、絞り込み...

【GDevelop】「オブジェクトを削除する」アクションの知っておくべき特性

イメージ
あらゆるゲームと状況下で多用されるであろう、「オブジェクトを削除する」アクションですが、実は他のアクションとは少し違った特性があり、知らないとアレレ?ってことになるので、その点について解説します。 ※ イベントってなに?アクションってなに?という方は、先に「 GDevelop の条件とかアクションって何?どれのこと? 」をご覧ください。 実は即削除していない これはどういうことかというと、 「オブジェクトを削除する」アクションが実行されたイベントが終わるまで対象のオブジェクトは削除されていない 、ということです。 具体的な例を挙げて説明しましょう。 ↓これは、GreenTank が ひとつ 配置されているだけのシーンです。 そしてそのシーンのイベントは次のようになっています。 では、このシーンをプレビューして、シーンをクリックすると、背景色は何色になるでしょうか? 一見すると(というか普通のプログラミング的に考えれば)、最初に削除アクションを実行しているので、GreenTank の角度も変わることなく、さらにオブジェクトの数も 0 になっているので、背景色は赤(255;0;0)になりそうなものですが、実際にはなんと青色(0;0;255)になります。 そして背景が赤くなるのは、2回目のクリックからです。 普通、アクションは実行したとたん効果を発揮しますが、上記のことから「オブジェクトを削除する」アクションは、即座に対象を削除するアクションではないことが分かります。 (角度を 90 度にしているアクションは、即座に効果を発揮し、続く条件で真(True)と、評価されている点も見逃さないでください) では、どのタイミングで削除されるのかと言うと、それは 「オブジェクトを削除する」アクションを実行したイベントが終わった時 です。 例えば次のように、削除アクションを別のサブイベント(赤矢印)に分ければ……↓ 削除アクションを実行したイベントが終わってから、オブジェクトの数をチェックしているので、結果は 0 個の真(True)となり、背景色は赤色となります。 続く角度をチェックしている条件では、既に対象が存在していないので偽(False)となり、背景を青にするアクションは実行されません。 このように組むことで、最初の例とは異なる結果になります。 なお、最初の例を見ると分か...

【GDevelop】式の中に登場するオブジェクトは絞り込みの対象じゃないゾ!

イメージ
「 GDevelop の「イベント」を正しく理解しよう 」のページでも解説したように、GDevelop のイベントは、条件でオブジェクトの絞り込みをしてくれるのですが、実は絞り込まない場合もあるのです😅 それは、 オブジェクトが式の中に登場している場合 です。 ちなみに「式」とは、条件やアクションの入力画面で  や  が横にくっついてる欄に入力する文字とか数のあれですw(正確には文字列の場合は「文字列式」です) では早速、具体的な例を挙げてみましょう。 例えばこんなシーンが有ったとして↓ こんなイベントを組んだとします↓ 条件で GreyTank1 の X 座標が 480 より小さいかを判定しています。 一見すると、X 座標が 480 より小さい GreyTank1 に絞り込まれ、その条件を満たす左の二輌だけが削除されるように見えますが、実際には全ての GreyTank1 が削除されます。 (またはどの GreyTank1 も削除されません。理由は後記) なぜなら、ここで参照されている GreyTank1 が絞り込みの対象ではないためです。 実は使用している条件が「二つの数値を比べる」であり、GreyTank1 はその 式の中 で参照されています↓ そのため、GreyTank1 は絞り込みの対象では無いのです。 また、この条件の GreyTank1 とは、三輌あるうちの(GDevelop の内部的に)最初の一輌のみを指しています。 もし、その最初の一輌の X 座標が 480 より小さいなら、全ての GreyTank1 (絞り込まれていないため)が削除されるし、480 以上なら条件を満たしていないので、アクションが実行されることはありません。(つまりどの GreyTank1 も消えない) 上記の例では、条件「二つの数値を比べる」ではなく、オブジェクトがもつ条件「オブジェクトの X 位置を比べる」を利用すれば、絞り込まれるようになります↓ しかし、必ずしも希望する条件をオブジェクトが有しているとは限りません。 例えばオブジェクトのポイント位置(PointX() や PointY())を比較する条件は、今のところ用意されていません。 その場合は、条件「二つの数値を比べる」を利用することになりますが、その式に登場するオブジェクトは絞...

GDevelop の「イベント」を正しく理解しよう

イメージ
特にプログラミング経験者がおちいりやすい罠なのですが、GDevelop の「イベント」は「if文」(条件分岐)ではありません。 このことは公式 Wiki でもサラッとしか説明されていないため、誤解したままイベントを if 文と同じように利用してしまうと、その独特な挙動に悩まされることになります。 ゲーム作りの基本コンセプト:GDevelop を使うために知っておきたいこと「イベントとそれがいかにしてオブジェクトを選択するか」 確かにイベントは if 文と同じ役割を果たす面もありますが、イベントの役割はそれだけではなく、 対象のオブジェクト(インスタンス)を絞り込み 、その上で絞り込まれたインスタンスに対し 一括でアクションを実行する事ができる 、という特徴があります。 例えば、次の画像のようなシーンで、ミサイルが当たっている戦車のみ削除したい場合は…… 次の画像のようなイベントを設定するだけで、ミサイルが当たっている戦車のみ削除することができます。 これは、イベントの条件で「ミサイルに衝突している戦車」のみにインスタンスが絞られたため、そのイベントのアクションで戦車を削除すると、ミサイルと衝突している戦車だけが削除されるという仕組みです。 このような特徴により、わざわざ次の画像のようにインスタンスをひとつずつ参照して、衝突しているか確認するようなイベントの組み方をする必要はありません。 (希望通りの動作はしますが、イベントの仕組みを正しく理解していない組み方です) さらに、この絞り込まれたインスタンスは、サブイベントにも引き継がれます。 例えば次の画像のように、それぞれの戦車にインスタンス変数を持たせて、異なる番号を割り当てたシーンならば…… 次の画像のようなイベントにすることで、ミサイルとの衝突時に戦車を ID ごとに異なるアニメーションに変化させることができます。 これは、最初のイベントでミサイルと衝突している戦車のみに絞り込み、更にサブイベントで ID が一致する戦車のみに絞り込むことで、それぞれ異なるアクションが実行される仕組みです。 なお、条件に該当するオブジェクトがない場合は、そのイベントのアクションは実行されません。 では、これまでの例とは異なり「戦車のどれか1輌にでもミサイルが当たったら、3輌全て消す」には、どうしたら良いかというと…… 上の画像のよ...

このブログの人気の投稿

【GDevelop】タイルスプライトで作る流れる背景

実は奥(闇)が深い「真のあいだ一度だけ実行(一度だけ実行する)」条件を使いこなそう【GDevelop】

GDevelop でシンプルなボタンの作り方