查看: 6653|回复: 23

[原创发布] SEP 全鼠标脚本 v0.93 update

[复制链接]

遠航の猫咪

梦石
3
星屑
26947
在线时间
2423 小时
注册时间
2005-10-15
回帖
987

开拓者

发表于 2018-1-12 23:51:39 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 SailCat 于 2018-1-21 00:12 编辑

以为小500行能搞定了,尼玛又整了姐一千多行……Window_NameInput类神马,能不能不要辣么坑……

虽然所有的scene和window类全部犁过了,但还是真怕哪些犄角旮旯里有漏掉的。

0.93 update
1. 增加对L/R/X/Y/Z按键的鼠标处理(其实就是按Ctrl和Alt修饰)
2. 鼠标增加开关设置,可以在设置中指定开或者关,也可以设置为一个数,表示绑定到这个编号的开关
3. 支持交换左右键

注意插入的位置,默认系统插哪都行,SEP核心系统如果用了窗口增强要插在所有增强的后面,毕竟鼠标最重要的就是操作窗口

[pre lang="ruby"]#==============================================================================
# ■ SEP 全鼠标处理核心 v0.93 by SailCat
#------------------------------------------------------------------------------
#   方法:本脚本插入Main之前使用
#   依赖:无
#   版本:v0.93 (Build 180121)
#   效果:
#     1. 全鼠标响应(不含滚轮)
#     2. 注入Input模块的update处理和trigger处理
#     3. 默认设置中,单击左键等于按C,单击右键等于按B,单击中键等于按A
#        按住CTRL键单击左/右键等于按R或L,按住ALT键单击左/右/中键等于按Z/Y/X
#     4. 注入了对所有窗口(默认引擎中)以及战斗目标箭头的鼠标操作处理
#     5. 地图上可以按住鼠标来移动
#     6. 鼠标操作可以通过配置来开关
#   配置:重复延迟和重复间隔速率,双击设定和行走设定,光标图片等
#   冲突:其他类似脚本
#   说明:
#     1. 调用全鼠标方法为Mouse.press?(按键名称),表示对应的键处于按下状态。
#        键名为以下5个之一:L(左)、R(右)、M(中)、X1(自定1)、X2(自定2)
#     2. 上述press?也可替换为click?, repeat?, release?或trigger?,分别表示:
#        单击(按下并松开一次),按住不放,松开瞬间,按下瞬间
#     3. 双击并不是自动判定的,需要通过begin_dblclick和check_dblclick手动开启,
#        然后用Mouse.dblclick?(按键名称)判定,这是为了避免误操作问题。
#     4. 本脚本并不依赖窗口增强脚本,但如果你使用了窗口增强脚本,
#        请将本脚本插入到窗口增强类脚本的后面。
#==============================================================================
#==============================================================================
# ■ SailCat's 插件公用
#==============================================================================
module SailCat
  $sailcat_import ||= {}
  #--------------------------------------------------------------------------
  # ● 脚本配置区
  #--------------------------------------------------------------------------
  module Mouse_Config
    MOUSE_ENABLED = true          # 是否启用鼠标(true是,false否,数字绑定开关)
    REPEAT_DELAY = 8              # 首次重复前的延迟值(帧)
    REPEAT_SPEED = 4              # 每次重复点击的间隔(帧),越大越慢
    DBLCLICK_TIME = 20            # 双击判定最长有效间隔(帧)
    DBLCLICK_MOVE = 3             # 双击判定最多有效移动(像素)
    C_DBLCLICK = false            # 按下C键是否要求双击
    MOVE_DIR8 = false             # 是否为八方向行走
    CURSOR_PIC = ""               # 鼠标指针图片,为空是默认的图片(白色箭头)
    LEFT_HANDED = false           # 是否为左手鼠标(交换左右键)
    #--------------------------------------------------------------------------
    # ● 配置检查,请勿更改
    #--------------------------------------------------------------------------
    unless REPEAT_SPEED > 0
      raise "重复点击的间隔不能低于1帧"
    end
    unless DBLCLICK_TIME > 0
      raise "双击判定的间隔不能低于1帧"
    end
    unless DBLCLICK_MOVE >= 0
      raise "双击判定的移动不能低于0像素"
    end
  end
  #--------------------------------------------------------------------------
  # ● 植入
  #--------------------------------------------------------------------------
  $sailcat_import[:Mouse] = 0.93
end

#==============================================================================
# ■ 鼠标全局指针
#==============================================================================
$mouse_pointer = Sprite.new
if SailCat::Mouse_Config::CURSOR_PIC != ""
  # 加载图片
  $mouse_pointer.bitmap = RPG::Cache.picture(SailCat::Mouse_Config.CURSOR_PIC)
else
  # 绘制默认图片
  $mouse_pointer.bitmap = Bitmap.new(13, 18)
  black = Color.new(0, 0, 0, 255)
  white = Color.new(255, 255, 255, 255)
  for y in 0..17
    case y
    when 0..11
      $mouse_pointer.bitmap.set_pixel(0, y, black)
      $mouse_pointer.bitmap.fill_rect(1, y, y - 1, 1, white) if y > 1
      $mouse_pointer.bitmap.set_pixel(y, y, black)
    when 12
      $mouse_pointer.bitmap.set_pixel(0, y, black)
      $mouse_pointer.bitmap.fill_rect(1, y, 4, 1, white)
      $mouse_pointer.bitmap.fill_rect(5, y, 8, 1, black)
    when 13..17
      $mouse_pointer.bitmap.set_pixel(0, y, black)
      $mouse_pointer.bitmap.fill_rect(1, y, 16 - y, 1, white) if y < 16
      $mouse_pointer.bitmap.set_pixel(17 - y, y, black)
    end
  end
end
# 设为可见,半透明,总在最上
$mouse_pointer.visible = true
$mouse_pointer.opacity = 160
$mouse_pointer.z = 2147483647

