じ☆ve冰风 发表于 2026-1-21 16:24:43

自改事件点击触发增强版,添加触发格位

//=============================================================================
// Yanfly Engine Plugins - Event Click Trigger
// YEP_EventClickTrigger.js
//=============================================================================

var Imported = Imported || {};
Imported.YEP_EventClickTrigger = true;

var Yanfly = Yanfly || {};
Yanfly.EvClTr = Yanfly.EvClTr || {};
Yanfly.EvClTr.version = 1.10;

//=============================================================================
/*:
* @plugindesc v1.10 事件点击触发 - 增强版
* @author Yanfly Engine Plugins
* @modified by Your Name
*
* @help
* ============================================================================
* 导言
*============================================================================
*
* 有没有想过可以点击一个事件并立即触发它
* 而不必让你的玩家角色一直走到它
* 触发前先检查一下?有了这个插件,你可以。通过设置
* 特定事件的某些注释标签和/或评论标签,玩家现在可以
* 只需在远处点击即可触发事件。
*
*============================================================================
* 新功能:触发格位
*============================================================================
*
* 现在可以设置事件的触发格位,让事件可以在特定的格子位置被触发
* 而不需要在事件所在的精确格位点击。
*
* 用法:
* <Click Trigger>
* <trigger area: x,y,width,height>
*
* 例如:
* <trigger area: 0,0,3,2> - 从事件位置开始,向右3格,向下2格的区域
* <trigger area: -1,-1,3,3> - 以事件为中心的3x3区域
*
* 如果不指定,默认只在事件所在格位触发
*
*============================================================================
* 注释标签和注释标签
*============================================================================
*
* 要从屏幕上的任何位置触发事件,请使用
* notetags或comment tags,使它们可以单击。如果notetag是
* 如果已使用,则无论是哪一页,这都将应用于整个事件。如果
* 仅使用注释标记,它将仅应用于该特定事件页。
*
* 事件注释标签和注释标签
*
*<Click Trigger>
*   - 这将导致事件可以从远处点击,而不需要玩家一直走到它前面来触发它。
*
*<trigger area: x,y,width,height>
*   - 设置事件的触发区域。x,y是相对于事件位置的偏移量,width,height是区域大小
*   - 示例:<trigger area: 0,0,3,2> 表示从事件位置开始3x2的矩形区域
*   - 示例:<trigger area: -1,-1,3,3> 表示以事件为中心的3x3区域
*
* ============================================================================
* Changelog
* ============================================================================
*
* Version 1.10:
* - 添加了触发格位功能
* - 修复了点击检测的问题
*
* Version 1.00:
* - Finished Plugin!
*
* ============================================================================
* End of Helpfile
* ============================================================================
*
*/
//=============================================================================

//=============================================================================
// Game_Temp
//=============================================================================

Yanfly.EvClTr.Game_Temp_setDestination = Game_Temp.prototype.setDestination;
Game_Temp.prototype.setDestination = function(x, y) {
if (!this.isClickableEventAtXy(x, y)) {
    Yanfly.EvClTr.Game_Temp_setDestination.call(this, x, y);
}
};

Game_Temp.prototype.isClickableEventAtXy = function(x, y) {
// 先检查是否有事件在点击的精确位置
var events = $gameMap.eventsXy(x, y);
for (var i = 0; i < events.length; ++i) {
    var ev = events;
    if (ev && ev.isClickTriggered()) {
      ev.onMouseClickTrigger();
      return true;
    }
}

// 如果没有精确命中,检查触发格位
var allEvents = $gameMap.events();
for (var i = 0; i < allEvents.length; ++i) {
    var ev = allEvents;
    if (ev && ev.isClickTriggered() && ev.isInTriggerArea(x, y)) {
      ev.onMouseClickTrigger();
      return true;
    }
}

return false;
};

//=============================================================================
// TouchInput
//=============================================================================

Yanfly.EvClTr.TouchInput_onMouseMove = TouchInput._onMouseMove;
TouchInput._onMouseMove = function(event) {
    Yanfly.EvClTr.TouchInput_onMouseMove.call(this, event);
    this._mouseOverX = Graphics.pageToCanvasX(event.pageX);
    this._mouseOverY = Graphics.pageToCanvasY(event.pageY);
};

//=============================================================================
// Game_Event
//=============================================================================

Yanfly.EvClTr.Game_Event_setupPage = Game_Event.prototype.setupPage;
Game_Event.prototype.setupPage = function() {
Yanfly.EvClTr.Game_Event_setupPage.call(this);
this.setupEventClickTriggerCommentTags();
};

Game_Event.prototype.setupEventClickTriggerCommentTags = function() {
if (!this.page()) return;
this._isClickTriggerable = false;
this._triggerArea = null; // 重置触发区域

// 检查事件备注中的标签
if (this.event().note.match(/<Click Trigger>/i)) {
    this._isClickTriggerable = true;
    this.setupTriggerAreaFromNote(this.event().note);
}

// 检查事件页注释中的标签
var list = this.list();
if (!list) return;

var length = list.length;
for (var i = 0; i < length; ++i) {
    var ev = list;
    if (.contains(ev.code)) {
      var comment = ev.parameters;
      if (comment.match(/<Click Trigger>/i)) {
      this._isClickTriggerable = true;
      }
      if (comment.match(/<trigger area:/i)) {
      this.setupTriggerArea(comment);
      }
    }
}
};

