はじめに (対象読者・この記事でわかること)

この記事は、GDevelop を使ってゲームやインタラクティブコンテンツを作成している方、特に イベントの実行回数を制御したい と考えている開発者を対象にしています。
JavaScript の基礎知識が少しでもあれば、GDevelop のビジュアルイベントだけでは実現しづらい「○回目にだけ処理を走らせる」や「N 回実行したら別のロジックへ遷移する」などのロジックを簡単に追加できます。

この記事を読むことで以下ができるようになります。

  • GDevelop の「Variable」や「Counter」イベントを利用して、指定回数後に一度だけ処理を走らせる基本パターンを理解する。
  • JavaScript スクリプトを組み合わせ、条件判定や処理の分岐を柔軟に拡張できるようになる。
  • 実装中に遭遇しやすいエラーや、デバッグのコツを身につけ、スムーズに開発を進められるようになる。

本記事は、実務や個人プロジェクトで「回数制御」が必要になったときの即戦力になることを目的に執筆しました。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。

  • GDevelop の基本的な操作と、イベントシステム(条件・アクション)の概要
  • JavaScript の変数宣言、基本的な演算子、関数定義ができること
  • (任意)GDevelop の「Javascript code」アクションの使い方

GDevelop における回数制御の概要

GDevelop では、ビジュアルイベントだけで「何回目か」を管理するために 変数 を利用します。
たとえば「敵が倒された回数」や「ボタンがクリックされた回数」をカウントする場合、シーン変数やオブジェクト変数をインクリメントさせるだけで実装可能です。

しかし、単純なインクリメントだけでは 「5 回目にだけ特別な演出を走らせる」 といった要件を満たすのがやや面倒です。
そこで、以下の2つのアプローチが有効です。

  1. 条件分岐での直接チェック
    「変数が 5 と等しいときだけアクションを実行」 と書けば実現できますが、5 回目の直後に変数が 6 になると再度実行されない保証が必要です。

  2. JavaScript でカウンタロジックを拡張
    GDevelop の「Javascript code」アクションを使い、カウンタ増加と同時に「既に実行済みか」フラグを管理すれば、1 回だけ確実に処理を走らせられます。

この章では、まずビジュアルだけで実装できるシンプルパターンを示し、次に JavaScript でより堅牢かつ拡張性の高い実装へとステップアップする流れを説明します。

実装手順:指定回数後に処理を走らせる完全ガイド

以下では、「プレイヤーがアイテムを取得した回数が 3 回目になったときに、特別なボーナスエフェクトを表示」 という具体例をもとに、ステップごとに解説します。
全体で約 1500 文字程度になるよう、コード例とともにポイントを丁寧に説明します。

ステップ1 カウンタ変数の準備

  1. シーン変数 itemCount を作成
    * シーンエディタの「Variables」タブで「New variable」→itemCount → 初期値 0 と設定します。

  2. 取得イベントの作成
    * 条件:プレイヤーがアイテムに接触(Collision condition)
    * アクション:シーン変数 itemCount を 1 増やす(Add to variable)

Plaintext
条件 Player is in collision with Item アクション Do +1 to scene variable itemCount

このだけで、アイテム取得回数がシーン変数に蓄積されます。

ステップ2 ビジュアルだけで 3 回目を判定する(簡易版)

  1. 条件に比較を追加
    * 上記取得イベントに 「シーン変数 itemCount = 3」 という追加条件を設定。

  2. アクションでボーナスエフェクトを出す
    * 例:エフェクト「Glow」 をプレイヤーに付与、または 「Create object」 でエフェクトオブジェクトを生成。

Plaintext
条件 Player is in collision with Item AND Scene variable itemCount = 3 アクション Create object BonusEffect at Player.X; Player.Y

注意点:このままだと、itemCount が 4,5,... になるたびに条件が false になるので、3 回目だけ実行されます。
しかし、同フレーム内で複数回衝突が起きた場合(例:高速移動で重なったまま)に、itemCount が 3 → 4 と瞬時に変化し、3 回目の判定がスキップされるリスクがあります。

ステップ3 JavaScript で確実に 1 回だけ実行させる

このリスクを回避するために、JavaScript code アクションを使って「実行済みフラグ」を管理します。

  1. シーン変数 bonusTriggered(Boolean)を追加
    * 初期値 0(未実行)

  2. 取得イベントに JavaScript アクションを挿入