#==============================================================================
# ■ 全鼠标处理核心
#==============================================================================
module Mouse
  include SailCat::Mouse_Config
  #--------------------------------------------------------------------------
  # ● 常量
  #--------------------------------------------------------------------------
  NONE, M, X1, X2 = 0, 4, 5, 6
  L = LEFT_HANDED ? 2 : 1
  R = LEFT_HANDED ? 1 : 2
  #--------------------------------------------------------------------------
  # ● API
  #--------------------------------------------------------------------------
  GetCursorPos = Win32API.new("user32", "GetCursorPos", "p", "i")
  ScreenToClient = Win32API.new("user32", "ScreenToClient", "ip", "i")
  GetActiveWindow = Win32API.new("user32", "GetActiveWindow", "", "i")
  GetAsyncKeyState = Win32API.new("user32", "GetAsyncKeyState", "i", "i")
  #--------------------------------------------------------------------------
  # ● 鼠标按键和光标数据
  #--------------------------------------------------------------------------
  Flags = {}
  Data = {:x => 0, :y => 0, :key => NONE, :frame => 0, :dx => 0, :dy => 0}
  #--------------------------------------------------------------------------
  # ● 鼠标是否可用
  #--------------------------------------------------------------------------
  def self.enabled?
    if MOUSE_ENABLED.is_a?(Fixnum)
      $game_switches ? $game_switches[MOUSE_ENABLED] : true
    else
      MOUSE_ENABLED
    end
  end
  #--------------------------------------------------------------------------
  # ● 更新鼠标输入,该方法每帧调用1次
  #--------------------------------------------------------------------------
  def self.update
    if enabled?
      s = [0, 0].pack("l*")
      GetCursorPos.call(s)
      ScreenToClient.call(hwnd, s)
      Data[:x], Data[:y] = s.unpack("l*")
      $mouse_pointer.visible = true unless $mouse_pointer.visible
      $mouse_pointer.x = Data[:x]
      $mouse_pointer.y = Data[:y]
      Data[:key] = NONE if Data[:frame] == -1
      Data[:frame] += 1
      Flags.each_key do |k|
        if GetAsyncKeyState.call(k) & 32768 != 0
          Flags[k] += 1
        else
          Flags[k] >= 0 ? Flags[k] = -1 : Flags.delete(k)
        end
      end
    elsif $mouse_pointer.visible
      $mouse_pointer.visible = false
      Data[:key] = NONE
    end
  end
  #--------------------------------------------------------------------------
  # ● 判断对应的键是否被按下
  #--------------------------------------------------------------------------
  def self.press?(key)
    return false unless enabled?
    key = const_get(key) if key.is_a?(Symbol)
    return true if Flags[key] && Flags[key] >= 0
    GetAsyncKeyState.call(key) & 32768 != 0 ? (Flags[key] ||= 0; true) : false
  end
  #--------------------------------------------------------------------------
  # ● 判断对应的键是否被松开
  #--------------------------------------------------------------------------
  def self.release?(key)
    return false unless enabled?
    key = const_get(key) if key.is_a?(Symbol)
    Flags[key] == -1
  end
  #--------------------------------------------------------------------------
  # ● 判断对应的键是否被触发
  #--------------------------------------------------------------------------
  def self.trigger?(key)
    return false unless enabled?
    key = const_get(key) if key.is_a?(Symbol)
    Flags[key] ? Flags[key] == 0 : press?(key)
  end
  #--------------------------------------------------------------------------
  # ● 判断对应的键是否被点击
  #--------------------------------------------------------------------------
  def self.click?(key)
    return false unless enabled?
    key = const_get(key) if key.is_a?(Symbol)
    Flags[key] ? release?(key) : (press?(key); false)
  end
  #--------------------------------------------------------------------------
  # ● 判断对应的键是否被按住
  #--------------------------------------------------------------------------
  def self.repeat?(key)
    return false unless enabled?
    key = const_get(key) if key.is_a?(Symbol)
    Flags[key] ? (Flags[key] >= REPEAT_DELAY and (Flags[key] - REPEAT_DELAY) %
      REPEAT_SPEED == 0) : press?(key)
  end
  #--------------------------------------------------------------------------
  # ● 判断对应的键是否被双击
  #--------------------------------------------------------------------------
  def self.dblclick?(key)
    return false unless enabled?
    key = const_get(key) if key.is_a?(Symbol)
    Data[:key] == key and Data[:frame] == -1
  end
  #--------------------------------------------------------------------------
  # ● 获得窗口句柄
  #--------------------------------------------------------------------------
  def self.hwnd
    @hwnd ||= GetActiveWindow.call
  end
  #--------------------------------------------------------------------------
  # ● 获得鼠标指针坐标
  #--------------------------------------------------------------------------
  def self.x;       Data[:x];            end
  def self.y;       Data[:y];            end
  #--------------------------------------------------------------------------
  # ● 双击开始处理
  #--------------------------------------------------------------------------
  def self.begin_dblclick(key)
    key = const_get(key) if key.is_a?(Symbol)
    Data[:key] = key
    Data[:frame] = 0
    Data[:dx] = x
    Data[:dy] = y
    # 按的是左键,不要求C键双击的情况下,判定成功
    Data[:frame] = -1 unless C_DBLCLICK or key != L
  end
  #--------------------------------------------------------------------------
  # ● 双击检查处理
  #--------------------------------------------------------------------------
  def self.check_dblclick(key)
    key = const_get(key) if key.is_a?(Symbol)
    # 如果按的键不是要检查的双击键,双击失败
    return begin_dblclick(key) if Data[:key] != key
    # 如果按的键间隔时间过长了,双击失败
    return begin_dblclick(key) if Data[:frame] > DBLCLICK_TIME
    # 如果两次按键中鼠标移动太多了,双击失败
    return begin_dblclick(key) if (x - Data[:dx]).abs > DBLCLICK_MOVE
    return begin_dblclick(key) if (y - Data[:dy]).abs > DBLCLICK_MOVE
    # 设置双击标记
    Data[:frame] = -1
  end
