スクリプトファイルのフォーマットは以下の形式を使用できます。
複数フォーマットが混在する状態で、#include を使用しファイル結合した場合は、
内部的には全てUnicodeに変換してファイルを結合します。
(不要な変換処理が入るため、フォーマットは1つに統一した方が速く動作します。)
種別 | 説明 |
Shift-JIS |
テキストエディタで、SJIS,Shift-JISを選択することで、保存することができる形式です。 (0.12mやph3 [.0]以前は、この形式のファイルのみ読み込むことができました) 日本語設定のWindowsでのみ正常に表示することができます。 |
Unicode (UTF16LE) |
テキストエディタで、Unicode,UTF16,UTF16LEを選択することで、保存することができる形式です。 ファイル先頭にBOM(Byte Order Mark)が必要です。 (Byte Order Markは、通常はテキストエディタが自動的に付加してくれます) |
スクリプトヘッダとは、弾幕風本体のメニューへの登録や自機スクリプトとして認識させるために
スクリプトの先頭に記述するテキストのことです。
「#~~~」で記述し、以下の種類があります。
要素 | 説明 |
#東方弾幕風[xxx] |
「#東方弾幕風」を記述することで東方弾幕風本体のメニューに登録することができます。 また「#TouhouDanmakufu」でも同様の意味があります。 以下の種類があります。 ・#東方弾幕風[Single]:単発スクリプトとしてメニューに登録します。 ・#東方弾幕風[Plural]:連続再生スクリプトとしてメニューに登録します。 ・#東方弾幕風[Stage]:ステージスクリプトとしてメニューに登録します。 ・#東方弾幕風[Package]:パッケージスクリプトとしてメニューに登録します。 ・#東方弾幕風[Player]:自機スクリプトとして弾幕風に認識させます。 |
#ScriptVersion[3] |
スクリプトバージョン3であることを示します。 スクリプトバージョン3のみしか再生できないため必須です。 |
#ID["XXX"] |
スクリプトのIDです。 内部的にスクリプトを区別するのに使用します。 できるだけ他のスクリプトと一致しない名称にする方が良いです。 省略可能です。 省略した場合はファイル名になります。 |
#Title["XXX"] |
メニューのタイトルに使用される文字列です。 |
#Text["XXX"] |
メニューでの説明に使用される文字列です。 |
#Image["XXX"] |
メニューの画像に使用される画像ファイルへのパスです。 640×480の画像を指定します。 実行ファイル位置からの相対パスです。 ただし[./~]のようにパスの最初に「./」をかくと、スクリプトファイルのあるフォルダからの相対パスになります。 省略可能です。 |
#System["XXX"] |
システムスクリプトへのパスです。 システムスクリプトではスコアや残機、敵ライフの表示などを行います。 実行ファイル位置からの相対パスです。 ただし[./~]のようにパスの最初に「./」をかくと、スクリプトファイルのあるフォルダからの相対パスになります。 省略可能です。 省略した場合「/script/default_system/Default_System.txt」のシステムスクリプトが適応されます。 |
#Background["XXX"] |
背景スクリプトへのパスです。 実行ファイル位置からの相対パスです。 ただし[./~]のようにパスの最初に「./」をかくと、スクリプトファイルのあるフォルダからの相対パスになります。 省略可能です。 省略した場合、背景は黒となります。 内部的には、このパスを使用して、LoadScript→StartScriptしているだけです。 省略した場合でも、独自に背景用のスクリプトをLoadScript→StartScriptすれば背景は描画されます。 |
#BGM["XXX"] |
BGMに使用されるファイルへのパスです。 実行ファイル位置からの相対パスです。 ただし[./~]のようにパスの最初に「./」をかくと、スクリプトファイルのあるフォルダからの相対パスになります。 省略可能です。 省略した場合は無音になります。 内部的には、このパスを使用して、音声再生をしているだけです。 省略した場合でも、独自に音声再生を行えばBGMは鳴ります。 |
#Player["XXX","YYY",...] |
このスクリプトで使用できる自機スクリプトへのパスです。 「,」で区切って複数の自機を登録します。 実行ファイル位置からの相対パスです。 ただし[./~]のようにパスの最初に「./」をかくと、スクリプトファイルのあるフォルダからの相対パスになります。 省略可能です。 省略した場合は「/script/player/」下のすべての自機スクリプトが使用可能になります。 |
#ReplayName["XXX"] |
リプレイ用の自機名称です。 8文字以内で指定します。 |
組み込みルーチンは「@XXX」で記述される特別なルーチンのことです。
特定のタイミングで弾幕風本体から自動的に呼び出されます。
以下の種類があります。
種類 | 説明 |
@Initialize |
スクリプト初期化時に一度だけ呼び出されます。 1回目の@MainLoopが呼び出される直前に呼ばれます。 |
@Finalize |
スクリプト終了時に一度だけ呼び出されます。 |
@MainLoop |
スクリプトがアクティブな場合に毎フレーム一度ずつ呼び出されます。 |
@Loading |
主にLoadScriptInThreadでのスクリプト読み込み時に呼び出され、 別スレッドでの初期化を行います。 テクスチャや音声の読み込みにのみ使用でき、 オブジェクトの生成などを行うとエラーになります。 乱数も使用できません。 (実行タイミングが制御できないため、リプレイの再生に影響が出るため。) |
@Event |
特定のイベントが発生したときに呼び出されます。 イベントを参照願います。 |
単発再生用スクリプトです。
スクリプトに「#東方弾幕風[Single]」と記述することで認識されます。
通常は敵のスペルカード1枚分に相当します。
以下に記述例を示します。
#東方弾幕風[Single] #ScriptVersion[3] #Title["星符「ミッドナイトレヴァリエ」"] #Text["Exルーミア最初のスペルカード:星符「ミッドナイトレヴァリエ」"] #Image["./img/ExRumia(星符「ミッドナイトレヴァリエ」).png"] #Background["script/default_system/Default_Background_IceMountain.txt"] #include"script/default_system/Default_ShotConst.txt" #include"script/default_system/Default_Effect.txt" let objEnemy; let bConcentrationMotion = false; @Initialize { objEnemy = ObjEnemy_Create(OBJ_ENEMY_BOSS); ObjEnemy_Regist(objEnemy); ObjEnemy_SetDamageRate(objEnemy, 10, 10);//披ダメージを10%に設定 TWork; TRender; TEnd; DeleteShotAll(TYPE_ALL, TYPE_ITEM);//出現と同時に敵弾を全て削除 } @MainLoop { let ex = ObjMove_GetX(objEnemy); let ey = ObjMove_GetY(objEnemy); ObjEnemy_SetIntersectionCircleToShot(objEnemy, ex, ey, 32);//当たり判定(自弾)登録 ObjEnemy_SetIntersectionCircleToPlayer(objEnemy, ex, ey, 24);//当たり判定(体当たり)登録 yield; } @Event { alternative(GetEventType()) case(EV_REQUEST_LIFE) { SetScriptResult(1500);//ライフを1500に設定 } case(EV_REQUEST_TIMER) { SetScriptResult(60);//時間制限を60秒に設定 } case(EV_REQUEST_SPELL_SCORE) { SetScriptResult(30000);//スペルカードボーナスを30000に設定 } } //~~~敵の制御など //---------------------------------------------------- //終了待機タスク //---------------------------------------------------- task TEnd { while(ObjEnemy_GetInfo(objEnemy, INFO_LIFE) > 0) { yield; } let ex = ObjMove_GetX(objEnemy); let ey = ObjMove_GetY(objEnemy); TExplosionA(ex, ey, 10, 0.6); DeleteShotAll(TYPE_ALL, TYPE_ITEM);//敵弾を全て削除 //連続再生の場合は敵を削除することで、 //次の段階に進みます。 //必ず削除してください。 Obj_Delete(objEnemy); loop(30){yield;} //最後はスクリプトをクローズしてください CloseScript(GetOwnScriptID()); }
連続再生用スクリプトです。
スクリプトに「#東方弾幕風[Plural]」と記述することで認識されます。
通常は敵のボス1体分に相当します。
以下に記述例を示します。
#東方弾幕風[Plural] #ScriptVersion[3] #Title["Exルーミアスクリプト連続再生"] #Text["Exルーミアスペルカード"] #Image["./img/ExRumia(星符「ミッドナイトレヴァリエ」).png"] #Background["script/default_system/Default_Background_IceMountain.txt"] @Initialize { TPlural(); } @MainLoop { yield; } @Finalize { } task TPlural { let dir = GetCurrentScriptDirectory(); //ボスシーンを作成します。 let obj = ObjEnemyBossScene_Create(); ObjEnemyBossScene_Add(obj, 0, dir ~ "ExRumia01.txt"); ObjEnemyBossScene_Add(obj, 0, dir ~ "ExRumiaSpell01.txt"); ObjEnemyBossScene_LoadInThread(obj); ObjEnemyBossScene_Regist(obj); //敵ボスシーンが終了するまで待機 while(!Obj_IsDeleted(obj)) { yield; } //スクリプト終了 CloseScript(GetOwnScriptID()); }
ステージスクリプトです。
スクリプトに「#東方弾幕風[Stage]」と記述することで認識されます。
通常は1ステージ分に相当します。
以下に記述例を示します。
#東方弾幕風[Stage] #ScriptVersion[3] #Title["EXルーミアテストステージ"] #Text["EXルーミアテストステージ"] #Image["./img/ExRumia(星符「ミッドナイトレヴァリエ」).png"] #Background["script/default_system/Default_Background_IceMountain.txt"] @Initialize { TStage(); } @MainLoop { yield; } @Finalize { } task TStage { let dir = GetCurrentScriptDirectory(); //ボス再生 let path = dir ~ "ExRumia_Plural.txt"; let idScript = LoadScriptInThread(path); loop(60){yield;}//1秒くらいあれば、コンパイル完了すると思われる。 StartScript(idScript); //敵ボスシーンが終了するまで待機 while(!IsCloseScript(idScript)) { yield; } //~~~敵の出現やボスの出現を繰り返す。 loop(240){yield;} //ステージ終了 CloseStgScene(); }
自機スクリプトです。
スクリプトに「#東方弾幕風[Player]」と記述することで自機用のスクリプトとして認識されます。
以下に記述例を示します。
#Image["./ExRumiaImage.png"] let objPlayer = GetPlayerObjectID(); let objSlowShot = ID_INVALID; let current = GetCurrentScriptDirectory(); @Initialize { let path = current ~ "Default_Player_RumiaShotData.txt"; LoadPlayerShotData(path); //自弾画像ロード ObjPlayer_AddIntersectionCircleA(objPlayer, 0, 0, 1, 20); //当たり判定登録 TImage();//自機描画用タスク起動 TShot();//弾発射用タスク起動 TMagicCircle();//無敵時間魔法陣タスク起動 } @MainLoop { yield; } @Finalize { } @Event { alternative(GetEventType()) case(EV_REQUEST_SPELL) { //スペルカード要求 let spell = GetPlayerSpell();//残りスペル数 if(spell >= 1) { SetScriptResult(true);//スペル発動可能 SetPlayerSpell(spell-1);//スペル数を1減らす TSpell();//スペルタスク起動 } else { SetScriptResult(false);//スペル発動不可 } } case(EV_HIT) { //被弾 TExplosion(); } case(EV_PLAYER_REBIRTH) { //復帰 SetPlayerSpell(3); SetPlayerInvincibilityFrame(180); } } //~~~省略
一時停止中などに呼び出されるスクリプトで、
メニュー系シーンのカスタマイズを行えます。
サンプルは各デフォルトスクリプトを参照お願いします。
いずれもSetScriptResultで特定の値を設定する必要があります。
これらのスクリプトでは自機や弾などの操作を行うことはできません。
種類 | 説明 |
一時停止 |
一時停止(ポーズ)中に呼び出されるスクリプトです。 システムスクリプト中で「SetPauseScriptPath」で使用スクリプトを設定します。 デフォルトでは「/script/default_system/Default_Pause.txt」が使用されます。 SetScriptResultに以下のいずれかを設定する必要があります。 ・RESULT_CANCEL:再開 ・RESULT_END:スクリプト:再生終了 ・RESULT_RETRY:リトライ |
STGシーン終了 |
ゲームオーバーやステージクリア時に呼び出されます。 デフォルトでは「/script/default_system/Default_EndScene.txt」が使用されます。 SetScriptResultに以下のいずれかを設定する必要があります。 ・RESULT_SAVE_REPLAY:リプレイ保存 ・RESULT_END:スクリプト:再生終了 ・RESULT_RETRY:リトライ |
リプレイ登録 |
リプレイ登録時に呼び出されます。 デフォルトでは「/script/default_system/Default_ReplaySaveScene.txt」が使用されます。 SetScriptResultに以下のいずれかを設定する必要があります。 ・RESULT_CANCEL:キャンセル ・RESULT_END:リプレイ保存終了 |
@Initialize { //弾削除時得点アイテム自動作成無効化 SetDefaultBonusItemEnable(false); //ユーザ定義アイテムデータ読み込み let dir = GetCurrentScriptDirectory(); LoadItemData(dir ~ "ItemData.txt") } @Event { alternative(GetEventType()) case(EV_GET_ITEM) { //アイテム取得イベント let itemType = GetEventArgument(0); //アイテム種別取得 let objItem = GetEventArgument(1); //アイテムオブジェクト取得 //アイテム取得時処理 } case(EV_DELETE_SHOT_TO_ITEM) { //弾削除時アイテム作成イベント let objShot = GetEventArgument(0); //オブジェクト取得 let objPos = GetEventArgument(1); //弾オブジェクト座標取得([0]=x, [1]=y) //弾削除時アイテム作成処理 TUserItem(objPos[0], objPos[1]); } } //ユーザ定義アイテム作成 task TUserItem(let itemX, let itemY) { let obj = CreateItemU1(1, itemX, itemY, 10000); ObjItem_SetDefinedMovePatternA1(obj, ITEM_MOVE_TOPLAYER); }
@Initialize { //弾消し(即消時)イベント有効 SetShotDeleteEventEnable(EV_DELETE_SHOT_IMMEDIATE, true); } @Event { alternative(GetEventType()) case(EV_DELETE_SHOT_IMMEDIATE) { //弾消し時イベント有効 let objShot = GetEventArgument(0); //オブジェクト取得 let objPos = GetEventArgument(1); //弾オブジェクト座標取得([0]=x, [1]=y) //弾消し時動作記載 } }
タイトル画面、リプレイ一覧画面、ステージの連続再生など、
すべての機能を作成するためのスクリプトです。
パッケージスクリプト専用の関数は
パッケージスクリプト専用関数
を参照お願いします。
記述方法は以下のサンプルスクリプトを参照お願いします。
/script/ExRumia/ExRumia_Package_Main.txt
実行ファイルをパッケージスクリプト再生専用にするには、「定義ファイル(th_dnh.def)」を参照お願いします。
@Eventは特定のタイミングで呼び出されます。
イベントの種類は、「GetEventType」で取得できます。
引数のあるイベントの場合は「GetEventArgument」で取得でき、
返値が必要なイベントの場合は「SetScriptResult」で返値を設定します。
組み込みのイベントには、以下の種類があります。
イベント種類 | 説明 |
EV_REQUEST_LIFE |
敵ボスのライフの要求です。 敵ボススクリプトのみで呼び出されます。 real値を「SetScriptResult」で返す必要があります。 要求された場合に無視するとエラーになります。 |
EV_REQUEST_TIMER |
敵ボスのタイマー要求です。 敵ボススクリプトのみで呼び出されます。 real値を「SetScriptResult」で返す必要があります。 無視すると、無制限になります。 |
EV_REQUEST_IS_LAST_SPELL |
ラストスペル要求です。 敵ボススクリプトのみで呼び出されます。 boolean値を「SetScriptResult」で返す必要があります。 無視すると、ラストスペルではなくなります。 |
EV_REQUEST_IS_DURABLE_SPELL |
耐久スペル要求です。 敵ボススクリプトのみで呼び出されます。 boolean値を「SetScriptResult」で返す必要があります。 無視すると、耐久スペルではなくなります。 |
EV_REQUEST_SPELL_SCORE |
スペルカードスコア要求です。 敵ボススクリプトのみで呼び出されます。 boolean値を「SetScriptResult」で返す必要があります。 無視すると、0点になります。 |
EV_TIMEOUT |
敵スペルのタイムアウト通知です。 アクティブな全スクリプトに通知されます。 |
EV_START_BOSS_SPELL |
敵スペルカード開始通知です。 アクティブな全スクリプトに通知されます。 |
EV_GAIN_SPELL |
スペルカード取得通知です。 アクティブな全スクリプトに通知されます。 |
EV_START_BOSS_STEP |
ボスの1ステップ開始通知です。(Singleの1スクリプト相当開始通知です。) アクティブな全スクリプトに通知されます。 |
EV_END_BOSS_STEP |
ボスの1ステップ終了通知です。(Singleの1スクリプト相当終了通知です。) アクティブな全スクリプトに通知されます。 |
EV_PLAYER_SHOOTDOWN |
自機撃墜通知です。 アクティブな全スクリプトに通知されます。 |
EV_PLAYER_SPELL |
自機スペル発動通知です。 アクティブな全スクリプトに通知されます。 |
EV_PLAYER_REBIRTH |
自機復帰通知です。 アクティブな全スクリプトに通知されます。 |
EV_PAUSE_ENTER |
一時停止開始通知です。 アクティブな全スクリプトに通知されます。 音声の停止操作などを想定しています。 このイベント内では、乱数の使用、敵/弾オブジェクトの生成などSTGシーンに影響を与える処理は行わないでください。 リプレイがずれます。 |
EV_PAUSE_LEAVE |
一時停止解除通知です。 アクティブな全スクリプトに通知されます。 音声の再開操作などを想定しています。 このイベント内では、乱数の使用、オブジェクトの生成などSTGシーンに影響を与える処理は行わないでください。 リプレイがずれます。 |
EV_REQUEST_SPELL |
自機スペル開始要求です。 自機スクリプトのみで呼び出されます。 boolean値を「SetScriptResult」で返す必要があります。 スペルカードを呼び出せる場合にtrueを返します。 要求された場合に無視するとエラーになります。 |
EV_GRAZE |
かすり通知です。 自機スクリプトのみで呼び出されます。 かすりのエフェクトや効果音を再生するのに使用します。 GetEventArgument(0):前フレームのかすり回数(real) GetEventArgument(1):前フレームのかすった弾IDのリスト(real配列) GetEventArgument(2):前フレームのかすった弾座標のリスト(real配列[index][x, y]) |
EV_HIT |
撃墜通知です。 自機スクリプトのみで呼び出されます。 自機の撃墜エフェクトや効果音を再生するのに使用します。 GetEventArgument(0):自機に当たった敵/弾ID(real) |
EV_GET_ITEM |
アイテム取得通知です。 自機スクリプト、アイテムスクリプトのみで呼び出されます。 GetEventArgument(0)でどのアイテムを取得したかを確認できます。 ・ITEM_POWER:パワーアップアイテム ・ITEM_POWER_S:パワーアップアイテム(小) ・ITEM_SPELL:スペル(ボム)アイテム ・ITEM_SPELL_S:スペル(ボム)アイテム(小) ・ITEM_POINT:点アイテム ・ITEM_POINT_S:点アイテム(小) GetEventArgument(1)でアイテムオブジェクトのIDを取得できます。 |
EV_DELETE_SHOT_IMMEDIATE |
敵弾の削除通知です。 弾動作カスタムスクリプトで呼び出されます。 弾動作カスタムスクリプトでのイベント通知は、 SetShotDeleteEventEnable(EV_DELETE_SHOT_IMMEDIATE, true); を呼び出すと有効になります。 GetEventArgument(0)で弾オブジェクトのIDを取得できます。 GetEventArgument(1)で弾座標を取得できます。(real配列 [x, y]) |
EV_DELETE_SHOT_TO_ITEM |
敵弾のアイテム化通知です。 アイテム動作カスタムスクリプトで呼び出されます。 GetEventArgument(0)で弾オブジェクトのIDを取得できます。 GetEventArgument(1)で弾座標を取得できます。(real配列 [x, y]) |
EV_DELETE_SHOT_FADE |
敵弾のフェード削除通知です。 弾動作カスタムスクリプトで呼び出されます。 弾動作カスタムスクリプトでのイベント通知は、 SetShotDeleteEventEnable(EV_DELETE_SHOT_FADE, true); を呼び出すと有効になります。 GetEventArgument(0)で弾オブジェクトのIDを取得できます。 GetEventArgument(1)で弾座標を取得できます。(real配列 [x, y]) |
イベント種類 | 説明 |
EV_USER_SYSTEM |
システムスクリプト用のユーザ定義イベント値です。 EV_USER_SYSTEM~EV_USER_SYSTEM + EV_USER_COUNT までの値を指定できます。 |
EV_USER_STAGE |
ステージ(敵)スクリプト用のユーザ定義イベント値です。 EV_USER_STAGE~EV_USER_STAGE + EV_USER_COUNT までの値を指定できます。 |
EV_USER_PLAYER |
自機スクリプト用のユーザ定義イベント値です。 EV_USER_PLAYER~EV_USER_PLAYER + EV_USER_COUNT までの値を指定できます。 |
EV_USER_PACKAGE |
パッケージスクリプト用のユーザ定義イベント値です。 EV_USER_PACKAGE~EV_USER_PACKAGE + EV_USER_COUNT までの値を指定できます。 |
EV_USER |
ユーザ定義イベント値です。 EV_USER~EV_USER + EV_USER_COUNT までの値を指定できます。 |