【解決済】選択中の項目をスクリプトで取得する方法について

とりもち
記事: 9
登録日時: 2021年5月09日(日) 16:23

【解決済】選択中の項目をスクリプトで取得する方法について

投稿記事by とりもち » 2021年5月09日(日) 16:39

はじめまして。いつもみなさんのトピックを参考にさせて頂いております。
自分で調べても、どうしてもわからなかった為、こちらで質問させてください。

各種ウィンドウにおいて、(まだ決定していない)現在選択中の項目があるかと思います。
(デフォルトのスキンでいうと、白く点滅している状態)

その選択中の項目を、スクリプトあるいはjsにて取得するにはどうしたらいいのでしょうか。

目的としては、バトルウィンドウ(ActorCommandSelection下)において、
スキルを選択中や、アイテムを選択中に、それぞれ特定のピクチャを表示したいというものです。

ピクチャを表示する条件として、選択中の項目を取得し条件分岐を行いたいのですが、
コアスクリプトをみても、それらが"skill"や"item"という状態であるということ以外、
自力で読み解くことができませんでした。

javascriptは、まだ0から構築することができない為、
戦闘中、コモンイベントの並列実行化プラグインを導入した上で、コモンイベントで管理したいと考えています。

先達の皆さまのお力添えを頂けますと、幸いです。
よろしくお願いい致します。
最後に編集したユーザー とりもち on 2021年5月11日(火) 21:09 [ 編集 1 回目 ]

HN:とりもち
ツクール歴:2年生
javascriptは詳しくわからないけど、コアスクリプトを眺めているうちに、
なんとなく意味はわかるになってきた...かな?
日々奮闘中です。
アバター
WTR
記事: 558
登録日時: 2015年12月22日(火) 19:14

Re: 選択中の項目をスクリプトで取得する方法について

投稿記事by WTR » 2021年5月09日(日) 18:37

戦闘中のスキル選択ウィンドウ、アイテム選択ウィンドウはそれぞれ

コード: 全て選択

SceneManager._scene._skillWindow
SceneManager._scene._itemWindow


その選択中の項目は

コード: 全て選択

SceneManager._scene._skillWindow.item()
SceneManager._scene._itemWindow.item()

で取得できます。
アイテム選択ウィンドウで例えばハイポーションを選択中だと

コード: 全て選択

{id: 8, animationId: 41, consumable: true, damage: {…}, description: "HPを1500ポイント回復する。", …}

こんなのが取得できます。
条件分岐に使うならIDとか名前が欲しいのだと思いますのでさらに…

コード: 全て選択

SceneManager._scene._skillWindow.item().id
SceneManager._scene._itemWindow.item().name

↾だとスキルID、アイテム名が取得できます。
Twitter、はじめました。
https://twitter.com/wtr_in_reverie/
とりもち
記事: 9
登録日時: 2021年5月09日(日) 16:23

Re: 選択中の項目をスクリプトで取得する方法について

投稿記事by とりもち » 2021年5月09日(日) 22:01

WTRさん、お返事ありがとうございます。
教えて頂いたこと、どれも知らないことばかりで大変勉強になります。

選択中の情報が「.item()」という指定の仕方で、取得できるのかな...?と思いましたが、
実は、分岐の条件として取得したいデータが、実際にスキルやアイテムを選択するひとつ前の状態(※画像参照)で、
ここで「必殺技」や「アイテム」が予約状態となっているか?という条件分岐を行いたいのです。

画像

教えて頂いた内容を元に、自分なりに「Scene_Battle.prototype.createActorCommandWindow」に辿り着き、
試行錯誤してみたのですが、設定の仕方が悪いのか、あるいは検討外れなのかうまくいきません。

コード: 全て選択

const test = function() {
if(SceneManager._scene._actorCommandWindow.item() == "skill"){
$gameScreen.showPicture(1,"テスト画像",1,0,0,100,100,255,0);
};
};


お忙しい中大変恐縮ですが、加えてご指南頂けないでしょうか。
よろしくお願いいたします。
HN:とりもち
ツクール歴:2年生
javascriptは詳しくわからないけど、コアスクリプトを眺めているうちに、
なんとなく意味はわかるになってきた...かな?
日々奮闘中です。
アバター
WTR
記事: 558
登録日時: 2015年12月22日(火) 19:14

Re: 選択中の項目をスクリプトで取得する方法について

投稿記事by WTR » 2021年5月10日(月) 10:38