end

#==============================================================================
# ■ Input 模块的注入
#==============================================================================
module Input
  class << self
    unless method_defined?(:sailcat_sepmouse_update)
      alias sailcat_sepmouse_update update
      alias sailcat_sepmouse_trigger? trigger?
    end
    def update
      sailcat_sepmouse_update
      Mouse.update
    end
    def trigger?(key)
      case key
      when A
        sailcat_sepmouse_trigger?(key) or
          (Mouse.click?(:M) and !press?(CTRL) and !press?(ALT))
      when B
        sailcat_sepmouse_trigger?(key) or
          (Mouse.click?(:R) and !press?(CTRL) and !press?(ALT))
      when C
        sailcat_sepmouse_trigger?(key) or
          (Mouse.dblclick?(:L) and !press?(CTRL) and !press?(ALT))
      when L
        sailcat_sepmouse_trigger?(key) or
          (Mouse.click?(:R) and press?(CTRL) and !press?(ALT))
      when R
        sailcat_sepmouse_trigger?(key) or
          (Mouse.click?(:L) and press?(CTRL) and !press?(ALT))
      when X
        sailcat_sepmouse_trigger?(key) or
          (Mouse.click?(:M) and !press?(CTRL) and press?(ALT))
      when Y
        sailcat_sepmouse_trigger?(key) or
          (Mouse.click?(:R) and !press?(CTRL) and press?(ALT))
      when Z
        sailcat_sepmouse_trigger?(key) or
          (Mouse.click?(:L) and !press?(CTRL) and press?(ALT))
      else
        sailcat_sepmouse_trigger?(key)
      end
    end
  end
end

#==============================================================================
# ■ Game_Player
#==============================================================================
class Game_Player
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined?(:sailcat_sepmouse_update)
    alias sailcat_sepmouse_update update
  end
  #--------------------------------------------------------------------------
  # ● 画面更新
  #--------------------------------------------------------------------------
  def update
    update_mouse
    sailcat_sepmouse_update
  end
  #--------------------------------------------------------------------------
  # ● 鼠标响应更新
  #--------------------------------------------------------------------------
  def update_mouse
    # 移动中、事件执行中、强制移动路线中、
    # 信息窗口一个也不显示的时候
    unless moving? or $game_system.map_interpreter.running? or
           @move_route_forcing or $game_temp.message_window_showing
      # 如果方向键被按下、主角就朝那个方向移动
      case Mouse::MOVE_DIR8 ? mouse_dir8 : mouse_dir4
      when 1
        move_lower_left
      when 2
        move_down
      when 3
        move_lower_right
      when 4
        move_left
      when 5
        dx = Mouse.x - self.screen_x
        dy = Mouse.y - self.screen_y + 16
        if dx.abs >= dy.abs
          dx < 0 ? turn_left : turn_right
        else
          dy < 0 ? turn_up : turn_down
        end
      when 6
        move_right
      when 7
        move_upper_left
      when 8
        move_up
      when 9
        move_upper_right
      end
      Mouse.check_dblclick(:L) if Mouse.click?(:L)
    end
  end
  #--------------------------------------------------------------------------
  # ● 获得鼠标的指向四方向
  #--------------------------------------------------------------------------
  def mouse_dir4
    return 0 unless Mouse.press?(:L)
    dx = Mouse.x - self.screen_x
    dy = Mouse.y - self.screen_y + 16
    return 5 unless dx.abs > 16 or dy.abs > 16
    dx.abs < dy.abs ? [8, 5, 2][(dy <=> 0) + 1] : [4, 5, 6][(dx <=> 0) + 1]
  end
  #--------------------------------------------------------------------------
  # ● 获得鼠标的指向八方向
  #--------------------------------------------------------------------------
  def mouse_dir8
    return 0 unless Mouse.press?(:L)
    dx = Mouse.x - self.screen_x
    dy = Mouse.y - self.screen_y + 16
    return 5 unless dx.abs > 16 or dy.abs > 16
    angle = (Math.atan2(dy, dx) / Math::PI * 180 + 202.5).round
    [4, 7, 8, 9, 6, 3, 2, 1][angle / 45 & 7]
  end
end

