brainwashing-school/js/plugins/NRP_EventCollisionEX.js
2025-05-30 08:36:40 -05:00

912 lines
30 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//=============================================================================
// NRP_EventCollisionEX.js
//=============================================================================
/*:
* @target MV MZ
* @plugindesc v1.04 Extends the collision detection for events.
* @author Takeshi Sunagawa (http://newrpg.seesaa.net/)
* @url http://newrpg.seesaa.net/article/481944599.html
*
* @help Extends the collision detection for events.
*
* This is useful for large objects and huge monsters.
* It also extends the range of event execution by triggers.
*
* Note that only squares can be extended.
* It does not support flexible changes such as circles and crosses.
*
* ■Usage
* There are three ways to extend the event collision detection.
* Please use the method that is easiest for you.
*
* ◆SettingList
* You can register the target file and collision detection
* in the plugin parameter SettingList.
* This is convenient because you do not need to register each event.
*
* ◆Note Field
* Please enter the following in the Note field of the event.
*
* <CollisionEX:?,?,?,?>
*
* Please set a numerical value in the ?.
* The collision detection will be extended
* in the following order: down, left, right, up.
*
* ◆Annotations
* You can also enter the same information
* in the annotation at the top of the event page.
* You can switch the status of this annotation for each current page.
*
* In addition, the order of priority is "Annotations > Notes > SettingList".
* Please note that if the event itself has a collision detection specification,
* the contents registered in the SettingList will be ignored.
*
* ■Notice
* This plugin has a relatively large impact.
* In order to avoid conflicts,
* it is recommended to place it as high up as possible.
*
* If normal movement of large events is not necessary,
* turning off "ConsiderEventMove" may stabilize the situation.
*
* Also, the behavior near the boundary of a looping map is
* I gave up on implementing it
* because it was too complicated. Sorry.......
* So, there is no collision detection for the part of the loop
* that extends beyond the loop.
*
* [Terms]
* There are no restrictions.
* Modification, redistribution freedom, commercial availability,
* and rights indication are also optional.
* The author is not responsible,
* but will deal with defects to the extent possible.
*
* @param ConsiderEventMove
* @type boolean
* @default true
* @desc The collision detection is also calculated when a large event moves. Turning it off will reduce the processing.
*
* @param SettingList
* @type struct<Setting>[]
* @default []
* @desc List of settings related to collision detection.
*/
/*~struct~Setting:
* @param File
* @type file
* @dir img/characters
* @desc A file of character images to extend the collision detection.
*
* @param Index
* @type number
* @desc The index value of the image to use (0~7).
* If blank, all will be used.
*
* @param CollisionDown
* @type number
* @desc This is an additional value for downward collision detection.
*
* @param CollisionLeft
* @type number
* @desc This is an additional value for leftward collision detection.
*
* @param CollisionRight
* @type number
* @desc This is an additional value for rightward collision detection.
*
* @param CollisionUp
* @type number
* @desc This is an additional value for upward collision detection.
*/
/*:ja
* @target MV MZ
* @plugindesc v1.04 イベントの当たり判定を拡張する。
* @author 砂川赳http://newrpg.seesaa.net/
* @url http://newrpg.seesaa.net/article/481944599.html
*
* @help イベントの当たり判定を拡張します。
*
* 大型のオブジェクトや巨大モンスターなどに便利です。
* トリガーによるイベントの実行範囲も拡張されます。
*
* なお、拡張できる範囲は四角だけです。
* 円や十字などの柔軟な変更には対応していません。
*
* ■使用方法
* 三通りの方法によって、イベントの当たり判定を拡張できます。
* 使いやすい方法をご利用ください。
*
* ◆設定リスト
* プラグインパラメータの設定リストに、
* 対象のファイルと当たり判定を登録できます。
* いちいちイベント毎に登録する必要がないので便利です。
*
* ◆メモ欄
* イベントのメモ欄に以下を記入してください。
*
* <CollisionEX:?,?,?,?>
*
* ?には数値を設定してください。
* 下、左、右、上の順番に当たり判定が拡張されます。
*
* ◆注釈
* また、イベントページ先頭の注釈に同様の記入しても有効となります。
* こちらは現在のページ毎に状態を切り替えられます。
*
* なお、優先度は『注釈>メモ欄>設定リスト』の順番になっています。
* イベント自体に指定がある場合、設定リストに登録した内容は
* 無視されますのでご注意ください。
*
* ■注意点
* 比較的、影響の大きいプラグインです。
* 競合を避けるため、なるべく上方への配置を推奨します。
*
* 大型イベントの通常移動が不要な場合は、
* 『大型イベントの移動を考慮』をオフにしておくと安定するかもしれません。
*
* また、ループするマップの境界付近での挙動については、
* ややこしくて実装を断念しました。すまぬ……。
* なので、ループの向こうへはみ出している部分には、
* 当たり判定がありません。
*
* ■利用規約
* 特に制約はありません。
* 改変、再配布自由、商用可、権利表示も任意です。
* 作者は責任を負いませんが、不具合については可能な範囲で対応します。
*
* @param ConsiderEventMove
* @text 大型イベントの移動を考慮
* @type boolean
* @default true
* @desc 大型イベントが移動した際も当たり判定を計算します。
* オフにすると処理が軽減されます。
*
* @param SettingList
* @text 設定リスト
* @type struct<Setting>[]
* @default []
* @desc 当たり判定の設定の一覧です。
*/
/*~struct~Setting:ja
* @param File
* @text 画像ファイル
* @type file
* @dir img/characters
* @desc 当たり判定を拡張するキャラクター画像のファイルです。
*
* @param Index
* @text 画像インデックス
* @type number
* @desc 使用する画像のインデックス値0~7です。
* 空欄なら全てを対象とします。
*
* @param CollisionDown
* @text 当たり判定(下)
* @type number
* @desc 下方向への当たり判定の加算値です。
*
* @param CollisionLeft
* @text 当たり判定(左)
* @type number
* @desc 左方向への当たり判定の加算値です。
*
* @param CollisionRight
* @text 当たり判定(右)
* @type number
* @desc 右方向への当たり判定の加算値です。
*
* @param CollisionUp
* @text 当たり判定(上)
* @type number
* @desc 上方向への当たり判定の加算値です。
*/
(function() {
"use strict";
/**
* ●構造体二重配列をJSで扱えるように変換
*/
function parseStruct2(arg) {
var ret = [];
JSON.parse(arg).forEach(function(str) {
ret.push(JSON.parse(str));
});
return ret;
}
function toBoolean(str, def) {
if (str === true || str === "true") {
return true;
} else if (str === false || str === "false") {
return false;
}
return def;
}
function toNumber(str, def) {
if (str == undefined || str == "") {
return def;
}
return isNaN(str) ? def : +(str || def);
}
function setDefault(str, def) {
if (str == undefined || str == "") {
return def;
}
return str;
}
const PLUGIN_NAME = "NRP_EventCollisionEX";
const parameters = PluginManager.parameters(PLUGIN_NAME);
const pConsiderMove = toBoolean(parameters["ConsiderEventMove"], true);
const pSettingList = parseStruct2(parameters["SettingList"]);
/**
* ●効率化のため事前変換
*/
for (const setting of pSettingList) {
setting.file = setting.File;
setting.index = toNumber(setting.Index);
setting.collisionDown = toNumber(setting.CollisionDown, 0);
setting.collisionLeft = toNumber(setting.CollisionLeft, 0);
setting.collisionRight = toNumber(setting.CollisionRight, 0);
setting.collisionUp = toNumber(setting.CollisionUp, 0);
}
//--------------------------------------------------------------
// 基本処理
//--------------------------------------------------------------
/**
* ●変数初期化
*/
const _Game_CharacterBase_initMembers = Game_CharacterBase.prototype.initMembers;
Game_CharacterBase.prototype.initMembers = function() {
_Game_CharacterBase_initMembers.apply(this, arguments);
// 当たり判定初期化
this._collisionDown = 0;
this._collisionLeft = 0;
this._collisionRight = 0;
this._collisionUp = 0;
}
/*
* Game_Event.prototype.setImageが未定義の場合は事前に定義
* ※これをしておかないと以後のGame_CharacterBase側への追記が反映されない。
*/
if (Game_Event.prototype.setImage == Game_CharacterBase.prototype.setImage) {
Game_Event.prototype.setImage = function(
characterName,
characterIndex
) {
Game_CharacterBase.prototype.setImage.apply(this, arguments);
}
}
/**
* 【独自】画像を設定する。
* ※Game_CharacterBaseの関数をオーバーライド
*/
const _Game_Event_setImage = Game_Event.prototype.setImage;
Game_Event.prototype.setImage = function(
characterName,
characterIndex
) {
_Game_Event_setImage.apply(this, arguments);
// 当たり判定初期化
this._collisionDown = 0;
this._collisionLeft = 0;
this._collisionRight = 0;
this._collisionUp = 0;
// ページを取得できない場合は処理終了
if (!this.page()) {
return;
}
//-------------------------------------------
// 当たり判定をイベントに設定する。
// 優先度は『注釈>メモ欄>画像ファイル名』の順番
//-------------------------------------------
let collisionEX = undefined;
// 注釈欄から読込を行う。
const list = this.list();
// 処理が存在する場合
if (list && list.length > 0) {
for (const line of list) {
// 108:注釈開始, 408:注釈続き
if (line.code == 108 || line.code == 408) {
// 注釈から<CollisionEX:*>を取得
collisionEX = getMetaValue(line.parameters[0]);
// 取得できればイベントに設定
if (collisionEX != undefined) {
setCollision(this, collisionEX);
return;
}
// それ以外はループ終了
} else {
break;
}
}
}
// メモ欄に、当たり判定の設定があれば反映
collisionEX = this.event().meta.CollisionEX;
if (collisionEX != undefined) {
setCollision(this, collisionEX);
return;
}
// 設定されている画像名から判定
for (const setting of pSettingList) {
// 一致する画像名が存在した場合
if (setting.file == this.characterName()) {
// インデックスの指定がない場合は常に有効
if (setting.index == undefined) {
setCollisionFromSetting(this, setting);
return;
// インデックスの指定がある場合
} else if (setting.index == this.characterIndex()) {
setCollisionFromSetting(this, setting);
return;
}
}
}
};
/**
* ●<CollisionEX>の指定があれば取得
*/
function getMetaValue(note) {
// 注釈から<CollisionEX:*>を取得
const strArr = note.match("<CollisionEX:(.+)>");
// 取得できれば返す
if (strArr) {
return strArr[1];
}
}
/**
* ●各方向の当たり判定をイベントに設定する。
*/
function setCollision(event, collisionEX) {
// 下、左、右、上の順番
const collisionArray = collisionEX.split(",");
event._collisionDown = toNumber(collisionArray[0]);
if (collisionArray.length >= 2) {
event._collisionLeft = toNumber(collisionArray[1]);
}
if (collisionArray.length >= 3) {
event._collisionRight = toNumber(collisionArray[2]);
}
if (collisionArray.length >= 4) {
event._collisionUp = toNumber(collisionArray[3]);
}
}
/**
* ●各方向の当たり判定をイベントに設定する。
* こちらは設定リストから読み込む場合です。
*/
function setCollisionFromSetting(event, setting) {
// 下、左、右、上の順番
event._collisionDown = setting.collisionDown;
event._collisionLeft = setting.collisionLeft;
event._collisionRight = setting.collisionRight;
event._collisionUp = setting.collisionUp;
}
/**
* 【独自】衝突計算用の中央X座標
*/
Game_CharacterBase.prototype.collisionCenterX = function(x) {
return x + (this._collisionRight - this._collisionLeft) / 2;
};
/**
* 【独自】衝突計算用の中央Y座標
*/
Game_CharacterBase.prototype.collisionCenterY = function(y) {
return y + (this._collisionDown - this._collisionUp) / 2;
};
/**
* 【独自】衝突計算用の横幅
*/
Game_CharacterBase.prototype.collisionWidth = function() {
return 1 + this._collisionRight + this._collisionLeft;
};
/**
* 【独自】衝突計算用の縦幅
*/
Game_CharacterBase.prototype.collisionHeight = function() {
return 1 + this._collisionUp + this._collisionDown;
};
/**
* 【独自】拡張を行っているかどうか?
*/
Game_CharacterBase.prototype.isCollisionEX = function() {
return this._collisionUp || this._collisionDown || this._collisionLeft || this._collisionRight;
};
//--------------------------------------------------------------
// プレイヤーからイベントへの当たり判定
// ※プレイヤーは拡張なしとして計算
//--------------------------------------------------------------
/**
* 【上書】指定の座標に当たり判定のあるイベントを求める。
*/
Game_Map.prototype.eventsXyNt = function(x, y) {
return this.events().filter(event => event.posNtCollisionEX(x, y));
};
/**
* 【独自】該当の座標にすり抜けではないイベントが存在するかどうか?
* ※当たり判定の拡張を考慮
*/
Game_CharacterBase.prototype.posNtCollisionEX = function(x, y) {
return !this.isThrough() && this.posCollisionEX(x, y);
};
/**
* 【独自】該当の座標に一致するかどうか?
* ※当たり判定の拡張を考慮
*/
Game_CharacterBase.prototype.posCollisionEX = function(x, y) {
return this._x + this._collisionRight >= x && this.x - this._collisionLeft <= x
&& this._y + this._collisionDown >= y && this._y - this._collisionUp <= y;
};
//--------------------------------------------------------------
// 飛行船の着陸判定
//--------------------------------------------------------------
/**
* ●乗降判定
*/
const _Game_Vehicle_isLandOk = Game_Vehicle.prototype.isLandOk;
Game_Vehicle.prototype.isLandOk = function(x, y, d) {
// 飛行船の場合
if (this.isAirship()) {
// イベントが存在する場合は着陸禁止
if ($gameMap.eventsXyCollisionEX(x, y).length > 0) {
return false;
}
}
return _Game_Vehicle_isLandOk.apply(this, arguments);
};
//--------------------------------------------------------------
// イベントからイベントへの当たり判定
//--------------------------------------------------------------
/**
* 【上書】指定の座標に当たり判定のあるイベントが存在するか?
*/
Game_Event.prototype.isCollidedWithEvents = function(x, y) {
const events = this.eventsXyNt(x, y);
return events.length > 0;
};
/**
* 【独自】指定の座標に当たり判定のあるイベントを求める。
*/
Game_Event.prototype.eventsXyNt = function(x, y) {
// Game_Mapと異なり、自分自身は判定から除外する。
// さもないと、自分の当たり判定で動けなくなる。
return $gameMap.events().filter(event => event != this && event.posNtCollisionEXEvent(x, y, this));
};
/**
* 【独自】該当の座標にすり抜けではないイベントが存在するかどうか?
* ※当たり判定の拡張を考慮
*/
Game_Event.prototype.posNtCollisionEXEvent = function(x, y, event) {
return !this.isThrough() && this.posCollisionEXEvent(x, y, event);
};
/**
* 【独自】該当の座標に一致するかどうか?
* ※当たり判定の拡張を考慮
*/
Game_CharacterBase.prototype.posCollisionEXEvent = function(x, y, event) {
// 大型イベントの移動を考慮しない場合
if (!pConsiderMove) {
return this.posCollisionEX(x, y);
}
//-----------------------------------
// 引数のイベントとの当たり判定を計算
//-----------------------------------
// 中央座標を求める
const aCenterX = this.collisionCenterX(this._x);
const aCenterY = this.collisionCenterY(this._y);
const bCenterX = event.collisionCenterX(x);
const bCenterY = event.collisionCenterY(y);
// 横幅・縦幅を計算
const aWidth = this.collisionWidth();
const aHeight = this.collisionHeight();
const bWidth = event.collisionWidth();
const bHeight = event.collisionHeight();
// 中心同士の距離を計算
const distanceCenterX = Math.abs(aCenterX - bCenterX);
const distanceCenterY = Math.abs(aCenterY - bCenterY);
// 横幅・縦幅を考慮した距離
const distanceX = distanceCenterX - (aWidth + bWidth) / 2;
const distanceY = distanceCenterY - (aHeight + bHeight) / 2;
// 両方がマイナスなら重なっている
if (distanceX < 0 && distanceY < 0) {
return true;
}
return false;
};
//--------------------------------------------------------------
// イベントからプレイヤー&フォロワーへの当たり判定
//--------------------------------------------------------------
/**
* イベントが移動しない想定なら不要
*/
if (pConsiderMove) {
/**
* ●プレイヤー&フォロワーとの衝突判定
*/
Game_Event.prototype.isCollidedWithPlayerCharacters = function(x, y) {
// イベントが通常キャラと同じ以外なら処理しない。
if (!this.isNormalPriority()) {
return false;
}
// プレイヤーがすり抜けなら処理しない。
if ($gamePlayer.isThrough()) {
return false;
}
// プレイヤーとフォロワーに衝突するかどうか?
return $gamePlayer.posCollisionEXEvent(x, y, this)
|| $gamePlayer._followers.isSomeoneCollidedExEvent(x, y, this);
};
/**
* 【独自】イベントとフォロワーとの衝突判定
*/
Game_Followers.prototype.isSomeoneCollidedExEvent = function(x, y, event) {
return this.visibleFollowers().some(follower => follower.posCollisionEXEvent(x, y, event));
};
}
//--------------------------------------------------------------
// イベントからマップへの当たり判定
//--------------------------------------------------------------
/**
* イベントが移動しない想定なら不要
*/
if (pConsiderMove) {
/*
* Game_Event.prototype.canPassが未定義の場合は事前に定義
* ※これをしておかないと以後のGame_CharacterBase側への追記が反映されない。
*/
if (Game_Event.prototype.canPass == Game_CharacterBase.prototype.canPass) {
Game_Event.prototype.canPass = function(x, y, d) {
return Game_CharacterBase.prototype.canPass.apply(this, arguments);
}
}
/**
* 【独自】イベントからマップへの当たり判定
* ※Game_CharacterBaseの関数をオーバーライド
*/
const _Game_Event_canPass = Game_Event.prototype.canPass;
Game_Event.prototype.canPass = function(x, y, d) {
const x2 = $gameMap.roundXWithDirection(x, d);
const y2 = $gameMap.roundYWithDirection(y, d);
if (!this.isMapValid(x2, y2)) {
return false;
}
return _Game_Event_canPass.apply(this, arguments);
};
/**
* 【独自】イベントの当たり判定を考慮して、マップの有効無効を確認
*/
Game_Event.prototype.isMapValid = function(x, y) {
let horizontalOk = false;
let verticalOk = false;
// 横ループのマップなら、横チェックは行わない。
if ($gameMap.isLoopHorizontal()) {
horizontalOk = true;
// 横範囲に収まっているか?
} else if (x - this._collisionLeft >= 0 && x + this._collisionRight < $gameMap.width()) {
horizontalOk = true;
}
// 縦ループのマップなら、縦チェックは行わない。
if ($gameMap.isLoopVertical()) {
verticalOk = true;
// 縦範囲に収まっているか?
} else if (y - this._collisionUp >= 0 && y + this._collisionDown < $gameMap.height()) {
verticalOk = true;
}
return horizontalOk && verticalOk;
};
/**
* ●イベントからマップへの当たり判定
* ※イベント限定の機能なのでGame_Eventにしたかったけど、
*  『OverpassTile.js』辺りと併用できなくなるのでここに実装。
*/
const _Game_CharacterBase_isMapPassable = Game_CharacterBase.prototype.isMapPassable;
Game_CharacterBase.prototype.isMapPassable = function(x, y, d) {
// イベント以外は元の処理を使用
if (!this.event) {
return _Game_CharacterBase_isMapPassable.apply(this, arguments);
}
// 先端座標を取得
const tipX = this.collisionTipX(x, d);
const tipY = this.collisionTipY(y, d);
// 先端の移動先座標を取得
const tipX2 = $gameMap.roundXWithDirection(tipX, d);
const tipY2 = $gameMap.roundYWithDirection(tipY, d);
const d2 = this.reverseDir(d);
// RegionBase.jsに対応
if ($gameMap.setPassableSubject) {
$gameMap.setPassableSubject(this);
}
return this.isPassableWide(tipX, tipY, d) && this.isPassableWide(tipX2, tipY2, d2);
};
/**
* 【独自】イベントがタイルを通過できるか?
* ※イベントの進路に対する水平サイズを考慮
*/
Game_CharacterBase.prototype.isPassableWide = function(x, y, d) {
// 上下
if (d === 2 || d === 8) {
const startX = x - this._collisionLeft;
const endX = x + this._collisionRight;
for (let tmpX = startX; tmpX <= endX; tmpX++) {
// RegionBase.jsに対応
if ($gameMap.isCollidedByRegion) {
if ($gameMap.isCollidedByRegion(tmpX, y, d)) {
return false;
} else if ($gameMap.isThroughByRegion(tmpX, y)) {
continue;
}
}
// 通行禁止に該当があれば処理終了
if (!$gameMap.checkPassage(tmpX, y, (1 << (d / 2 - 1)) & 0x0f)) {
return false;
}
}
// 通行可能
return true;
// 左右
} else if (d === 4 | d === 6) {
const startY = y - this._collisionUp;
const endY = y + this._collisionDown;
for (let tmpY = startY; tmpY <= endY; tmpY++) {
// RegionBase.jsに対応
if ($gameMap.isCollidedByRegion) {
if ($gameMap.isCollidedByRegion(x, tmpY, d)) {
return false;
} else if ($gameMap.isThroughByRegion(x, tmpY)) {
continue;
}
}
// 通行禁止に該当があれば処理終了
if (!$gameMap.checkPassage(x, tmpY, (1 << (d / 2 - 1)) & 0x0f)) {
return false;
}
}
// 通行可能
return true;
}
// とりあえずそのまま
return $gameMap.checkPassage(x, y, (1 << (d / 2 - 1)) & 0x0f);
};
}
/**
* 【独自】衝突時の先端となるX座標
*/
Game_CharacterBase.prototype.collisionTipX = function(x, d) {
// 左
if (d === 4) {
x -= this._collisionLeft;
// 右
} else if (d === 6) {
x += this._collisionRight;
}
return x;
};
/**
* 【独自】衝突時の先端となるY座標
*/
Game_CharacterBase.prototype.collisionTipY = function(y, d) {
// 下
if (d === 2) {
y += this._collisionDown;
// 上
} else if (d === 8) {
y -= this._collisionUp;
}
return y;
};
//--------------------------------------------------------------
// イベント起動
//--------------------------------------------------------------
/**
* 【上書】マップイベントの起動
*/
Game_Player.prototype.startMapEvent = function(x, y, triggers, normal) {
if (!$gameMap.isEventRunning()) {
for (const event of $gameMap.eventsXyCollisionEX(x, y)) {
if (
event.isTriggerIn(triggers) &&
event.isNormalPriority() === normal
) {
event.start();
}
}
}
};
/**
* 【独自】指定の座標に存在するイベントを求める。
*/
Game_Map.prototype.eventsXyCollisionEX = function(x, y) {
return this.events().filter(event => event.posCollisionEX(x, y));
};
/**
* イベントから接触の場合
* ※イベントが移動しない想定なら不要
*/
if (pConsiderMove) {
/*
* Game_Event.prototype.checkEventTriggerTouchFrontが未定義の場合は事前に定義
* ※これをしておかないと以後のGame_CharacterBase側への追記が反映されない。
*/
if (Game_Event.prototype.checkEventTriggerTouchFront == Game_CharacterBase.prototype.checkEventTriggerTouchFront) {
Game_Event.prototype.checkEventTriggerTouchFront = function(d) {
Game_CharacterBase.prototype.checkEventTriggerTouchFront.apply(this, arguments);
}
}
// 一時的に保持する向き
let mTmpD = 0;
/**
* 【独自】イベントから接触による起動判定1
* ※Game_CharacterBaseの関数をオーバーライド
*/
const _Game_Event_checkEventTriggerTouchFront = Game_Event.prototype.checkEventTriggerTouchFront;
Game_Event.prototype.checkEventTriggerTouchFront = function(d) {
mTmpD = d;
_Game_Event_checkEventTriggerTouchFront.apply(this, arguments);
};
/**
* ●イベントから接触による起動判定1
*/
const _Game_Event_checkEventTriggerTouch = Game_Event.prototype.checkEventTriggerTouch;
Game_Event.prototype.checkEventTriggerTouch = function(x, y) {
// 拡張対象外の場合は元の処理
if (!this.isCollisionEX()) {
_Game_Event_checkEventTriggerTouch.apply(this, arguments);
return;
}
// 本来引数に存在しないdを取得
const d = mTmpD;
// 先端座標を取得
const tipX = this.collisionTipX(this._x, d);
const tipY = this.collisionTipY(this._y, d);
// 先端の向いている座標を取得
const x2 = $gameMap.roundXWithDirection(tipX, d);
const y2 = $gameMap.roundYWithDirection(tipY, d);
// イベント確認&起動
this.checkEventTriggerTouchCollisionEX(x2, y2, d);
};
/**
* 【独自】イベントから接触による起動判定2
*/
Game_Event.prototype.checkEventTriggerTouchCollisionEX = function(x, y, d) {
if (!$gameMap.isEventRunning()) {
if (this._trigger === 2 && $gamePlayer.posTriggerTouchCollisionEX(x, y, d, this)) {
if (!this.isJumping() && this.isNormalPriority()) {
this.start();
}
}
}
};
/**
* 【独自】イベントから接触の対象座標に一致するかどうか?
* ※当たり判定の拡張を考慮
*/
Game_Player.prototype.posTriggerTouchCollisionEX = function(x, y, d, event) {
// 進路が上下
if (d === 2 || d === 8) {
if (this.y == y) {
const startX = x - event._collisionLeft;
const endX = x + event._collisionRight;
// 該当範囲のX座標を確認
for (let tmpX = startX; tmpX <= endX; tmpX++) {
// 該当があればtrue
if (this.x == tmpX) {
return true;
}
}
}
// 進路が左右
} else if (d === 4 | d === 6) {
if (this.x == x) {
const startY = y - this._collisionUp;
const endY = y + this._collisionDown;
// 該当範囲のY座標を確認
for (let tmpY = startY; tmpY <= endY; tmpY++) {
// 該当があればtrue
if (this.y == tmpY) {
return true;
}
}
}
}
// それ以外は通常の座標一致
return this.pos(x, y);
};
}
})();