アクターコマンドウィンドウには item() というメソッドはないですね。
"skill" とか "item" とかいう戻り値が期待なら代わりに currentSymbol() というメソッドがありました。

コード: 全て選択

SceneManager._scene._actorCommandWindow.currentSymbol() === "skill"

こんな感じでどうでしょう。
Twitter、はじめました。
https://twitter.com/wtr_in_reverie/
とりもち
記事: 9
登録日時: 2021年5月09日(日) 16:23

Re: 選択中の項目をスクリプトで取得する方法について

投稿記事by とりもち » 2021年5月10日(月) 20:22

WTRさん、何度も教えてくださってありがとうございます。
WTRさんのおかげで、なんとか希望の挙動を行うことができました。

コアスクリプトをみている限り、
「Scene_Battle.prototype」というメソッド(?)はよく散見するのですが、
とても独力では「SceneManager」というものには、辿り着けませんでした。
お力を貸して頂き、本当にありがとうございます。

WTRさんは、こういったメソッドは、普段、どの様にして探していらっしゃるのでしょうか?

実は、表示をすることはできるようになったのですが、「必殺技」を選択後も、次の画面で、
「SceneManager._scene._actorCommandWindow.currentSymbol() 」に
「"skill"」の戻り値が代入され続けているらしく、表示した画像が消えてくれません。

次は、スキルの選択ウィンドウ(_skillWindow)のなにかしらの戻り値、あるいはコマンドウィンドウ(_actorCommandWindow)がhideになっているときの戻り値を取得するべきだと思うのですが、コアスクリプトに記載されているものは挙動ばかりで、どこになんの値が代入されているときに、skillWindowが表示されているのかを知ることができず、また悩んでしまっています。

SceneManager._scene._skillWindow.hide() === ??? (スキルウィンドウが隠れているときの値や)
SceneManager._actorCommandWindow.activate() === ???(コマンドウィンドウがアクティブじゃないときの値)
これらは、コアスクリプトのどこかに記述されているのでしょうか?

重ねて恐縮なのですが、もしコアスクリプトを読み解くコツなどあれば、知りたいです。
HN:とりもち
ツクール歴:2年生
javascriptは詳しくわからないけど、コアスクリプトを眺めているうちに、
なんとなく意味はわかるになってきた...かな?
日々奮闘中です。
chro
記事: 86
登録日時: 2021年2月14日(日) 11:26

Re: 選択中の項目をスクリプトで取得する方法について

投稿記事by chro » 2021年5月11日(火) 01:29

具体的にやりたいことや画面推移イメージを書いたほうがいいと思います。
実現可能かどうか、見当外れかどうかもわからないままになってしまいます。

そもそもウィンドウ系は決定キーやキャンセルキーを起点にして、コマンド内容やスキル/アイテムの範囲、次のアクターや前のアクターなどで分岐しています。
この流れに従ってそれぞれのコアスクリプトで分散されている形になっています。

例えば、共通で制御されているような、コモンイベントや変数、スイッチのような感覚のものはありません。
プラグインで機能追加出来る都合上もあります。

なので根本的にイベントコマンドのスクリプトでこの流れを追って条件分岐させるのには無理が生じてきます。
アクターコマンドとスキルやアイテムのウィンドウも違うので、メソッドも変わってきます。

特定の条件で特定の状態になるという事くらいしかわからないので、新たな問題が生じます。
キャンセル(スキル選択で戻った場合、次のアクターから前のアクターへ戻った場合)というのもありますし、関連するプラグイン導入時にも挙動が変わってしまいます。
勉強しながら試行錯誤するのならいいですが。


一応これだけ、コアスクリプトの関連範囲があります。

・PixiJS(コアスクリプトが利用するグラフィックライブラリ)
https://pixijs.download/dev/docs/PIXI.Container.html

・rmmz_core.js
Window.prototype
・rmmz_managers.js
BattleManager
・rmmz_scenes.js
Scene_Battle.prototype
・rmmz_windows.js
Window_Base.prototype
Window_Scrollable.prototype
Window_Selectable.prototype
Window_Command.prototype (アクターやパーティーコマンドの場合のみ)
Window_Battle***.prototype

コアスクリプトをちゃんと読み解くとなると、例えばこの本の(初心者向けではない)5章レベルが必要になってきます。
thisやprototype、インスタンス、メソッド、クラスなど基礎もこの範囲です。