#==============================================================================
# ■ Window_Base
#==============================================================================
class Window_Base
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined?(:sailcat_sepmouse_update)
    alias sailcat_sepmouse_update update
  end
  #--------------------------------------------------------------------------
  # ● 相对于本窗口的坐标变换
  #--------------------------------------------------------------------------
  def mouse_x;          Mouse.x - x;              end
  def mouse_y;          Mouse.y - y;              end
  #--------------------------------------------------------------------------
  # ● 相对于窗口内容的坐标变换
  #--------------------------------------------------------------------------
  def contents_x;       mouse_x - 16 + ox;        end
  def contents_y;       mouse_y - 16 + oy;        end
  #--------------------------------------------------------------------------
  # ● 更新
  #--------------------------------------------------------------------------
  def update
    update_mouse if respond_to_mouse?
    sailcat_sepmouse_update
  end
  #--------------------------------------------------------------------------
  # ● 指针位置判定
  #--------------------------------------------------------------------------
  def mouse_over?(rect = Rect.new(x, y, width, height))
    mouse_x.between?(rect.x, rect.x + rect.width - 1) and
    mouse_y.between?(rect.y, rect.y + rect.height - 1)
  end
  #--------------------------------------------------------------------------
  # ● 响应鼠标判定
  #--------------------------------------------------------------------------
  def respond_to_mouse?
    contents != nil and visible
  end
  #--------------------------------------------------------------------------
  # ● 响应选择判定
  #--------------------------------------------------------------------------
  def respond_to_select?
    false
  end
  #--------------------------------------------------------------------------
  # ● 更新鼠标操作
  #--------------------------------------------------------------------------
  def update_mouse
    update_mouse_scroll unless self.is_a?(Window_Selectable) and not active
    update_mouse_select if respond_to_select?
    update_cursor_rect if respond_to?(:update_cursor_rect)
  end
  #--------------------------------------------------------------------------
  # ● 更新鼠标滚动窗口内容
  #--------------------------------------------------------------------------
  def update_mouse_scroll
    # 内容可以水平滚动的情况下
    if contents.width > width - 32
      # 如果单击左右箭头区域
      if Mouse.repeat?(:L) and mouse_y >= 16 and mouse_y < height - 16
        if mouse_x >= 0 and mouse_x < 16
          # 向左侧滚动窗口内容
          scroll_left
        elsif mouse_x >= width - 16 and mouse_x < width
          # 向右侧滚动窗口内容
          scroll_right
        end
      end
    end
    # 内容可以垂直滚动的情况下
    if contents.height > height - 32
      # 如果单击上下箭头区域
      if Mouse.repeat?(:L) and mouse_x >= 16 and mouse_x < width - 16
        if mouse_y >= 0 and mouse_y < 16
          # 向上方滚动窗口内容
          scroll_up
        elsif mouse_y >= height - 16 and mouse_y < height
          # 向下方滚动窗口内容
          scroll_down
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 滚动的单位X值
  #--------------------------------------------------------------------------
  def scroll_x
    Font.default_size
  end
  #--------------------------------------------------------------------------
  # ● 滚动的单位Y值
  #--------------------------------------------------------------------------
  def scroll_y
    return self.line_height if respond_to?(:line_height)
    32
  end
  #--------------------------------------------------------------------------
  # ● 向左滚动
  #--------------------------------------------------------------------------
  def scroll_left
    self.ox = [ox - scroll_x, 0].max
  end
  #--------------------------------------------------------------------------
  # ● 向右滚动
  #--------------------------------------------------------------------------
  def scroll_right
    # 保证显示整字
    d = (contents.width + 32 - width) % scroll_x
    d = scroll_x - d if d > 0
    self.ox = [ox + scroll_x, contents.width + 32 - width + d].min
  end
  #--------------------------------------------------------------------------
  # ● 向上滚动
  #--------------------------------------------------------------------------
  def scroll_up
    self.oy = [oy - scroll_y, 0].max
  end
  #--------------------------------------------------------------------------
  # ● 向下滚动
  #--------------------------------------------------------------------------
  def scroll_down
    # 保证显示整行
    d = (contents.height + 32 - height) % scroll_y
    d = scroll_y - d if d > 0
    self.oy = ([oy + scroll_y, contents.height + 32 - height + d].min)
  end
end

#==============================================================================
# ■ Window_Selectable
#==============================================================================
class Window_Selectable
  #--------------------------------------------------------------------------
  # ● 响应选择判定
  #--------------------------------------------------------------------------
  def respond_to_select?
    active
  end
  #--------------------------------------------------------------------------
  # ● 响应鼠标选择
  #--------------------------------------------------------------------------
  def update_mouse_select
    # 点击内容有效区域的情况下
    if mouse_over?(Rect.new(16, 16, width - 32, height - 32))
      # 点击左键的情况下,检查点击项目
      update_click_select if Mouse.click?(:L)
      # 按住左键的情况下,检查选择项目
      update_check_select if Mouse.press?(:L)
    end
  end
  #--------------------------------------------------------------------------
  # ● 检查点击项目
  #--------------------------------------------------------------------------
  def update_click_select
    # 如果鼠标所在的项就是当前项,检查双击
    Mouse.check_dblclick(:L) if click_index == @index
  end
  #--------------------------------------------------------------------------
  # ● 检查选择项目
  #--------------------------------------------------------------------------
  def update_check_select
    # 如果被点击的项并非当前项
    if click_index != @index
      # 演奏光标SE
      $game_system.se_play($data_system.cursor_se)
      # 选中当前项
      self.index = [[click_index, 0].max, @item_max - 1].min
    end
  end
  #--------------------------------------------------------------------------
  # ● 更新向上滚动
  #--------------------------------------------------------------------------
  def scroll_up
    super
    # 移到区域外的情况下,带动光标一起移动
    if @index / @column_max > self.top_row + (self.page_row_max - 1)
      $game_system.se_play($data_system.cursor_se)
      self.index -= @column_max
    end
  end
  #--------------------------------------------------------------------------
  # ● 更新向下滚动
  #--------------------------------------------------------------------------
  def scroll_down
    super
    # 移到区域外的情况下,带动光标一起移动
    if @index / @column_max < self.top_row
      $game_system.se_play($data_system.cursor_se)
      self.index = [@index + @column_max, @item_max - 1].min
    end
  end
  #--------------------------------------------------------------------------
  # ● 滚动的单位X值
  #--------------------------------------------------------------------------
  def scroll_x
    padding = respond_to?(:cursor_padding) ? cursor_padding : 32
    (contents.width + padding) / @column_max
  end
  #--------------------------------------------------------------------------
  # ● 滚动的单位Y值
  #--------------------------------------------------------------------------
  def scroll_y
    respond_to?(:item_height) ? self.item_height : super
  end
  #--------------------------------------------------------------------------
  # ● 取得光标所指的项目
  #--------------------------------------------------------------------------
  def click_index
    [@item_max - 1, contents_y / scroll_y * @column_max +
      contents_x / scroll_x].min
  end
end

#==============================================================================
# ■ Window_MenuStatus
#==============================================================================
class Window_MenuStatus
  #--------------------------------------------------------------------------
  # ● 项目的行高,但已被窗口增强核心重新定义的情况例外
  #--------------------------------------------------------------------------
  unless $sailcat_import[:WindowCore]
    def item_height;  116;  end
  end
end

#==============================================================================
# ■ Window_Target
#==============================================================================
class Window_Target
  #--------------------------------------------------------------------------
  # ● 项目的行高,但已被窗口增强核心重新定义的情况例外
  #--------------------------------------------------------------------------
  unless $sailcat_import[:WindowCore]
    def item_height;  116;  end
  end
end

