RPGツクールプラグイン制作過程紹介 第8回
前回はたきぎ以外のイベントに対応可能にし、その一環としてプラグインコマンドの引数の使い方も見てきました。
第8回となる今回は、いよいよ《ファイアⅠ》以外のスキルの作り方を見ていきます!
作成するスキルの仕様構想
《ファイアⅠ》以外のスキルといっても色々あるわけですが、今回は《ファイアⅠ》と相反する関係のスキルである《ウォーターⅠ》の処理を作っていきたいと思います。
水をかけることで期待される反応というと、何を思い浮かべるでしょうか。
容器に水を注いだり、植物に水をやったり、喉を潤したり…色々考えられます。
今回は最もオーソドックスであり、またこれまでに作ってきた《ファイアⅠ》と密接な関係のある「火を消す」という反応を作っていきたいと思います。
現在の仕様確認
まずは現在の仕様のまま組んでみることにします。
《ウォーターⅠ》を以下のように、《ファイアⅠ》のときと同様に設定します。
使用可能時を常時、コモンイベントに3番を設定しました。
続いてそのコモンイベント3番を設定します。まずはこれまで《ファイアⅠ》に使用してきたコモンイベント2番の内容をコピーします。
あとは《ファイアⅠ》特有の設定を《ウォーターⅠ》に準拠した設定に変更します。
すなわちアニメを81番に、不発時に回復するMP量を20にします。
これでコモンイベントの設定はできました。
続いてその対象となるイベントをマップ上に設置しましょう。
まずは「最初から火がついているたき火」を作ってみることにします。そこに《ウォーターⅠ》を使用すると火が消える、という想定です。
これまでのたきぎとは反対のパターンですね。
以下のように設定します。
また、テストしやすいように魔法使いが《ウォーターⅠ》をレベル1で習得するように設定しておきましょう。
ここまでできたらテスト開始です!
きちんと動作していますね。これでひとまず設定できました。
続いてはこのように最初からたき火なのではなく、これまでに作った《ファイアⅠ》で火をつけられるたきぎイベントを対象にしてみましょう。
つまり《ファイアⅠ》で火をつけた後に《ウォーターⅠ》で消火する、という流れです。そのような行為にゲーム上どのような意味を持たせるのかはさておき、一つのイベントに複数の反応が用意されているとスキル利用の幅がより広がって楽しくなりそうな気がします。
早速設定してみましょう。
…と言いたいところですが、どのように設定すればいいのでしょうか。
これまではイベントのメモに<skillSwitchId:スイッチ番号>と記述することでスキル使用後にオンにするスイッチを指定してきましたが、このイベントにはすでに《ファイアⅠ》用のスイッチを指定しています。
そこにさらに消火用のスイッチを設定しようにも、このメタタグには一つのスイッチ番号しか指定できないのです。
これでは《ファイアⅠ》と《ウォーターⅠ》の区別ができませんね。
…ということは、ひょっとして現状だとこのようになってしまうのではないでしょうか。
このようにスキルの種別を問わずイベントにスイッチが入ってしまうのです。これは問題ですね。
どうすれば解決できるでしょうか。
問題点の確認
なぜこのような挙動になってしまうのでしょうか。改めて、以前に作成したtoggleSwitchesByFacingSkillTargets関数を見てみましょう。
Game_Player.prototype.toggleSwitchesByFacingSkillTargets = function() {
const events = this.facingSkillTargets();
for (const event of events) {
const switchId = event.skillSwitchId();
$gameSwitches.setValue(switchId, true);
}
};
まずプレイヤーの目の前にある全てのイベントを取得し、そのイベントごとに設定されているスイッチIDを入れる、という処理をしています。
もうお気づきの方もいらっしゃるでしょう。そう、この関数にはスキルの種類の区別がないのです。
だから《ファイアⅠ》と《ウォーターⅠ》のどちらを使ってもイベントが反応してしまうのですね。
これを解決するには、イベントに設定されているスイッチ番号をスキル種別ごとに変える、という方法が考えられます。例えば《ファイアⅠ》が使用されたときはスイッチ1番をオンにする、といった具合です。
反対に、スイッチ1番がオンになっている(火が点いている)状態で《ウォーターⅠ》が使用されたときは最初のページに戻ることで火が消えたことを表現したいので、スイッチは必ずしもオンにするばかりではなくスキル次第ではオフにもできるような仕組みにしたいところです。
また、これまではたきぎ一つ一つに対してスイッチ番号を設定してきましたが、数が多くなると管理が大変になります。しかもたきぎをコピーしただけでは同時に発火してしまうのでスイッチ番号を変える必要がありました。
このような仕様ではあまり使い勝手がいいとは言えません。そこでスイッチには通常のゲームスイッチではなくセルフスイッチを使用することにします。これならイベントを丸ごとコピーすることが可能になります。
これを実現するには以下のようなデータ構造が考えられます。
コモンイベントID:スキルに設定されているコモンイベントの番号
セルフスイッチ記号:スキル使用後に変更されるセルフスイッチの記号
変化後スイッチ:オンかオフか
スイッチ条件:オンになっていることが前提となるセルフスイッチの記号
そして一つのイベントには複数のスキルに対する反応を設定したいので、このデータ構造を複数設定できるようにしたいところです。
そのような複雑な設定をイベントのメモに記述するのは無理があります。そこで、その設定にそれぞれ固有の名前(識別子)をつけて、その名前をメモに記述することでその設定が参照されるという仕様にすることにします。これならメモにも記述しやすくなります。
この仕組みなら、他の可燃物に設定を流用することも可能になります。例えば前回作成したロウソクイベントの設定に、たきぎのものを流用できるようになります。
今回作成する「炎系スキルを使用すると火がつき(セルフスイッチAがオンになる)、セルフスイッチAがオンの状態で水系スキルを使用すると火が消える(セルフスイッチAがオフになる)」という設定にはcombustible(可燃物)という名前(識別子)をつけることにします。
では、このような設定をどこに設ければ良いでしょうか? プラグインに直接記述することもできますが、これはあくまでも「プラグイン素材」です。作者以外のユーザーも使うことを想定する必要があります。
プラグインユーザーにとって、設定しやすい場所はどこなのかといえば…プラグインをよく使う方であれば、もうお分かりでしょう。そう、プラグインパラメータです。
プラグインパラメータはプラグインコマンドと同様、非常に多様なフォーマットを用意することができます。数値を入力させることも、アニメを指定することもできます。
それではプラグインパラメータの設定方法を確認していきましょう。
プラグインパラメータの定義
プラグインパラメータはプラグインコマンドと同様、アノテーションに記述することで設定できます。以下の書式になります。
* @param paramName
* @text パラメータ名
* @desc パラメータの説明
* @default
* @type number
(公式プラグイン講座より抜粋)
プラグインコマンドとよく似ていますね。違いを見ていきましょう。
@paramはこのパラメータの名前(識別子)です。ここは、プラグインコマンドの@commandに相当します。つまりプラグインパラメータにせよプラグインコマンドにせよ区別のために名前をつける必要があるわけですが、名前を@paramの後に書いた場合プラグインパラメータとみなされ、@commandの後ろであればプラグインコマンドとみなされる、という仕組みなのです。
@textと@descはプラグインコマンドにもあったものと同一と考えて問題ありません。多言語対応においてはこれらを変えることになります。
@defaultはプラグインコマンドにはありませんでしたね。これは、このパラメータのデフォルト値になります。つまりユーザーが何も指定しなかった場合に自動的に使用される値です。
@typeはプラグインコマンドにもありましたが、使用できる型の種類も共通です。今回はstructという型を使用することにします。structとはいわゆる構造体で、複数の値を保持する入れ物とでもお考えください。
まず、以下のように記述します。
* @param skillReactionPatterns
* @text スキル反応パターン
* @desc スキルに対する反応パターンを、反応の種類だけ定義します。
* @type struct<switchPatternList>[]
イベントの、スキルに対する反応のパターンを定義するパラメータなので@paramはskillReactionPatternsとしました。
@typeには上述の通りstructを指定しますが、後ろには<型名>という、任意の名前を指定します。詳細は後述します。
さらにその後ろには[]が付いています。これは、このパラメータで取得される値を配列にするための指定です。これから作る、火をつけたり消したりする反応を上述のcombustibleという設定にまとめるとして、それ以外にも作りたいパターンは色々考えられます。
例えば液体に対する、《アイスⅠ》で凍結させたり《ファイアⅠ》でそれを溶かしたりといった反応なども作りたいですよね。つまり設定を複数格納できる入れ物が必要なのです。
ですのでこのパラメータの値は、structという構造体を複数格納することができるように配列にするのです。ちなみに@paramをskillReactionPattern"s"と複数形で命名したのもそのためです。
なお今回は@defaultを省略しています。
ここまでで一通り定義できましたが、structを使用する場合もう一つしなければならないことがあります。struct自体は入れ物なので、その具体的な中身は別途定義する必要があるのです。
structの中身は、アノテーション本体とは別枠で定義する必要があります。
/*~struct~型名:
*
* @param param
* @text パラメータ名称
* @desc パラメータの説明
* @default
* ......
*/
(公式プラグイン講座より抜粋)
定義できる内容自体はプラグインパラメータと変わりません。
今回は、以下のように定義しました。
/*~struct~switchPatternList:ja
*
* @param identifier
* @text 識別子
* @desc スキル反応パターンの識別子です。
* @type string
*
* @param patterns
* @text スキル反応パターンリスト
* @desc スキル反応パターンのリストです。
* @type struct<switchPattern>[]
*
*/
順番に見ていきましょう。
/*~struct~switchPatternList:ja
structの型は、~struct~の後ろに上記のstruct<型名>で定義したものと同じ名前を記述することで定義します。今回はswitchPatternListです。
なおその後ろには:jaとついていますが、structの型も多言語対応可能であり、ここでは日本語を指定しています。
* @param identifier
* @text 識別子
* @desc スキル反応パターンの識別子です。
* @type string
この反応の識別子の入力用パラメータです。
ユーザーはここに任意の文字列を入力することが期待されます。
関数側では、その文字列によって取得すべき反応パターンを区別するような動作にします。
* @param patterns
* @text スキル反応パターンリスト
* @desc スキル反応パターンのリストです。
* @type struct<switchPattern>[]
これはスキルの反応パターンを複数格納するための入れ物です。
@typeには上記とは別の型名(switchPattern)を持つstructを指定しています。
《ファイアⅠ》に対する反応や、《ウォーターⅠ》に対する反応を一つの塊とみなすとして、複数のスキルに対する反応を格納する必要があるので、ここでもまたstructに[]をつけて配列の値としています。
そして、また別枠のアノテーションに~struct~switchPatternと記述することでこのstructの型を定義します。
/*~struct~switchPattern:ja
*
* @param commonEventId
* @text コモンイベントID
* @desc イベントに作用するコモンイベントのIDです。
* @type common_event
*
* @param selfSwitchCh
* @text セルフスイッチ記号
* @desc 変化するセルフスイッチの記号です。
* @default A
* @type select
* @option A
* @option B
* @option C
* @option D
*
* @param selfSwitchValue
* @text 変化後スイッチ
* @desc 反応後に変化するセルフスイッチの値です。
* @type boolean
* @default true
*
* @param selfSwitchCondition
* @text セルフスイッチ条件
* @desc この反応を有効にするためにオンになっている必要があるセルフスイッチの記号です。
* @default なし
* @type select
* @option なし
* @value null
* @option A
* @option B
* @option C
* @option D
*
*/
再度上から見ていきましょう。
* @param commonEventId
* @text コモンイベントID
* @desc イベントに作用するコモンイベントのIDです。
* @type common_event
スキルに設定されているコモンイベントの番号です。
@typeにはそのものズバリのcommon_eventを指定しているので、ユーザーはコモンイベント一覧から選択することができます。
* @param selfSwitchCh
* @text セルフスイッチ記号
* @desc 変化するセルフスイッチの記号です。
* @default A
* @type select
* @option A
* @option B
* @option C
* @option D
スキル使用後に変化するセルフスイッチの記号です。
@typeにselectを指定し、@optionを必要なだけ記述すると、プルダウンから@optionの項目を指定できるようになります。
実際の画面は以下のようになります。
* @param selfSwitchValue
* @text 変化後スイッチ
* @desc 反応後に変化するセルフスイッチの値です。
* @type boolean
* @default true
この反応が起きた際に変化するセルフスイッチの値です。
@typeにbooleanを指定するとオンかオフの二択になります。
デフォルト値はtrue、つまりオンにしました。
* @param selfSwitchCondition
* @text セルフスイッチ条件
* @desc この反応を有効にするためにオンになっている必要があるセルフスイッチの記号です。
* @default なし
* @type select
* @option なし
* @value null
* @option A
* @option B
* @option C
* @option D
最後は、この反応が有効になるためにオンになっている必要があるセルフスイッチの記号です。
こちらも@typeにはselectを指定し、@optionに選択肢を指定しています。
ただしselfSwitchChと違い、必ずしもいずれかのセルフスイッチがオンになっていないといけないわけではないので、「なし」という@optionも用意しています。また、これがデフォルトになっています。
なしの下には@value nullと指定していますが、これはなしの実際の値です。なしはただの文字列ですが、プログラム的に意味を持たせるためにnullを指定しています。
なお@optionのA〜Dには@valueを指定していませんが、省略した場合@optionがそのまま値になります。つまり"A"や"B"といった文字列が値になります。
全体としては、以下のような並びになっています。
このように、アノテーション本体とは別のアノテーションを作り、その中に記述しています。
structの型の定義はそれぞれが単独のアノテーションなので、多言語対応も別枠で用意する必要があります。
これでプラグインパラメータができました。
続いてツクール上で実際に設定していきます。
プラグインパラメータの設定
プラグイン管理からFieldActionを開きます。
そしてパラメータのスキル反応パターンをダブルクリックします。
この時点ではまだ空のリストです。
上でstructに[]を付けたので、複数の構造体を格納できる配列になっているのです。
一番上の空欄をダブルクリックします。
switchPatternListで定義したstructのパラメータが現れています。
上からダブルクリックしてみましょう。
識別子には文字列が入力可能になっています。
今回はcombustibleと指定しました。
スキル反応パターンリストは再び配列になっています。ダブルクリックします。
するとswitchPatternで指定したstructのパラメータが現れます。
まずは《ファイアⅠ》の設定を作っていきます。
コモンイベントはこのようにコモンイベント一覧から選択できます。
今回は2番の「たきぎ(第4回)」を指定しました。
値を変化させるセルフスイッチの記号です。
今回はAと指定します。
セルフスイッチの変化後の値です。
今回はオンにしました。
このパターンが有効になるためにオンになっている必要のあるセルフスイッチの記号です。
今回は特に条件を指定しないのでなしを選択しました。
ここまで設定できたらOKをクリックします。
続いては《ウォーターⅠ》の設定を作っていきます。
2番目の空欄をダブルクリックします。
以下のように設定しました。
コモンイベントIDは3、セルフスイッチ記号はA、変化後スイッチはオフ、セルフスイッチ条件はAです。
《ファイアⅠ》でオンにしたセルフスイッチAをオフにすることで消火を表現できるように変化後スイッチにオフを、セルフスイッチ条件にAを設定したところがポイントです。
ここまでできたら可燃物反応combustibleは出来上がりなので、保存しましょう。
続いてはこのパラメータを実際に使った処理を組んでいきましょう…と言いたいところですが、長くなったので今回はここまでとします!
まとめ
今回は別々のスキルに対する反応を使い分けるために、プラグインパラメータ、特にstructの使い方を見てきました。お疲れ様でした。
次回は今回の続きということで、プラグインパラメータの取得方法とその利用方法を見ていきます。
今回までの最終コード
今回からGitHubの公開リポジトリにて、このプロジェクトのdataフォルダの内容とプラグインファイル(FieldAction.js)を公開することにしました。
以下にアクセスすることでご自由にダウンロードしていただくことができます。
ダウンロードしたファイルを新規プロジェクトの所定フォルダ内にそれぞれコピー(置き換え)することで、本シリーズのプロジェクトと同一内容にできます。
なおライセンスはMITライセンスです。
//=============================================================================
// RPG Maker MZ -
//=============================================================================
/*:
* @target MZ
* @plugindesc
* @author
*
* @help
*
* @param skillReactionPatterns
* @text Skill Reaction Patterns
* @desc Contains skill reaction patterns as many as necessary.
* @type struct<switchPatternList>[]
*
* @command toggleSwitchesByFacingSkillTargets
* @text Turn Switches on by Events Faced by Player
* @desc Turns on switches whose IDs correspond to <skillSwitchId: > note of events faced by the player.
*
* @command requestAnimationAtFacingSkillTargets
* @text Show Animation at Facing Events
* @desc Show a specified animation at events faced by the player.
*
* @arg animationId
* @text Animation ID
* @desc ID of the animation to be shown.
* @type animation
*
*/
/*~struct~switchPatternList:
*
* @param identifier
* @text Identifier
* @desc The identifier for skill reaction patterns.
* @type string
*
* @param patterns
* @text Skill Reaction Pattern List
* @desc The list for skill reaction patterns.
* @type struct<switchPattern>[]
*
*/
/*~struct~switchPattern:
*
* @param commonEventId
* @text Common Event ID
* @desc The common event ID which affects the event.
* @type common_event
*
* @param selfSwitchCh
* @text Self Switch Character
* @desc The self switch character which will change.
* @default A
* @type select
* @option A
* @option B
* @option C
* @option D
*
* @param selfSwitchValue
* @text Self Switch Value
* @desc The changed Value of the self switch.
* @type boolean
* @default true
*
* @param selfSwitchCondition
* @text Self Switch Condition
* @desc The self switch character which needs to be on for enabling this reaction.
* @default none
* @type select
* @option none
* @value null
* @option A
* @option B
* @option C
* @option D
*
*/
/*:ja
* @target MZ
* @plugindesc
* @author
*
* @help
*
* @param skillReactionPatterns
* @text スキル反応パターン
* @desc スキルに対する反応パターンを、反応の種類だけ定義します。
* @type struct<switchPatternList>[]
*
* @command toggleSwitchesByFacingSkillTargets
* @text 直前イベントスイッチオン
* @desc プレイヤーの目の前のイベントのメタタグに設定されているスイッチをオンにします。
*
* @command requestAnimationAtFacingSkillTargets
* @text 直前イベントアニメーション表示
* @desc プレイヤーの目の前のイベントに指定したIDのアニメーションを表示します。
*
* @arg animationId
* @text 表示アニメーション番号
* @desc 表示するアニメーションの番号です。
* @type animation
*
*
*/
/*~struct~switchPatternList:ja
*
* @param identifier
* @text 識別子
* @desc スキル反応パターンの識別子です。
* @type string
*
* @param patterns
* @text スキル反応パターンリスト
* @desc スキル反応パターンのリストです。
* @type struct<switchPattern>[]
*
*/
/*~struct~switchPattern:ja
*
* @param commonEventId
* @text コモンイベントID
* @desc イベントに作用するコモンイベントのIDです。
* @type common_event
*
* @param selfSwitchCh
* @text セルフスイッチ記号
* @desc 変化するセルフスイッチの記号です。
* @default A
* @type select
* @option A
* @option B
* @option C
* @option D
*
* @param selfSwitchValue
* @text 変化後スイッチ
* @desc 反応後に変化するセルフスイッチの値です。
* @type boolean
* @default true
*
* @param selfSwitchCondition
* @text セルフスイッチ条件
* @desc この反応を有効にするためにオンになっている必要があるセルフスイッチの記号です。
* @default なし
* @type select
* @option なし
* @value null
* @option A
* @option B
* @option C
* @option D
*
*/
(() => {
'use strict';
const PLUGIN_NAME = "FieldAction";
PluginManager.registerCommand(PLUGIN_NAME, "toggleSwitchesByFacingSkillTargets", args => {
$gamePlayer.toggleSwitchesByFacingSkillTargets();
});
PluginManager.registerCommand(PLUGIN_NAME, "requestAnimationAtFacingSkillTargets", args => {
const targets = $gamePlayer.facingSkillTargets();
const animationId = Number(args.animationId);
$gameTemp.requestAnimation(targets, animationId);
});
Game_Player.prototype.facingSkillTargets = function() {
const direction = this.direction();
const x1 = this.x;
const y1 = this.y;
const x2 = $gameMap.roundXWithDirection(x1, direction);
const y2 = $gameMap.roundYWithDirection(y1, direction);
const events = $gameMap.eventsXy(x2, y2);
return events;
};
Game_Player.prototype.isFacingSkillTargets = function() {
const events = this.facingSkillTargets();
return events.length > 0;
};
Game_Player.prototype.toggleSwitchesByFacingSkillTargets = function() {
const events = this.facingSkillTargets();
for (const event of events) {
const switchId = event.skillSwitchId();
$gameSwitches.setValue(switchId, true);
}
};
Game_Event.prototype.skillSwitchId = function() {
return this.event().meta.skillSwitchId;
};
})();
この記事が気に入ったらサポートをしてみませんか?