Javascript
// GDevelop の runtime にアクセス let itemCount = runtimeScene.getVariables().get("itemCount"); let bonusTriggered = runtimeScene.getVariables().get("bonusTriggered"); // カウントが 3 かつ未実行ならば処理を走らせる if (itemCount.getNumber() === 3 && bonusTriggered.getNumber() === 0) { // ボーナスエフェクトを作成(例: "BonusEffect" オブジェクト) runtimeScene.createObject("BonusEffect", runtimeScene.getObjects("Player")[0].getX(), runtimeScene.getObjects("Player")[0].getY()); // フラグを立てる bonusTriggered.setNumber(1); }
  1. イベントの流れ
    * ① アイテム取得 → itemCount が +1
    * ② 直後にこの JavaScript アクションが実行され、条件が満たされたらエフェクト生成とフラグ更新
    * ③ 以降の取得では bonusTriggered が 1 になっているため、再度実行されません

コードのポイント解説

項目 説明
runtimeScene.getVariables().get("itemCount") シーン変数オブジェクトを取得
getNumber() / setNumber() 変数の数値取得・設定
runtimeScene.createObject 任意のオブジェクトを動的生成
runtimeScene.getObjects("Player")[0] プレイヤーオブジェクトを取得(配列の 0 番目)

ステップ4 汎用化:任意回数でのコールバック関数化

同様のパターンを 複数箇所で使い回す ために、以下のようなユーティリティ関数を作成すると便利です。

Javascript
/** * 指定回数目にだけコールバックを実行し、以降は無視する * @param {gdjs.RuntimeScene} scene - 現在のシーン * @param {string} counterVar - カウント用シーン変数名 * @param {number} targetCount - 実行したい回数 * @param {function} callback - 実行したい処理 */ function runOnceAtCount(scene, counterVar, targetCount, callback) { const countVar = scene.getVariables().get(counterVar); const flagVarName = counterVar + "_triggered"; let flagVar = scene.getVariables().has(flagVarName) ? scene.getVariables().get(flagVarName) : null; if (!flagVar) { // フラグ変数が無ければ作成 scene.getVariables().set(flagVarName, 0); flagVar = scene.getVariables().get(flagVarName); } if (countVar.getNumber() === targetCount && flagVar.getNumber() === 0) { callback(); flagVar.setNumber(1); } }

使い方例(先ほどのボーナスエフェクト):

Javascript
runOnceAtCount(runtimeScene, "itemCount", 3, () => { const player = runtimeScene.getObjects("Player")[0]; runtimeScene.createObject("BonusEffect", player.getX(), player.getY()); });

この関数は 任意の変数名・任意の回数 に対応でき、コードの重複を大幅に削減します。

ハマった点やエラー解決

現象 原因 解決策
runtimeScene.createObject がエラーになる オブジェクト名がシーンに未登録 プロジェクトの「Objects」リストに対象オブジェクト(例: BonusEffect)を追加
フラグ変数が自動で作成されず undefined getVariables().has が古いバージョンで未実装 直接 scene.getVariables().set(flagVarName, 0) で作成し、取得後に使用
同フレームでカウントが 2 回増えると 3 回目がスキップ 複数衝突が同時に処理される カウント増加とフラグ判定を同一 JavaScript アクション内で行うか、await で待機させる(非同期は不要だがロジックをまとめる)

デバッグのコツ

  • 「Debug」パネルでシーン変数のリアルタイム値を確認。
  • JavaScript アクション内で console.loggdjs.evtTools.debug)を利用し、変数の状態を出力。
  • フラグ変数が期待通りに切り替わっているかを必ずチェックする。

以上で、「指定回数後に一度だけ処理を実行する」 完全な実装が完了です。

まとめ

本記事では、GDevelop で「指定回数後に処理を行う」課題を、ビジュアルだけの簡易実装から JavaScript を組み合わせた堅牢実装まで段階的に解説しました。

  • シーン変数とフラグ変数を利用し、回数カウントと実行済み判定を管理できること。
  • JavaScript code アクションでフラグロジックを実装すれば、同フレームでの多重衝突や非同期性の問題を回避できること。
  • 汎用ユーティリティ関数を作ることで、プロジェクト内の様々な「N 回目」ロジックを統一的に扱えること。

この手法を活用すれば、スコアのボーナス、ステージ解放条件、特殊エフェクトのトリガーなど、幅広いゲームロジックをシンプルかつ安全に実装できます。次回は、「時間経過と回数制御の複合」 について掘り下げ、タイムアウト付きカウントダウンロジックを紹介する予定です。

参考資料