#==============================================================================
# ■ Window_NameInput
#==============================================================================
class Window_NameInput
  #--------------------------------------------------------------------------
  # ● 响应选择判定
  #--------------------------------------------------------------------------
  def respond_to_select?
    active
  end
  #--------------------------------------------------------------------------
  # ● 响应鼠标选择
  #--------------------------------------------------------------------------
  def update_mouse_select
    # 点击内容有效区域的情况下
    if mouse_over?(Rect.new(16, 16, width - 32, height - 32))
      # 点击左键的情况下,检查点击项目
      update_click_select if Mouse.click?(:L)
      # 按住左键的情况下,检查选择项目
      update_check_select if Mouse.press?(:L)
    end
  end
  #--------------------------------------------------------------------------
  # ● 检查点击项目
  #--------------------------------------------------------------------------
  def update_click_select
    # 如果鼠标所在的项就是当前项,处理双击
    if click_index == @index
      Mouse.begin_dblclick(:L) unless on_command?
      Mouse.check_dblclick(:L)
    end
  end
  #--------------------------------------------------------------------------
  # ● 检查选择项目
  #--------------------------------------------------------------------------
  def update_check_select
    # 如果被点击的项并非当前项
    if click_index != @index and click_index >= 0
      # 演奏光标SE
      $game_system.se_play($data_system.cursor_se)
      # 选中当前项
      @index = [[click_index, 0].max, item_max - 1].min
    end
  end
  #--------------------------------------------------------------------------
  # ● [确定]的判定
  #--------------------------------------------------------------------------
  def on_command?
    @index >= item_max - 1
  end
  #--------------------------------------------------------------------------
  # ● 最大项目数
  #--------------------------------------------------------------------------
  def item_max
    if respond_to?(:choices_max)
      choices_max
    elsif $sailcat_import[:WindowCore]
      CHARACTER_TABLE_NORMAL.size
    else
      CHARACTER_TABLE.size + 1
    end
  end
  #--------------------------------------------------------------------------
  # ● 取得光标所指的项目
  #--------------------------------------------------------------------------
  def click_index
    mx, my = mouse_x - 16, mouse_y - 16
    0.upto(item_max - 1) do |i|
      r = item_rect(i)
      if (mx - r.x).between?(0, r.width - 1) and
        (my - r.y).between?(0, r.height - 1)
        return i
      end
    end
    -1
  end
  #--------------------------------------------------------------------------
  # ● 取得某项的光标区域
  #--------------------------------------------------------------------------
  def item_rect(index)
    last_index = @index
    @index = index
    update_cursor_rect
    rect = cursor_rect.clone
    @index = last_index
    update_cursor_rect
    rect
  end
end

#==============================================================================
# ■ Window_InputNumber
#==============================================================================
class Window_InputNumber
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined?(:sailcat_sepmouse_initialize)
    alias sailcat_sepmouse_initialize initialize
    alias sailcat_sepmouse_update_cursor_rect update_cursor_rect
  end
  #--------------------------------------------------------------------------
  # ● 初始化对像
  #     digits_max : 位数
  #--------------------------------------------------------------------------
  def initialize(digits_max)
    @up_arrow = Sprite.new
    @down_arrow = Sprite.new
    sailcat_sepmouse_initialize(digits_max)
    @up_arrow.bitmap = @down_arrow.bitmap = self.windowskin
    @up_arrow.src_rect = Rect.new(self.windowskin.width - 40, 16, 16, 7)
    @down_arrow.src_rect = Rect.new(self.windowskin.width - 40, 41, 16, 7)
    @up_arrow.z = @down_arrow.z = z + 1
  end
  #--------------------------------------------------------------------------
  # ● 设置内容不透明度
  #--------------------------------------------------------------------------
  def contents_opacity=(opacity)
    super
    @up_arrow.opacity = @down_arrow.opacity = opacity
  end
  #--------------------------------------------------------------------------
  # ● 更新光标矩形
  #--------------------------------------------------------------------------
  def update_cursor_rect
    sailcat_sepmouse_update_cursor_rect
    offset = $sailcat_import[:WindowCore] ? 24 + @cursor_width >> 1 : 16
    @up_arrow.x = @down_arrow.x = x + @index * @cursor_width + offset
    @up_arrow.y = y + 7
    @down_arrow.y = y + height - 14
  end
  #--------------------------------------------------------------------------
  # ● 释放
  #--------------------------------------------------------------------------
  def dispose
    @up_arrow.dispose
    @down_arrow.dispose
    super
  end
  #--------------------------------------------------------------------------
  # ● 响应选择判定
  #--------------------------------------------------------------------------
  def respond_to_select?
    active
  end
  #--------------------------------------------------------------------------
  # ● 响应鼠标选择
  #--------------------------------------------------------------------------
  def update_mouse_select
    # 点击内容有效区域的情况下
    if mouse_over?(Rect.new(16, 16, width - 32, height - 32))
      # 点击左键的情况下,检查点击项目
      update_click_select if Mouse.click?(:L)
      # 按住左键的情况下,检查选择项目
      update_check_select if Mouse.press?(:L)
    # 点击上箭头的情况下
    elsif Mouse.x.between?(@up_arrow.x, @up_arrow.x + 15) and
      Mouse.y.between?(@up_arrow.y, @up_arrow.y + 6)
      update_value(+2) if Mouse.repeat?(:L)
    # 点击下箭头的情况下
    elsif Mouse.x.between?(@down_arrow.x, @down_arrow.x + 15) and
      Mouse.y.between?(@down_arrow.y, @down_arrow.y + 6)
      update_value(-2) if Mouse.repeat?(:L)
    end
  end
  #--------------------------------------------------------------------------
  # ● 更新数值
  #--------------------------------------------------------------------------
  unless $sailcat_import[:WindowCore]
    def update_value(delta)
      $game_system.se_play($data_system.cursor_se)
      place = 10 ** (@digits_max - 1 - @index)
      n = @number / place % 10
      @number -= n * place
      n = (n + 1) % 10 if delta > 0
      n = (n + 9) % 10 if delta < 0
      @number += n * place
      refresh
    end
  end
  #--------------------------------------------------------------------------
  # ● 检查点击项目
  #--------------------------------------------------------------------------
  def update_click_select
    # 如果鼠标所在的项就是当前项,检查双击
    Mouse.check_dblclick(:L) if click_index == @index
  end
  #--------------------------------------------------------------------------
  # ● 检查选择项目
  #--------------------------------------------------------------------------
  def update_check_select
    # 如果被点击的项并非当前项
    if click_index != @index
      # 演奏光标SE
      $game_system.se_play($data_system.cursor_se)
      # 选中当前项
      @index = [[click_index, 0].max, @digits_max - 1].min
    end
  end
  #--------------------------------------------------------------------------
  # ● 取得光标所指的项目
  #--------------------------------------------------------------------------
  def click_index
    contents_x / @cursor_width
  end
