查看: 489|回复: 0

[原创发布] 自改事件点击触发增强版,添加触发格位

[复制链接]
梦石
0
星屑
1130
在线时间
138 小时
注册时间
2020-12-6
回帖
27
发表于 2026-1-21 16:27:41 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
[pre lang="javascript"]//=============================================================================
// 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 ([108, 408].contains(ev.code)) {
      var comment = ev.parameters[0];
      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[1]),
      y: parseInt(match[2]),
      width: parseInt(match[3]),
      height: parseInt(match[4])
    };
  }
};

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[0]) {
      case 'enableEvent':
        var eventId = parseInt(args[1]);
        var event = $gameMap.event(eventId);
        if (event) event._isClickTriggerable = true;
        break;
      case 'disableEvent':
        var eventId = parseInt(args[1]);
        var event = $gameMap.event(eventId);
        if (event) event._isClickTriggerable = false;
        break;
      case 'setArea':
        var eventId = parseInt(args[1]);
        var x = parseInt(args[2]);
        var y = parseInt(args[3]);
        var width = parseInt(args[4]);
        var height = parseInt(args[5]);
        var event = $gameMap.event(eventId);
        if (event) {
          event._triggerArea = { x: x, y: y, width: width, height: height };
        }
        break;
    }
  }
};
*/

//=============================================================================
// End of File
//=============================================================================[/pre]
我是的大大,一个做辣鸡游戏的。
您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部