Game_Event.prototype.setupTriggerAreaFromNote = function(note) {
if (note.match(/<trigger area:/i)) {
    this.setupTriggerArea(note);
}
};

Game_Event.prototype.setupTriggerArea = function(comment) {
var match = comment.match(/<trigger area:\s*([-\d]+),\s*([-\d]+),\s*([-\d]+),\s*([-\d]+)>/i);
if (match) {
    this._triggerArea = {
      x: parseInt(match),
      y: parseInt(match),
      width: parseInt(match),
      height: parseInt(match)
    };
}
};

Game_Event.prototype.isClickTriggered = function() {
if (this._isClickTriggerable === undefined) {
    this.setupEventClickTriggerCommentTags();
}
return this._isClickTriggerable || false;
};

Game_Event.prototype.getTriggerArea = function() {
if (!this._triggerArea) {
    // 默认触发区域:事件所在的一个格子
    return {
      x: 0,
      y: 0,
      width: 1,
      height: 1
    };
}
return this._triggerArea;
};

Game_Event.prototype.isInTriggerArea = function(mapX, mapY) {
if (!this.isClickTriggered()) return false;

var evX = this.x;
var evY = this.y;
var area = this.getTriggerArea();

// 计算触发区域的边界
var startX = evX + area.x;
var startY = evY + area.y;
var endX = startX + area.width - 1;
var endY = startY + area.height - 1;

// 检查点击位置是否在区域内
return mapX >= startX && mapX <= endX &&
         mapY >= startY && mapY <= endY;
};

Game_Event.prototype.onMouseClickTrigger = function() {
if (this.isClickTriggered()) {
    $gameTemp.clearDestination();
    this.start();
}
};

//=============================================================================
// 可视化触发区域(调试用)
//=============================================================================

// 如果需要可视化显示触发区域,可以取消注释以下代码
/*
Yanfly.EvClTr.Sprite_Character_update = Sprite_Character.prototype.update;
Sprite_Character.prototype.update = function() {
Yanfly.EvClTr.Sprite_Character_update.call(this);

// 只在调试模式下显示触发区域
if (this._character instanceof Game_Event && this._character.isClickTriggered()) {
    if (!this._triggerAreaOverlay) {
      this._triggerAreaOverlay = new Sprite();
      this._triggerAreaOverlay.bitmap = new Bitmap(1, 1);
      this.addChild(this._triggerAreaOverlay);
    }
   
    var area = this._character.getTriggerArea();
    var tileWidth = $gameMap.tileWidth();
    var tileHeight = $gameMap.tileHeight();
   
    // 计算屏幕位置
    var screenX = this.x - tileWidth / 2;
    var screenY = this.y - tileHeight;
   
    // 绘制触发区域
    this._triggerAreaOverlay.x = screenX + area.x * tileWidth;
    this._triggerAreaOverlay.y = screenY + area.y * tileHeight;
    this._triggerAreaOverlay.bitmap.clear();
    this._triggerAreaOverlay.bitmap.resize(
      area.width * tileWidth,
      area.height * tileHeight
    );
    this._triggerAreaOverlay.bitmap.fillRect(
      0, 0,
      area.width * tileWidth,
      area.height * tileHeight,
      'rgba(255, 0, 0, 0.3)'
    );
    this._triggerAreaOverlay.visible = true;
} else if (this._triggerAreaOverlay) {
    this._triggerAreaOverlay.visible = false;
}
};
*/

//=============================================================================
// Scene_Map 更新 - 更好的鼠标悬停检测
//=============================================================================

// 添加鼠标悬停检测功能(可选)
/*
Yanfly.EvClTr.Scene_Map_update = Scene_Map.prototype.update;
Scene_Map.prototype.update = function() {
Yanfly.EvClTr.Scene_Map_update.call(this);

if (TouchInput.isMoved() || TouchInput.isPressed()) {
    var x = $gameMap.canvasToMapX(TouchInput.x);
    var y = $gameMap.canvasToMapY(TouchInput.y);
   
    var allEvents = $gameMap.events();
    for (var i = 0; i < allEvents.length; ++i) {
      var ev = allEvents;
      if (ev && ev.isClickTriggered() && ev.isInTriggerArea(x, y)) {
      // 可以在这里添加悬停效果
      document.body.style.cursor = 'pointer';
      return;
      }
    }
    document.body.style.cursor = 'default';
}
};
*/

//=============================================================================
// 添加插件命令(可选功能)
//=============================================================================

// 如果需要插件命令控制,可以取消注释以下代码
/*
var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
_Game_Interpreter_pluginCommand.call(this, command, args);

if (command === 'EventClickTrigger') {
    switch(args) {
      case 'enableEvent':
      var eventId = parseInt(args);
      var event = $gameMap.event(eventId);
      if (event) event._isClickTriggerable = true;
      break;
      case 'disableEvent':
      var eventId = parseInt(args);
      var event = $gameMap.event(eventId);
      if (event) event._isClickTriggerable = false;
      break;
      case 'setArea':
      var eventId = parseInt(args);
      var x = parseInt(args);
      var y = parseInt(args);
      var width = parseInt(args);
      var height = parseInt(args);
      var event = $gameMap.event(eventId);
      if (event) {
          event._triggerArea = { x: x, y: y, width: width, height: height };
      }
      break;
    }
}
};
*/

//=============================================================================
// End of File
//=============================================================================
页: [1]
查看完整版本: 自改事件点击触发增强版,添加触发格位