end

#==============================================================================
# ■ Window_Message
#==============================================================================
class Window_Message
  #--------------------------------------------------------------------------
  # ● 响应选择判定
  #--------------------------------------------------------------------------
  def respond_to_select?
    contents_opacity == 255 and @input_number_window.nil?
  end
  #--------------------------------------------------------------------------
  # ● 响应鼠标选择
  #--------------------------------------------------------------------------
  def update_mouse_select
    # 当前是消息结束待机的情况下
    if pause or (@text and not @text.empty?)
      # 左键单击视同双击
      if Mouse.click?(:L)
        Mouse.begin_dblclick(:L)
        Mouse.check_dblclick(:L)
      end
    # 当前是处理选择项的情况下,执行原处理
    elsif active
      super
    end
  end
  #--------------------------------------------------------------------------
  # ● 检查选择项目
  #--------------------------------------------------------------------------
  def update_check_select
    # 点击项不在列表区域的情况下,返回
    return if click_index < 0
    super
  end
  #--------------------------------------------------------------------------
  # ● 取得光标所指的项目
  #--------------------------------------------------------------------------
  def click_index
    # 变换坐标为相对于内容的值
    mx, my = mouse_x - 16, mouse_y - 16 - $game_temp.choice_start * scroll_y
    # 多列的情况下考虑列间距
    padding = respond_to?(:cursor_padding) ? cursor_padding : 32
    [@item_max - 1, (self.top_row + my / scroll_y) * @column_max +
      mx / ((contents.width + padding) / @column_max)].min
  end
end

#==============================================================================
# ■ Arrow_Base
#==============================================================================
class Arrow_Base
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined?(:sailcat_sepmouse_update)
    alias sailcat_sepmouse_update update
  end
  #--------------------------------------------------------------------------
  # ● 更新
  #--------------------------------------------------------------------------
  def update
    update_mouse
    sailcat_sepmouse_update
  end
  #--------------------------------------------------------------------------
  # ● 更新鼠标处理
  #--------------------------------------------------------------------------
  def update_mouse
    # 点击左键,指向有效的情况下
    if (Mouse.trigger?(:L) or Mouse.release?(:L)) and click_index >= 0
      # 点击当前指向战斗者的情况下
      if click_index == @index
        # 执行双击检查
        Mouse.check_dblclick(:L) if Mouse.click?(:L)
      # 点击的不是当前战斗者的情况下
      else
        # 演奏光标 SE
        $game_system.se_play($data_system.cursor_se)
        @index = click_index
        # 开始准备双击
        Mouse.begin_dblclick(:L) if Mouse.click?(:L)
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 取得光标所指的项目
  #--------------------------------------------------------------------------
  def click_index
    members.sort {|a, b| b.screen_z - a.screen_z}.each do |c|
      next if c.is_a?(Game_Enemy) and not c.exist?
      bitmap = RPG::Cache.battler(c.battler_name, c.battler_hue)
      x = c.screen_x - (bitmap.width >> 1)
      y = c.screen_y - bitmap.height
      if Mouse.x.between?(x, x + bitmap.width - 1) and
        Mouse.y.between?(y, y + bitmap.height - 1)
        return c.index
      end
    end
    return -1
  end
end

#==============================================================================
# ■ Arrow_Enemy
#==============================================================================
class Arrow_Enemy
  #--------------------------------------------------------------------------
  # ● 队伍成员
  #--------------------------------------------------------------------------
  def members;          $game_troop.enemies;          end
end

#==============================================================================
# ■ Arrow_Actor
#==============================================================================
class Arrow_Actor
  #--------------------------------------------------------------------------
  # ● 队伍成员
  #--------------------------------------------------------------------------
  def members;          $game_party.actors;           end
end

#==============================================================================
# ■ Scene_File
#==============================================================================
class Scene_File
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined?(:sailcat_sepmouse_update)
    alias sailcat_sepmouse_update update
  end
  #--------------------------------------------------------------------------
  # ● 更新
  #--------------------------------------------------------------------------
  def update
    update_mouse
    sailcat_sepmouse_update
  end
  #--------------------------------------------------------------------------
  # ● 更新鼠标处理
  #--------------------------------------------------------------------------
  def update_mouse
    # 点击左键,窗口有效的情况下
    if (Mouse.press?(:L) or Mouse.release?(:L)) and click_index >= 0
      # 如果被点击的项就是当前项
      if click_index + (@top_index || 0) == @file_index
        # 执行双击检查
        Mouse.check_dblclick(:L) if Mouse.click?(:L)
      # 如果被点击的项并非当前项
      elsif @savefile_windows[click_index].is_a?(Window_SaveFile)
        # 演奏光标SE
        $game_system.se_play($data_system.cursor_se)
        # 选中当前项
        @savefile_windows[@file_index % 4].selected = false
        @file_index = [[click_index, 0].max, @savefile_windows.size - 1].min +
          (@top_index || 0)
        @savefile_windows[@file_index % 4].selected = true
        # 开始准备双击
        Mouse.begin_dblclick(:L) if Mouse.click?(:L)
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 取得光标所指的项目
  #--------------------------------------------------------------------------
  def click_index
    @savefile_windows.each_with_index do |w, i|
      return i if w.mouse_over?
    end
    return -1
  end
