参考:
プレイ時にある操作でフリーズすることについて(ツクマテ)
https://tm.lucky-duet.com/viewtopic.php?f=23&t=5284
謝辞:
しぐれん様、ツミオ様、剣崎宗二様、あかみどり様、にいやん様
ツクマテ様
■事象
アイテム画面で操作不能になる
再現動画
https://www.youtube.com/watch?v=ni2SWrJcIZs
■再現方法
・2018/1/7現在、ツクールMVの全コアスクリプト(〜V1.5.1)で再現可能
・メニューからアイテム選択画面へ高速で切り替えると発生
・コントローラで決定ボタン、キーボードでキャンセルボタンを繰り返すと再現させやすい
(私も同じ操作で11回目、20回目のボタン操作で再現することを確認)
・操作不能になるのはアイテム画面を描画しているタイミング
■原因
メニュー画面とアイテム画面の連続した画面遷移の際に、内部処理で不整合が生じていることが原因のようです。
・正常であればWindow_ItemCategoryでcansel判定(ダブルタップorキャンセルボタン押下)が発生するとSceneManager.popに画面遷移する
//1238行目
Scene_Item.prototype.createCategoryWindow = function() {
this._categoryWindow = new Window_ItemCategory();
this._categoryWindow.setHelpWindow(this._helpWindow);
this._categoryWindow.y = this._helpWindow.height;
this._categoryWindow.setHandler('ok', this.onCategoryOk.bind(this));
this._categoryWindow.setHandler('cancel', this.popScene.bind(this));//★cansel判定時にthis.popSceneへハンドルを渡す
this.addWindow(this._categoryWindow);
};
この処理はアイテムのほか、スキル、装備、ステータス、オプションでも行われており、他の画面遷移でも発生する恐れがあります。
トラブル再現時は連続した画面遷移操作によりビジー状態と判定され、this.popSceneへハンドルを渡す操作が破棄されたため操作不能に陥っているとのことです。(ツクマテ剣崎 宗二氏のコメントを参考に推測)
//rpg_managers.js 1996行目
SceneManager.changeScene = function() {
if (this.isSceneChanging() && !this.isCurrentSceneBusy()) {
if (this._scene) {
this._scene.terminate();
this._scene.detachReservation();
this._previousClass = this._scene.constructor;
}
■対処
2018/1/7現在、安全性が高いと推測される対処は、次の手順で処理を追加することだと思います。
私の環境では200回再現動作(アイテムとメニューの往復)を行いましたが回避しております。
別の問題を引き起こす可能性もありますので、様子見も含めてご判断ください。
特に作品公開が直前に控えている場合、安易に手を加えることはオススメできません。
1.以下の場所から「rpg_scenes.js」をテキストエディタで開く
場所:
プロジェクト名\js\rpg_scenes.js
※jsファイルは右クリック→プログラムから開く→メモ帳(または「既定のプログラムの選択」からテキストエディタを選ぶ)ことで開くことができます
2.Ctrl+Fキーで「Scene_Item.prototype.create」を検索し、this.addWindow(this._categoryWindow);の次の行にthis._categoryWindow.activate();を追記する
Scene_Item.prototype.createCategoryWindow = function() {
this._categoryWindow = new Window_ItemCategory();
this._categoryWindow.setHelpWindow(this._helpWindow);
this._categoryWindow.y = this._helpWindow.height;
this._categoryWindow.setHandler('ok', this.onCategoryOk.bind(this));
this._categoryWindow.setHandler('cancel', this.popScene.bind(this));
this.addWindow(this._categoryWindow);
this._categoryWindow.activate();//★この行を追記
};
MVバージョン1.5.1(rpg_scenes.jsのバージョンは1.5.0)の場合は1245行目に追記
※画像クリックで拡大
■補足1)画面遷移の内部処理について
次の記事に画面の遷移の内部処理が記載されていました。
RPGツクールMVのランタイムコードを読む - Sceneを理解する
http://gan.hatenablog.jp/entry/2016/01/07/225635
【画面遷移の際に行われる処理】
@initialized:初期化完了
Aready:新画面のリソースの読み込みが完了
Bstart_transition:今の画面から新画面の切り替え処理を開始
Crunning:切り替え処理を実行中
Dstop_transition:今の画面から新画面に切り替え中
Estopped 新画面に置き換わり、前の画面情報を破棄する準備が整う
Fterminated:前の画面情報の破棄が完了
rpg_managers.js 1996行目で実行されているSceneManager.changeSceneの処理はthis.isSceneChanging()がfalseとみなされた場合はthis.isCurrentSceneBusy()が返されるという意味。
連続した画面遷移操作でthis.isSceneChanging()がfalseと判定されたためにthis.isCurrentSceneBusy()が実行されEの状態で停止したというのが今回の事象なのかなと思います。
SceneManager.changeScene = function() {
if (this.isSceneChanging() && !this.isCurrentSceneBusy()) { //★ここでthis.isCurrentSceneBusy()の方に処理が返されたために不整合が生じた?
if (this._scene) {
this._scene.terminate();
this._scene.detachReservation();
this._previousClass = this._scene.constructor;
}
■補足2)アイテム以外の対処
構造上はアイテム以外でも同じ事象が発生するため、次の箇所でも同対処が有効かもしれません。
(ただしアイテム以外は画面遷移の変化が少ないためなのか、私の環境では再現しませんでした)
分かりましたら追記します。
Scene_Item.prototype.createCategoryWindow
1244行目 this.createActorWindow();の下
Scene_Skill.prototype.createSkillTypeWindow
1333行目 this.addWindow(this._skillTypeWindow);の下
Scene_Equip.prototype.createCommandWindow
1443行目 this.addWindow(this._commandWindow);の下
Scene_Status.prototype.create
1554行目 this.addWindow(this._statusWindow);の下
Scene_Options.prototype.createOptionsWindow
1601行目 this.addWindow(this._optionsWindow);の下
Scene_File.prototype.createListWindow
1654行目 this.addWindow(this._listWindow);の下
【このカテゴリーの最新記事】
-
no image
-
no image