改訂新版JavaScript本格入門
https://gihyo.jp/book/2016/978-4-7741-8411-1/#toc
chro
記事: 86
登録日時: 2021年2月14日(日) 11:26

Re: 選択中の項目をスクリプトで取得する方法について

投稿記事by chro » 2021年5月11日(火) 04:43

プラグインで、それぞれのウィンドウのカーソル移動や決定時、キャンセル時にスイッチや変数を操作するサンプルです。
可能性のある全パターンを判定出来るようにしているので、推移パターンの参考にしてください。

プラグイン上部のスイッチや変数番号のみ書き換えてご自由にお使いください。
添付ファイル
BattleSelectCommandType.js
(6.39 KiB) ダウンロード数: 64 回
アバター
WTR
記事: 558
登録日時: 2015年12月22日(火) 19:14

Re: 選択中の項目をスクリプトで取得する方法について

投稿記事by WTR » 2021年5月11日(火) 12:11

とりもち さんが書きました:WTRさんは、こういったメソッドは、普段、どの様にして探していらっしゃるのでしょうか?

SceneManager._scene は現在のシーン(このケースだと Scene_Battle)が入っている変数なわけですが
SceneManager.changeScene() で代入されてるというのは、正確には今知りました。
誰かが質問し、誰かが答えてくれていたのを見て知っただけだと思います。たぶん。
コアスクリプトを眺めるより知りたいことを単純なキーワードで検索するほうが早道なことは多いです。
単純化することが難しいことも多いですがそれは慣れるしかない…ですかね。

もっとロジカルに辿る方法としては
とりもち さんが書きました:SceneManager._scene._skillWindow.hide() === ??? (スキルウィンドウが隠れているときの値や)
SceneManager._actorCommandWindow.activate() === ???(コマンドウィンドウがアクティブじゃないときの値)
これらは、コアスクリプトのどこかに記述されているのでしょうか?

hide() や activate() は、ウィンドウの状態を知るためのメソッドではなく状態を変更するメソッドです。
閉じているかどうか知りたいときではなく、閉じろと命令するときに使います。

アクターコマンドウィンドウの定義は rmmz_windows.js にある Window_ActorCommand です。
しかし Window_ActorCommand のところを見ても
Window_ActorCommand.prototype.activate とかいう記述はありません。
書いてないけど使える。

それはなぜかというと…
Window_ActorCommand は Window_Command を元にして作られています。
そして Window_Command は Window_Selectable、さらに Window_Selectable は Window_Scrollable、さらにさらにWindow_Scrollable は Window_Base が元になっています。

元になった親のウィンドウが持っているメソッドは子のウィンドウでも使えます。
activate() とか hide() とか、ごくごく基本的な機能はすべてのウィンドウの親である Window_Base にもう定義されているので
Window_ActorCommand には何も書いてないのです。
で、辿った先の Window_Base の activate() をみると

コード: 全て選択

Window_Base.prototype.activate = function() {
    this.active = true;
};

と書かれていて、activate() っていうのは this.active を true にするというだけの処理なんだな、というのがわかります。
同じ this.active が Window_ActorCommand にもあるはずだから
コレを見ればアクティブかどうか判定できそうだ、となるわけです。
ということで

コード: 全て選択

SceneManager._scene._actorCommandWindow.active === true;

同様に hide() ってなにするんだろ、と辿っていくと
やっぱり Window_Base に辿り着いて this.visible を false にしている。
逆のことをする show() というメソッドも見つかると思うので
show() とか hide() が操作している this.visible っていうのがウィンドウの開閉状態判定に使えそうだな…と辿れるのではないでしょうか。
Twitter、はじめました。
https://twitter.com/wtr_in_reverie/
名無し蛙
記事: 302
登録日時: 2015年11月23日(月) 02:46

Re: 選択中の項目をスクリプトで取得する方法について

投稿記事by 名無し蛙 » 2021年5月11日(火) 18:09

あんまり沢山の人が言うのも何かと思ったけど補足で
とりもち さんが書きました:実は、表示をすることはできるようになったのですが、「必殺技」を選択後も、次の画面で、
「SceneManager._scene._actorCommandWindow.currentSymbol() 」に
「"skill"」の戻り値が代入され続けているらしく、表示した画像が消えてくれません。

Scene_Battle内で使用している方法ならcurrentSymbol()に加えてcurrentExt()を使いスキルタイプIDも判別しています。
extは任意拡張データであり、actorCommandWindowはスキルタイプIDの保存に使用しています。
また、並び順が固定ならindex()を使っても良いです。