end

#==============================================================================
# ■ Scene_Battle
#==============================================================================
class Scene_Battle
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined?(:sailcat_sepmouse_update_phase5)
    alias sailcat_sepmouse_update_phase5 update_phase5
  end
  #--------------------------------------------------------------------------
  # ● 画面更新 (结束战斗回合)
  #--------------------------------------------------------------------------
  def update_phase5
    sailcat_sepmouse_update_phase5
    update_mouse_phase5
  end
  #--------------------------------------------------------------------------
  # ● 更新鼠标处理 (结束战斗回合)
  #--------------------------------------------------------------------------
  def update_mouse_phase5
    # 等待计数已归 0 ,按左或右键的情况下
    if @phase5_wait_count == 0 and (Mouse.click?(:L) or Mouse.click?(:R))
      # 战斗结束
      battle_end(0)
    end
  end
end

#==============================================================================
# ■ Scene_Name
#==============================================================================
class Scene_Name
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined?(:sailcat_sepmouse_update)
    alias sailcat_sepmouse_update update
  end
  #--------------------------------------------------------------------------
  # ● 更新
  #--------------------------------------------------------------------------
  def update
    update_mouse
    sailcat_sepmouse_update
  end
  #--------------------------------------------------------------------------
  # ● 更新鼠标处理
  #--------------------------------------------------------------------------
  def update_mouse
    unless $sailcat_import[:WindowCore]
      # 右击鼠标的情况下
      if Mouse.click?(:R) and @edit_window.index > 0
        # 演奏取消 SE
        $game_system.se_play($data_system.cancel_se)
        # 删除文字
        @edit_window.back
      end
    end
  end
end

#==============================================================================
# ■ Scene_Gameover
#==============================================================================
class Scene_Gameover
  #--------------------------------------------------------------------------
  # ● 方法重定义
  #--------------------------------------------------------------------------
  unless method_defined?(:sailcat_sepmouse_update)
    alias sailcat_sepmouse_update update
  end
  #--------------------------------------------------------------------------
  # ● 更新
  #--------------------------------------------------------------------------
  def update
    update_mouse
    sailcat_sepmouse_update
  end
  #--------------------------------------------------------------------------
  # ● 更新鼠标处理
  #--------------------------------------------------------------------------
  def update_mouse
    # 点击鼠标左键或右键的情况下
    if Mouse.click?(:L) or Mouse.click?(:R)
      # 切换到标题画面
      $scene = Scene_Title.new
    end
  end
end
[/pre]

评分

参与人数 5赞 +5 收起 理由
kimi1123 + 1 我很赞同
mori13 + 1 塞糖
king + 1 精品文章
梦幻想 + 1 塞糖
RedWK + 1 塞糖

查看全部评分

SailCat (小猫子·要开心一点) 共上站 24 次,发表过 11 篇文章 上 次 在: [2006年01月28日11:41:18 星期六] 从 [162.105.120.91] 到本站一游。
梦石
0
星屑
29220
在线时间
1535 小时
注册时间
2006-1-10
回帖
1898

开拓者第一届地图绘制大赛RTP组第四名

发表于 2018-1-13 18:39:29 | 显示全部楼层
试用了一下,必须有SEP核心插件
然后,不要双击了,我觉得鼠标左键会被按坏

我只是进行几次战斗,操作上手感不好,我总觉得鼠标按键坏掉,因为点了一次没用,然后我就连击
菜单方面也是!为什么要双击?

还是我习惯MV的鼠标,都是鼠标操作比较流畅,总之确定,就点击左键,取消就右键
实在不习惯双击

点评

SEP核心其实就是系统默认引擎的部分重写,什么新增项也没有,理论上说不可能缺少它就无法运行的啊。能把出错信息贴一下吗?  发表于 2018-1-13 19:09
很奇怪,我在默认新建的工程中直接插入这个脚本是可以直接运行的,并不需要SEP核心插件…… 另外,不要双击的话改个设置就好 C_DBLCLICK = false  发表于 2018-1-13 19:02
右键倒是很灵敏,我老怀疑我的鼠标左键坏掉……取消连击2次吧,一次点击就行  发表于 2018-1-13 18:40
MV帮助 http://miaowm5.github.io/RMMV-F1/日复一日,年复一年人还是保留一点自我兴趣的好啊~~~忘记过去 ,这样我就可以  放弃未来了……哭~~终于找回以前的头像了,哎~~原来我是那么的想念阿……
画地图没灵感?很烦?很无聊 【 戳 我 】一 大 波 地 图 在 等 你  \^0^/
我的游戏
回复

使用道具 举报

梦石
0
星屑
29220
在线时间
1535 小时
注册时间
2006-1-10
回帖
1898

开拓者第一届地图绘制大赛RTP组第四名

发表于 2018-1-13 19:16:14 | 显示全部楼层
直接丢进12年的工程测试,没有任何冲突!  
对于事件类制作的小游戏,按下空格键判断无效,得用Mouse.press?(C)来代替?
右键呼出菜单,对于图片菜单无效!
其他的,1.没有自动寻路 2.没有冲刺加速
建议一直按鼠标用加速效果!
点击行走时,觉得人物好慢啊

点评

自动寻路问题在于目前所有算法都不能直接套用,因为角色行走和其他NPC是并行处理,预设路径上一旦挡了人以后都会%$*&%,并且明雷遇到怪也不触发   发表于 2018-1-13 19:21
自动寻路会另外发布的,毕竟不是鼠标专用脚本,冲刺加速这个怕引起其他问题。 图片菜单及事件问题,事件菜单里的判定用的是press?,我改改解释器.   发表于 2018-1-13 19:18
MV帮助 http://miaowm5.github.io/RMMV-F1/日复一日,年复一年人还是保留一点自我兴趣的好啊~~~忘记过去 ,这样我就可以  放弃未来了……哭~~终于找回以前的头像了,哎~~原来我是那么的想念阿……
画地图没灵感?很烦?很无聊 【 戳 我 】一 大 波 地 图 在 等 你  \^0^/
我的游戏
回复

使用道具 举报

梦石
0
星屑
4623
在线时间
1207 小时
注册时间
2016-4-7
回帖
944

开拓者

发表于 2018-1-13 20:11:31 | 显示全部楼层
本帖最后由 shitake 于 2018-1-13 20:13 编辑

支持滚轮?【逃

不过说到双击的话 想起那个frp里的操作 用一个filter轻松把单击事件组合成双击事件

点评

是的 要自己折腾一大堆win32api 贼几把麻烦 尤其是不靠dll纯ruby的话 2333  发表于 2018-1-15 00:00
滚轮的支持API太复杂了……我宁可自己黑了个Window_InputNumber,还算好用……但还是想把滚轮折腾出来啊……  发表于 2018-1-13 21:09
附庸的附庸不是我的附庸,女儿的女儿还是我的女儿。CK2沉迷ing
回复

使用道具 举报

梦石
0
星屑
1803
在线时间
133 小时
注册时间
2013-10-6
回帖
181
发表于 2018-1-14 00:20:02 | 显示全部楼层
其实刚才说的回调的问题搞定了之后,建议鼠标点击也用消息处理最好。GetAsyncKeyState可靠性太低了,容易吞输入;双击判定间隔之类的也是遵循用户设置为好。
←你看到一只经常潜水的萌新。
回复

使用道具 举报

梦石
0
星屑
2213
在线时间
759 小时
注册时间
2017-10-13
回帖
53
发表于 2018-1-18 19:40:50 | 显示全部楼层
@SailCat  能不能加个开关。。
回复

使用道具 举报

遠航の猫咪

梦石
3
星屑
26947
在线时间
2423 小时
注册时间
2005-10-15
回帖
987

开拓者

 楼主| 发表于 2018-1-21 00:11:50 | 显示全部楼层
更新0.93版本,另外双击C键的设置默认关掉了,有需要的可以打开。
SailCat (小猫子·要开心一点) 共上站 24 次,发表过 11 篇文章 上 次 在: [2006年01月28日11:41:18 星期六] 从 [162.105.120.91] 到本站一游。
回复

使用道具 举报

梦石
0
星屑
2709
在线时间
166 小时
注册时间
2018-1-19
回帖
88
发表于 2018-1-21 14:36:38 | 显示全部楼层
哇,真棒,支持!终于有开关了!虽然偶昨天把另一个鼠标版本试图加了开关但是不知道有没有什么后果。
不过想请问,能否在启用鼠标脚本后让电脑自带的鼠标消失呢?现在看到的情况是移动鼠标的时候新鼠标图标和原鼠标图标共存,导致有点分身的感觉
另外,偶试图更改了鼠标图片的路径Graphics/Icons/001-Weapon01.png,就会显示70行Nomethoderror, undefined method 'CURSOR_PIC' for SailCat::Mouse_Config:Module
虽然检查了过去,但是不理解为什么会变成未定义的。

点评

这个的话,偶翻了原来的鼠标脚本,有个叫ShowCursor的指令可以隐藏自带鼠标  发表于 2018-1-21 16:34
alt+enter全屏后,自带的鼠标就没有了……如果是窗口模式的话不太清楚,我研究一下。  发表于 2018-1-21 16:07
求勾搭QwQ(bu)会使用脚本和事件QwQ虽然脚本还只是初级程度,还在学习ingQwQ
平常很闲,特别想回答问题和解决问题。再求勾搭呜呜呜QWQ
QQ:841155947
回复

使用道具 举报

梦石
0
星屑
2709
在线时间
166 小时
注册时间
2018-1-19
回帖
88
发表于 2018-1-21 14:39:49 | 显示全部楼层
mori13 发表于 2018-1-21 14:36
哇,真棒,支持!终于有开关了!虽然偶昨天把另一个鼠标版本试图加了开关但是不知道有没有什么后果。
不过 ...

喔偶知道为什么会出这个错误了,乃把SailCat::Mouse_Config::CURSOR_PIC打成了SailCat::Mouse_Config.CURSOR_PIC了!,另外RPG::Cache.picture默认到一定是在picture里的文件了呢....鼠标图标的话不算经常放那里的感觉呢,嘛~不过还是很支持

点评

鼠标点击事件干嘛,启动吗?主角隔着八丈远启动事件好像有点什么不对……现在是你走到事件边上点击事件就可以启动之了……另外我在更新寻路.  发表于 2018-1-21 16:08
另外,希望能添加鼠标点击事件的功能同时主角不会乱动的功能。(当然,这好像和鼠标移动主角有些冲突了)  发表于 2018-1-21 15:44
求勾搭QwQ(bu)会使用脚本和事件QwQ虽然脚本还只是初级程度,还在学习ingQwQ
平常很闲,特别想回答问题和解决问题。再求勾搭呜呜呜QWQ
QQ:841155947
回复

使用道具 举报

梦石
0
星屑
2709
在线时间
166 小时
注册时间
2018-1-19
回帖
88
发表于 2018-1-21 16:46:44 | 显示全部楼层
鼠标点击事件来启动事件只是一个功能,可以用来点击图片上的按钮,或者是技能的图标之类的呀,或者是双击某些图案,以及可以类似于https://rpg.blue/thread-239820-1-1.html或者https://rpg.blue/thread-191580-1-1.html之类的讨论。顺便可以加个开关关闭鼠标控制角色移动和开关这个功能,防止点击的时候移动什么的...嘛,只是个建议啦(吐舌)
求勾搭QwQ(bu)会使用脚本和事件QwQ虽然脚本还只是初级程度,还在学习ingQwQ
平常很闲,特别想回答问题和解决问题。再求勾搭呜呜呜QWQ
QQ:841155947
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

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

在本版发帖返回顶部