コード: 全て選択

const w = SceneManager._scene._actorCommandWindow;
if (w.currentSymbol() === 'skill' && w.currentExt() === 1) // スキルであり、スキルタイプIDが1の場合
if (w.index() === 1) // (0番から数えて)並びが1番の場合

とりもち さんが書きました:重ねて恐縮なのですが、もしコアスクリプトを読み解くコツなどあれば、知りたいです。

VXAceのコアスクリプトを読むのをオススメしておきます。多分体験版から内容は読めます。
RGSS時代はツクラー自身がスクリプト改造する事を想定していて
全てのメソッドに対して一行説明コメントが振って有ったり
ヘルプに自作ウィンドウや自作シーン作成のステップアップチュートリアルがあったのですが
MV以降は露骨に方針変更していて初学者がステップアップする事を想定しているようには見えません。
予め何らかの(年単位で勉強している)下地がある人以外はプラグイン制作のハードルが高いです。
いきなりES5準拠のjsコードからOOP設計を学び取れというのも無茶な話だと思いますよ。
OOPを押さえていればSceneのインスタンスはどこにあるのか、イベントコマンドのスコープはどこかという発想が出てきます。

MZだと一応開発者向けにとんび氏が編纂した非公式リファレンスがありますが参考になりますかね。
とりもち
記事: 9
登録日時: 2021年5月09日(日) 16:23

Re: 選択中の項目をスクリプトで取得する方法について

投稿記事by とりもち » 2021年5月11日(火) 21:08

>>chroさん
お返事ありがとうございます。
頂いたプラグインを読み解いていると、とても勉強になります。

実は、昨日今日でWTRさんが仰っていることが理解したくて、
javascriptの勉強を続けていたのですが、
質問時の知識がだいぶ浅く、うまく意図を伝えていられなかったことを痛感しました。

chroさんが仰る、画像でイメージを伝えるという手段は、
自分のような素人がみなさんに質問をするとき、大事なことよくわかりました。

コアスクリプトの関連範囲も改めて提示されるとその膨大さに、
いかに質問が抽象的だったか……お恥ずかしい限りです。

javascriptはまだまだ勉強中なのですが、
chroさんが書いてくださったコードをきちんと理解できるようになりたいと思います。
(まだ、argumentsなどが完全に理解できていません)

お手を差し伸べて頂き、ありがとうございました。


>>WTRさん
何度も、丁寧でわかりやすい解説ありがとうございます。
WTRさんの説明は、自分のような素人にも大変わかりやすく、読み返しているだけで
コアスクリプトを読む10倍以上の知識が得られるようです。

”hide() や activate() は、ウィンドウの状態を知るためのメソッドではなく状態を変更するメソッドです。
閉じているかどうか知りたいときではなく、閉じろと命令するときに使います。”

これなどは、2時間コアスクリプトと睨めっこしても、まったくわかりませんでした。
具体的な説明も添えて頂いたので、とてもわかりやすかったです。

キーワードを元に、コアスクリプトの繋がりを辿っていくだけで、
何時間も費やしてしまいそうです。

頂いた式は、ずばり自分が実装したかった項目とも合致し、
やりたいことを完全に実行することができました。

わかりづらい文章にも関わらず、たくさんの知恵をご教授頂き、
感謝に尽きません。ありがとうございました。


>>名無し蛙さん
お返事ありがとうございます。

currentExt()という着想を教えて頂き、プログラムというのは、
ゴールする手段がいくつもあるのだと知ることができました。

新しい知識はどれだけあっても嬉しいので、
currentExt()、index()どちらも興味深いです。

紹介頂いたとんび氏のMZリファレンスも、さっそくお気に入りに登録しました。
以前のバージョンは、javascriptではなくRGSS(Ruby)という言語だったのは、
なんとなくしか知らなかったのですが、開発思想が違うのは面白そうです。

自分なんかは、VXから始められたほうがよかったのかな...?
なんとか頑張っていきたいと思います。


皆さまのおかげで、目標に辿り着くことができました。
解決済とさせて頂きます。本当にありがとうございました。
HN:とりもち
ツクール歴:2年生
javascriptは詳しくわからないけど、コアスクリプトを眺めているうちに、
なんとなく意味はわかるになってきた...かな?
日々奮闘中です。

“MZ:質問” へ戻る