| 赞 | 9 |
| VIP | |
| 好人卡 | |
| 积分 | 29 |
| 经验 | |
| 最后登录 | 2023-12-28 |
| 在线时间 | 713 小时 |
- 梦石
- 0
- 星屑
- 2920
- 在线时间
- 713 小时
- 注册时间
- 2010-7-25
- 回帖
- 659

|
发表于 2020-4-26 22:18:20
|
显示全部楼层
直接用game.exe进游戏发现不支持カルトの鳥篭的鼠标脚本,明明工程里的测试游戏都能正常使用....
点击展开/收起
[pre lang="ruby"]
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ■ RGSS3 Script UniversalMouse - 通用鼠标操作 -
#_/----------------------------------------------------------------------------
#_/ 制 作 者 : CanariAlternate
#_/ 发布来源 : カルトの鳥篭 (http://canarialt.blog.fc2.com)
#_/----------------------------------------------------------------------------
#_/ □ 概要 : 让游戏可以使用鼠标。适用于默认游戏系统,对于外来脚本也尽可能的
# 与其适应。
#_/ ※ 设置鼠标操作需要一些关于脚本的知识。
#_/
#_/ □ 必需 : 在 System 文件夹里放置 CAMouse.dll 文件
#_/
#_/ □ 位置 : 「▼ 素材」之下
#_/----------------------------------------------------------------------------
#_/ 目前、已发现的问题
#_/ 2014/04/03 某些情况下按 F1 时,鼠标会消失不见
#_/ 鼠标操作变得困难。
#_/
#_/----------------------------------------------------------------------------
#_/ 更新履歴 : 2013/09/23 Ver1.00 スクリプトを作成した。
#_/ 2013/09/24 Ver1.01 バグの修正と各種設定を調整した。
#_/ 2013/09/25 Ver1.02 無駄な処理を省き若干軽量化した。
#_/ 2013/09/28 Ver1.03 マウス入力の処理方法を変更した。
#_/ 2013/10/01 Ver1.04 マウスによるプレイヤー移動処理を変更した。
#_/ 2013/10/09 Ver1.05 F12リセットのバグ対策の記述を追加した。
#_/ 2013/10/20 Ver1.06 初期設定に問題を確認したので修正した。
#_/ 2013/10/22 Ver1.07 マウス操作の設定に条件式を使用可能にした。
#_/ 2013/11/01 Ver1.08 マウスカーソルのアニメーション機能を追加した。
#_/ 2013/11/02 Ver1.09 一部の計算式や判定式を設定で弄れるようにした。
#_/ 2013/11/03 Ver1.10 マウスホイールの回転操作の仕様を修正した。
#_/ 2013/11/04 Ver1.11 コンフィグ表示時にマウスが非表示のままの問題を修正した。
#_/ 2013/11/06 Ver1.12 マウス操作の設定の更新タイミングを変更した。
#_/ 2013/11/09 Ver1.13 カーソル及びマウスカーソルの移動に関する仕様を変更した。
#_/ 2013/11/09 Ver1.14 ゲームオーバー画面での設定が抜けていたので追加した。
#_/ 2013/11/10 Ver1.15 クライアント領域とゲーム画面領域の座標変換を追加した。
#_/ 2013/12/06 Ver1.16 セーブ・ロード画面におけるマウスカーソルの挙動を修正した。
#_/ 2013/12/11 Ver1.17 DLLファイルをCRTライブラリに依存しないように修正した。
#_/ 2014/04/03 Ver1.18 コンフィグ表示時にマウスが非表示の問題を若干修正した。
#_/ 2014/04/09 Ver1.19 マウスによるプレイヤー移動処理(:MOVE)を変更した。
#_/ 2014/05/26 Ver1.20 キーを押した状態で:MOVEに切り替わった時に移動する問題を修正した。
#_/ 2014/05/26 Ver1.21 画面内から押し続けているキーは画面外でも有効に仕様を変更した。
#_/ 2014/06/09 Ver1.22 DLLファイルをSystemフォルダに配置するように変更した。
#_/ 2014/07/06 Ver1.23 存在しないクラスを設定した場合、警告を表示するようにした。
#_/ 2014/07/10 Ver1.24 マウスによるプレイヤー移動処理(:MOVE)を変更した。
#_/ 2014/07/25 Ver1.26 モジュールの初期化処理を修正した。
#_/ 2014/07/29 Ver1.27 画面外の場合、マウスカーソルの画像が非表示になるよう修正した。
#_/ 2015/05/17 Ver1.28 イベントコマンドの条件分岐のボタンが機能していない問題を修正した。
#_/ 2015/08/29 Ver1.29 ウィンドウ最小化を解除した際にエラーが発生する問題を修正した。
#_/ 2015/08/30 Ver1.30 特殊なシンボルCPLUSがInput.repeat?において真を出力する間隔が短い問題を修正した。
#_/ 2015/09/02 Ver1.31 毎フレーム実行する必要のない処理を大きく間隔をあけて実行するように変更した。
#_/ 2015/09/05 Ver1.32 マウスの拡張ボタンに対応させた。それに合わせて初期設定とその説明を修正した。
#_/ 2015/09/10 Ver1.33 特殊なシンボル:CURSORの動作を修正した。
#_/ 2015/12/06 Ver1.34 フルスクリーン時のコンフィグにおいてマウスカーソルが非表示になる問題を修正した。
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
$imported ||= {}
$imported[:CanariAlternate_Mouse] = true
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ▼ 下面是脚本的设定
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#==============================================================================
# ■ Calt
#------------------------------------------------------------------------------
# CanariAlternateが制作したスクリプト用のモジュールです。
#==============================================================================
module Calt
#----------------------------------------------------------------------------
# ▼ 鼠标指针设定
#
# ◇ 鼠标指针图像
# 0 = 使用行走图 ※ 推荐
# 1 = 使用 PC 原来的鼠标
MOUSE_CURSOR_TYPE = 1
#
#----------------------------------------------------------------------------
# ▼ 鼠标指针图像设定
#
# 设定鼠标图像的宽度和高度,一张图中可以包含多个鼠标图像,从而做到动画播放效果。
# 和行走图的动画播放类似。
#
# ◇ マウスカーソルの画像名(不包含拓展名)
MOUSE_CURSOR_GRAPHIC_NAME = "Graphics/Characters/Behavior4"
# 初始设定鼠标指针的图片是 RTP 的行走图。
# 如果你想使用 Graphics/System 中的 MouseCursor.png 作为鼠标指针
# 请设定为:
# MOUSE_CURSOR_GRAPHIC_NAME = "Graphics/System/MouseCursor"
#
# ◇ 指针图片的宽度
MOUSE_CURSOR_WIDTH = 32
#
# ◇ 指针图片的高度
MOUSE_CURSOR_HEIGHT = 32
#
# ◇ 鼠标图片相对于鼠标的x坐标
MOUSE_CURSOR_OX = 0
#
# ◇ 鼠标图片相对于鼠标的y坐标
MOUSE_CURSOR_OY = 18
#
# ◇ 鼠标动画顺序(数组大小为 1 以上)
MOUSE_ANIME_PATTERN = [34, 35, 34, 33]
# MOUSE_CURSOR_GRAPHIC_NAME 中设定的图片,会根据鼠标指针图片的长宽裁剪成多个
# 从左到右、从上到下依次为0、1、2、3……
# 动画顺序为从左到右播放,最后一张图片结束后返回第一章。
#
# ◇ 指针动画各帧的持续时间(60帧=1秒)
MOUSE_ANIME_COUNT = 18
#
# ◇ 无任何操作一段时间后鼠标会隐藏
# 0 ~ = 指定时间过去后鼠标隐藏(60帧=1秒)
# nil = 始终显示鼠标,不隐藏
MOUSE_CURSOR_COUNT = 300
#
#----------------------------------------------------------------------------
# ▼ 效果设定
#
# ◇ 鼠标滚轮转动的重复输入 (※ 可用作普通初始值 ※)
# 由 MOUSE_WHEEL_REPEAT 设定转动后多少帧内再次转动视为重复转动。
# MOUSE_WHEEL_REPEAT_SYMBOL 是与这个函数的对象相对应的一个符号数组。
# 默认情况下,光标键是目标。
# 这个功能、当滚轮转到项目的最后(最初)时,不会返回最初(最后)。
MOUSE_WHEEL_REPEAT = 30 # 数值在 1 以上、推荐值 10 ~ 40
MOUSE_WHEEL_REPEAT_SYMBOL = [:UP, :DOWN, :LEFT, :RIGHT]
#
# ◇ 将鼠标光标移动到菜单选项时的坐标计算公式
# base_x = 菜单选项 X 座標
# base_y = 菜单选项 Y 座標
# width = 菜单选项宽
# height = 菜单选项高
MOUSE_POS_X = "base_x + [width - width / 20, width - MouseCursor.width ].max"
MOUSE_POS_Y = "base_y + [ height / 3, MouseCursor.height].min"
# ※ 初始设置为靠近菜单选项的右上方。
#
# ◇ 激活窗口的判定式
# window = 判定対象的窗口判别式
ACTIVE_WINDOW_CRITERION = "window.active && window.open? && window.visible"
#
#----------------------------------------------------------------------------
# ▼ 调试相关
#
# ◇ 显示激活窗口的数组
# p $debug_active_windows
#
# ◇ 显示与每个输入对应的符号数组
# p $debug_input_mouse
#
# ◇ 显示与每个鼠标输入相对应的窗口/场景类的数组
# p $debug_obs_subject
#----------------------------------------------------------------------------
end
#==============================================================================
# ■ MouseCursor
#------------------------------------------------------------------------------
# 该模块管理鼠标光标,执行获取鼠标光标的状态和坐标的设置。
#==============================================================================
module MouseCursor
#----------------------------------------------------------------------------
# ▼ 鼠标操作设置
#
# ◇ 为每个窗口类设置鼠标操作(场景类)
# 当类名设置的类(包括子类)的窗口(场景)处于活动状态时,右边对应的鼠标输入
# 用符号设置键。 如果有多个活动窗口(场景),则下面(摆列末尾)的设置优先。
#
#
# 类名 = 设定类名作为符号。对象也包含子类。
# ※ 如果字符设定由eval()处理、仅在结果是true时有效。
#
# 左键 = 鼠标左键。
#
# 右键 = 鼠标右键。
#
# 按下滚轮 = 按下鼠标滚轮。
#
# 滚轮↑ = 鼠标滚轮后旋转。(朝远离你的方向)
#
# 滚轮↓ = 鼠标滚轮前旋转。(朝你的方向)
#
# 平时 = 这里设定鼠标显示时、判断按键是否被持续按下。
# 我原本想用于 :MOVE 的,但效果很差就没有用了。
#
# 显示 = 显示・不显示・未定是否显示(true / false / nil)鼠标指针指针。
# 你可以设定在特殊场景、窗口中不显示鼠标。
#
# X1按钮 = 鼠标拓展按钮。
# 一般在浏览器中用于「返回」的那个按钮。
#
# X2按钮 = 鼠标拓展按钮。
# 一般在浏览器中用于「下一个」的那个按钮。
#
OBSERVED_SUBJECT_WINDOW = [
#优先度:低
#[ 类名(符号) , 左键, 右键, 按下滚轮, 滚轮↑, 滚轮↓, 平时 , 显示 , X1按钮, X2按钮]
[:Scene_Base , false , false , false , false , false , false , false , false , false ], # 全部场景的基础
[:Scene_Map , :X , :B , :B , :DASH , :WALK , false , true , :L , :R ], # 地图画面
[:Scene_Battle , :C , :B , false , :DASH , :WALK , false , true , :L , :R ], # 战斗画面
#["$game_switches[99]", :C , :B , :A , :LEFT , :RIGHT, false , true , :L , :R ], # 99号开关开启时
[:Scene_Gameover , :C , :B , :A , false , false , false , true , :L , :R ], # 游戏结束画面
[:Window_Message , :C , :B , :A , false , false , false , true , :L , :R ], # 显示文章
[:Window_ScrollText , :C , :B , :A , false , false , false , true , :L , :R ], # 显示滚动文章
[:Window_Selectable , :CPLUS, :B , :A , :SE_UP, :SE_DO, false , true , :L , :R ], # 菜单窗口的基础
[:Window_ItemList , :CPLUS, :B , :A , :SE_UP, :SE_DO, false , true , [:L] , [:R] ], # 物品列表
[:Window_SkillList , :CPLUS, :B , :A , :SE_UP, :SE_DO, false , true , [:L] , [:R] ], # 技能列表
[:Window_Status , :C , :B , :A , false , false , false , true , :L , :R ], # 窗台窗口
[:Window_ShopNumber , :CPLUS, :B , :A , :RIGHT, :LEFT , false , true , :DOWN , :UP ], # 商店的数值输入窗口
[:Window_NameInput , :CPLUS, :B , :A , :L , :R , false , true , :L , :R ], # 输入名称
[:Window_NumberInput , :CPLUS, :B , :A , :UP , :DOWN , false , true , :RIGHT, :LEFT ], # 输入数值
[:Window_DebugRight , :CPLUS, :B , :A , :RIGHT, :LEFT , false , true , :L , :R ], # 调试窗口
[:Scene_File , :C , :B , :A , :UP , :DOWN , false , true , :L , :R ]] # 存档・读档画面
#优先度:高
#
# ◇ 特殊符号
# :CPLUS = 只有在鼠标在选项上时,玩家按鼠标某个键才可以输出 :C (按下确定)。
# 如果鼠标不在选项上、请移到选项上再点击。
# ※ 如果不是 Window 及它的子类,会报错。
#
# :CURSOR = 将鼠标移到选项上。
# ※ 如果不是 Window 及它的子类,会报错。
#
# :MOVE = 玩家朝鼠标方向移动。此外的用途还没想好。
# 按住键时、玩家向鼠标移动。
#
# :DASH = 如果要维持冲刺的状态,请按住 :A。
# :WALK 或 :A 被按下后,冲刺解除。
# ※ 只有在输入:DASH 时 :A 才会维持固定状态。
# 例如、一个优先度高的菜单窗口被激活时
# 不存在:DASH 输入时 :A 的固定状态解除。
# ※ 冲刺状态会在同一场景中被记忆。
#
# :WALK = 参考 :DASH ,解除 :A 的固定状态。
#
# :SE_UP = 参考窗口的 :UP 和 :LEFT 进行输出。
# ※ 如果不是 Window_Selectable 及它的子类,会报错。
#
# :SE_DO = 参考窗口的 :DOWN 和 :RIGHT 进行输出。
# ※ 如果不是 Window_Selectable 及它的子类,会报错。
#
# nil = 对应的键未定(对应键的优先级变低)
#
# false = 没有对应的键
#
# ◇ 预设符号
# :UP = 上
# :DOWN = 下
# :LEFT = 左
# :RIGHT = 右
# :C = 确定
# :B = 取消
# :A = 冲刺
# :X = 未使用(预置)
# :Y = 未使用(预置)
# :Z = 未使用(预置)
# :L = 切换页面(后退)等
# :R = 切换页面(前进)等
# :SHIFT = Shift
# :CTRL = Ctrl
# :ALT = Alt
# :F5~F9 = 功能键( F5 ~ F9 )
#
# ◇ 禁用鼠标的移动
# 如果你使用类似 [:C] 或 [:B] 这样大小为1的数组,可以禁用按下按键时鼠标的移动。
#
# ◇ 窗口类结构图(预设)
# + Window_Base
# |---- + Window_Selectable
# | |---- + Window_Command
# | | |---- + Window_HorzCommand
# | | | |---- - Window_ItemCategory
# | | | |---- - Window_EquipCommand
# | | | |---- - Window_ShopCommand
# | | |
# | | |---- - Window_MenuCommand
# | | |---- - Window_SkillCommand
# | | |---- - Window_ChoiceList
# | | |---- - Window_PartyCommand
# | | |---- - Window_ActorCommand
# | | |---- - Window_TitleCommand
# | | |---- - Window_GameEnd
# | |
# | |---- + Window_MenuStatus
# | | |---- - Window_MenuActor
# | |
# | |---- + Window_ItemList
# | | |---- - Window_EquipItem
# | | |---- - Window_ShopSell
# | | |---- - Window_KeyItem
# | | |---- - Window_BattleItem
# | |
# | |---- + Window_SkillList
# | | |---- - Window_BattleSkill
# | |
# | |---- - Window_EquipSlot
# | |---- - Window_Status
# | |---- - Window_ShopBuy
# | |---- - Window_ShopNumber
# | |---- - Window_NameInput
# | |---- - Window_BattleLog
# | |---- + Window_BattleStatus
# | | |---- - Window_BattleActor
# | |
# | |---- - Window_BattleEnemy
# | |---- - Window_DebugLeft
# | |---- - Window_DebugRight
# |
# |---- - Window_Help
# |---- - Window_Gold
# |---- - Window_SkillStatus
# |---- - Window_EquipStatus
# |---- - Window_SaveFile
# |---- - Window_ShopStatus
# |---- - Window_NameEdit
# |---- - Window_NumberInput
# |---- - Window_Message
# |---- - Window_ScrollText
# |---- - Window_MapName
#
#----------------------------------------------------------------------------
end
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ▲ 以上、是脚本的设定
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ■ 以下使用的符号的含义
#_/
#_/ ★ : 重定义 (冲突可能性 高)
#_/
#_/ ● : 追加 (冲突可能性 中)
#_/
#_/ ○ : 新 (冲突可能性 低)
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ▼ 以下是关于鼠标输入信息的管理的定义
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#==============================================================================
# ■ InputMouse
#------------------------------------------------------------------------------
# マウスからの入力情報を扱うモジュール。
#==============================================================================
module InputMouse
#--------------------------------------------------------------------------
# ○ 定数
#--------------------------------------------------------------------------
TRUE = 1 # 真(※ TRUEは 0 以外なので関数の判定には FALSE を使用)
FALSE = 0 # 偽
GWL_EXSTYLE = -20 # 拡張ウィンドウスタイル(GetWindowLong)
WS_EX_TOPMOST = 0x08 # 最前面ウィンドウ(拡張ウィンドウスタイル)
SM_SWAPBUTTON = 0x17 # マウスボタンの左右の交換の有無(GetSystemMetrics)
VK_LBUTTON = 0x01 # 左マウスボタン
VK_RBUTTON = 0x02 # 右マウスボタン
VK_MBUTTON = 0x04 # ホイールボタン
VK_XBUTTON1 = 0x05 # X1 mouse button
VK_XBUTTON2 = 0x06 # X2 mouse button
#--------------------------------------------------------------------------
# ○ DLL読み込み失敗時はこのモジュールは動作しない
#--------------------------------------------------------------------------
DllLordError = false
#--------------------------------------------------------------------------
# ○ DLL読み込み
#--------------------------------------------------------------------------
begin
# ゲームウィンドウのウィンドウハンドルを取得
WindowHandle = Win32API.new('System/CAMouse', 'GetWindowHandle', 'v', 'l').call
# マウスホイールの回転量を取得する関数
GetWheelDelta = Win32API.new('System/CAMouse', 'GetWheelDelta' , 'v' , 'l')
# フックの解放(ゲーム終了前に実行させる必要あり)
DisposeHook = Win32API.new('System/CAMouse', 'DisposeHook' , 'v' , 'l')
# フックの再生成(特定の条件を満たすとフックが解除されるので)
RegenerationHook = Win32API.new('System/CAMouse', 'RegenerationHook', 'v' , 'l')
# マウスカーソルの表示・非表示を設定する関数
ShowCursor = Win32API.new('user32', 'ShowCursor' , 'l' , 'l')
# マウスカーソルのスクリーン座標を取得する関数
GetCursorPos = Win32API.new('user32', 'GetCursorPos' , 'p' , 'i')
# マウスカーソルのスクリーン座標を設定する関数
SetCursorPos = Win32API.new('user32', 'SetCursorPos' , %w(i i), 'i')
# ウィンドウのクライアント領域を取得する関数
GetClientRect = Win32API.new('user32', 'GetClientRect' , %w(l p), 'i')
# スクリーン座標をクライアント座標に変換する関数
ScreenToClient = Win32API.new('user32', 'ScreenToClient' , %w(l p), 'i')
# クライアント座標をスクリーン座標に変換する関数
ClientToScreen = Win32API.new('user32', 'ClientToScreen' , %w(l p), 'i')
# キー・ボタンの状態を取得する関数
GetAsyncKeyState = Win32API.new('user32', 'GetAsyncKeyState' , 'i' , 'i')
# システムの状態を取得する関数
GetSystemMetrics = Win32API.new('user32', 'GetSystemMetrics' , 'i' , 'i')
# ウィンドウの状態を取得する関数(フルスクリーン状態の検出に使用)
GetWindowLong = Win32API.new('user32', 'GetWindowLong' , %w(l i), 'l')
# ウィンドウハンドルの取得に失敗した場合
DllLordError = true if WindowHandle == 0
rescue
msgbox("DLL加载失败!!") if $TEST
DllLordError = true
end
#--------------------------------------------------------------------------
# ○ クラス変数
#--------------------------------------------------------------------------
@@client_rect = "\x00" * 16 # クライアント領域の矩形の取得に使用
@@pos = "\x00" * 8 # マウスカーソルの座標の取得に使用
@@last_frame_count = -1 # 最後のフレーム更新時のカウント
@@regeneration_count = -1 # フック再生成時のカウント
@@input = Array.new(7, 0) # マウス入力の状態
@@input_disabled = [] # マウス入力の禁止リスト
@@delta = 0 # マウスホイールの回転数
@@x = nil # マウスカーソルの X 座標
@@y = nil # マウスカーソルの Y 座標
@@in_client = false # クライアント領域内フラグ
@@inputted = false # マウス入力の有無
@@showing = true # マウスカーソルの表示状態
@@hide_wait = 0 # マウスカーソル非表示までのカウント
#--------------------------------------------------------------------------
# ○ 初期化
#--------------------------------------------------------------------------
def self.init
return if DllLordError
RegenerationHook.call
update
end
#--------------------------------------------------------------------------
# ○ 解放
#--------------------------------------------------------------------------
def self.dispose
return if DllLordError
DisposeHook.call
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの X 座標
#--------------------------------------------------------------------------
def self.x
return @@x
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの Y 座標
#--------------------------------------------------------------------------
def self.y
return @@y
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの座標を設定
#--------------------------------------------------------------------------
def self.set_pos(x, y)
return false if DllLordError
return false if FALSE == GetClientRect.call(WindowHandle, @@client_rect)
width, height = @@client_rect.unpack('l4')[2..3]
x = x * width / Graphics.width
y = y * height / Graphics.height
set_pos = [x, y].pack('ll')
return false if FALSE == ClientToScreen.call(WindowHandle, set_pos)
screen_x , screen_y = set_pos.unpack('ll')
return false if FALSE == SetCursorPos.call(screen_x , screen_y)
if @@showing && @@in_client
@@x, @@y = get_pos
else
@@x, @@y = get_pos
!@@in_client ? show : hide
end
return true
end
#--------------------------------------------------------------------------
# ○ ボタンが現在押されているかどうかを判定
#--------------------------------------------------------------------------
def self.press?(index)
return false if @@input_disabled[index]
return @@input[index] >= 0
end
#--------------------------------------------------------------------------
# ○ ボタンが新たに押されたかどうかを判定
#--------------------------------------------------------------------------
def self.trigger?(index)
return false if @@input_disabled[index]
return @@input[index] == 0
end
#--------------------------------------------------------------------------
# ○ ボタンが新たに押されたかどうかを判定(リピートを考慮)
#--------------------------------------------------------------------------
def self.repeat?(index)
return false if @@input_disabled[index]
value = @@input[index]
return value > 23 ? value % 6 == 5 : value % 23 == 0
end
#--------------------------------------------------------------------------
# ○ ボタンが押され続けている時間を取得
#--------------------------------------------------------------------------
def self.input_time(index)
return -1 if @@input_disabled[index]
return @@input[index]
end
#--------------------------------------------------------------------------
# ○ マウス入力の有無を判定
#--------------------------------------------------------------------------
def self.input?
return true if @@inputted
return true if @@delta != 0
return true if press?(VK_LBUTTON)
return true if press?(VK_RBUTTON)
return true if press?(VK_MBUTTON)
return true if press?(VK_XBUTTON1)
return true if press?(VK_XBUTTON2)
return false
end
#--------------------------------------------------------------------------
# ○ ホイール回転量を取得
#--------------------------------------------------------------------------
def self.wheel_delta
return @@delta
end
#--------------------------------------------------------------------------
# ○ 更新
#--------------------------------------------------------------------------
def self.update
return if DllLordError
@@inputted = input? || @@inputted
update_input
return if @@last_frame_count == Graphics.all_frame_count
if Graphics.all_frame_count - @@regeneration_count > 150
RegenerationHook.call
@@regeneration_count = Graphics.all_frame_count
end
@@inputted = false
@@x, @@y = get_pos # マウスカーソルの座標を更新
if !@@in_client
show
# 画面外での新たな入力は禁止
@@input_disabled[VK_LBUTTON] = true if @@input[VK_LBUTTON] <= 0
@@input_disabled[VK_RBUTTON] = true if @@input[VK_RBUTTON] <= 0
@@input_disabled[VK_MBUTTON] = true if @@input[VK_MBUTTON] <= 0
@@input_disabled[VK_XBUTTON1] = true if @@input[VK_XBUTTON1] <= 0
@@input_disabled[VK_XBUTTON2] = true if @@input[VK_XBUTTON2] <= 0
@@delta = 0
@@hide_wait = 10
else
hide
@@input_disabled.clear
@@hide_wait -= 1 if @@hide_wait > 0
end
show if fullscreen? # フルスクリーン時(F1設定画面におけるマウス非表示の対策)
@@last_frame_count = Graphics.all_frame_count
end
#--------------------------------------------------------------------------
# ○ フルスクリーンかどうか判定
#--------------------------------------------------------------------------
def self.fullscreen?
return GetWindowLong.call(WindowHandle, GWL_EXSTYLE) & WS_EX_TOPMOST == WS_EX_TOPMOST
end
#--------------------------------------------------------------------------
# ○ マウスカーソルを表示(毎フレーム呼び出しで表示状態を維持できる)
#--------------------------------------------------------------------------
def self.show
return if DllLordError
# 表示 : count == 0
# 非表示 : count == -1
# メモ : 32bit版以降のWindowsではプロセスごとに表示カウントが使われている。
# よって、ゲーム終了時にカウントを 0 に戻すなどの処理は不要である。
return if @@showing
begin
count = ShowCursor.call(TRUE)
end while count < 0
ShowCursor.call(FALSE) if count > 0
@@showing = true
end
# 以下は、内部処理
private
#--------------------------------------------------------------------------
# ○ マウスカーソルを非表示
#--------------------------------------------------------------------------
def self.hide
# return unless @@showing # DLLの仕様でコンフィグ画面表示時に表示に切り替わるのでコメントアウト
return if @@hide_wait > 0
if !@@showing
begin
count = ShowCursor.call(FALSE)
end while count >= 0
ShowCursor.call(TRUE) if count < -1
end
@@showing = false
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの座標を取得
#--------------------------------------------------------------------------
def self.get_pos
@@in_client = false
return nil, nil if FALSE == GetCursorPos.call(@@pos)
return nil, nil if FALSE == ScreenToClient.call(WindowHandle, @@pos)
x, y = @@pos.unpack('ll')
return nil, nil if FALSE == GetClientRect.call(WindowHandle, @@client_rect)
width, height = @@client_rect.unpack('l4')[2..3]
return nil, nil if width <= 0 || height <= 0
# クライアント領域内か判定
@@in_client = x >= 0 && y >= 0 && x < width && y < height
# スクリーン座標をゲーム画面座標に変換
x = x * Graphics.width / width
y = y * Graphics.height / height
return x, y
end
#--------------------------------------------------------------------------
# ○ マウス入力を更新
#--------------------------------------------------------------------------
def self.update_input
state_l = GetAsyncKeyState.call(VK_LBUTTON) # 左マウスボタン
state_r = GetAsyncKeyState.call(VK_RBUTTON) # 右マウスボタン
state_m = GetAsyncKeyState.call(VK_MBUTTON) # ホイールボタン
state_1 = GetAsyncKeyState.call(VK_XBUTTON1)
state_2 = GetAsyncKeyState.call(VK_XBUTTON2)
unless FALSE == GetSystemMetrics.call(SM_SWAPBUTTON) # 左右の交換を判定
temp = state_l
state_l = state_r
state_r = temp
end
# 前回の関数呼び出しまでの間に押されていたら真
state_l != 0 ? (@@input[VK_LBUTTON] += 1) : (@@input[VK_LBUTTON] = -1)
state_r != 0 ? (@@input[VK_RBUTTON] += 1) : (@@input[VK_RBUTTON] = -1)
state_m != 0 ? (@@input[VK_MBUTTON] += 1) : (@@input[VK_MBUTTON] = -1)
state_1 != 0 ? (@@input[VK_XBUTTON1] += 1) : (@@input[VK_XBUTTON1] = -1)
state_2 != 0 ? (@@input[VK_XBUTTON2] += 1) : (@@input[VK_XBUTTON2] = -1)
@@delta = GetWheelDelta.call # マウスホイールの回転量
end
end
#==============================================================================
# ■ SceneManager
#------------------------------------------------------------------------------
# シーン遷移を管理するモジュールです。たとえばメインメニューからアイテム画面
# を呼び出し、また戻るというような階層構造を扱うことができます。
#==============================================================================
module SceneManager
#--------------------------------------------------------------------------
# ● 実行
#--------------------------------------------------------------------------
class << self
alias :__Mouse__run :run
end
def self.run
begin
InputMouse.init
__Mouse__run
ensure
InputMouse.dispose
end
end
end
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ▲ 以上、マウス入力情報の管理に関する定義
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ▼ 以下、マウスカーソルの管理に関する定義
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#==============================================================================
# ■ MouseCursor
#------------------------------------------------------------------------------
# マウスカーソルを管理するモジュールです。マウスカーソルの状態や座標の取得
# 座標の設定などは、このモジュールから実行します。
#==============================================================================
module MouseCursor
#--------------------------------------------------------------------------
# ○ 定数
#--------------------------------------------------------------------------
LENGTH = 9 # マウス操作の設定の項目数 - 1
#--------------------------------------------------------------------------
# ○ クラス変数
#--------------------------------------------------------------------------
@@last_x = nil # 最後の X 座標
@@last_y = nil # 最後の Y 座標
@@sprite = nil # マウスカーソルのスプライト
@@moved_by_input = false # マウス入力によるカーソル移動の有無
@@active = false # アクティブ(カーソルの表示・非表示)
@@visible = false # 可視状態
@@visible_count = 9999 # 表示時間
@@input_mouse = Array.new(LENGTH, nil) # 現在、有効なマウス入力の設定の配列
@@obs_subject = Array.new(LENGTH, nil) # 設定の対象の配列(一部の特殊なシンボルで使用)
@@invalid_smp = Array.new(LENGTH, nil) # マウスカーソルの移動無効フラグの配列
#--------------------------------------------------------------------------
# ○ アクティブ
#--------------------------------------------------------------------------
def self.active
return @@active
end
#--------------------------------------------------------------------------
# ○ 可視状態
#--------------------------------------------------------------------------
def self.visible
return @@visible
end
#--------------------------------------------------------------------------
# ○ 可視状態の設定
#--------------------------------------------------------------------------
def self.visible=(visible)
@@visible = visible
@@visible_count = visible ? 0 : Calt::MOUSE_CURSOR_COUNT
end
#--------------------------------------------------------------------------
# ○ マウス入力の設定の配列
#--------------------------------------------------------------------------
def self.input_mouse
return @@input_mouse
end
#--------------------------------------------------------------------------
# ○ 設定の対象の配列
#--------------------------------------------------------------------------
def self.obs_subject
return @@obs_subject
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの移動無効フラグの配列
#--------------------------------------------------------------------------
def self.invalid_smp
return @@invalid_smp
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの X 座標
#--------------------------------------------------------------------------
def self.x
return InputMouse.x
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの Y 座標
#--------------------------------------------------------------------------
def self.y
return InputMouse.y
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの画像名
#--------------------------------------------------------------------------
def self.bitmap_name
return Calt::MOUSE_CURSOR_GRAPHIC_NAME
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの横幅
#--------------------------------------------------------------------------
def self.width
return Calt::MOUSE_CURSOR_WIDTH
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの縦幅
#--------------------------------------------------------------------------
def self.height
return Calt::MOUSE_CURSOR_HEIGHT
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの転送元原点の X 座標
#--------------------------------------------------------------------------
def self.ox
return Calt::MOUSE_CURSOR_OX
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの転送元原点の Y 座標
#--------------------------------------------------------------------------
def self.oy
return Calt::MOUSE_CURSOR_OY
end
#--------------------------------------------------------------------------
# ○ マウスカーソルのアニメーションパターン
#--------------------------------------------------------------------------
def self.anime_pattern
return Calt::MOUSE_ANIME_PATTERN
end
#--------------------------------------------------------------------------
# ○ マウスカーソルのアニメーションの更新間隔
#--------------------------------------------------------------------------
def self.anime_count
return Calt::MOUSE_ANIME_COUNT
end
#--------------------------------------------------------------------------
# ○ 特定の画面更新時はマウスカーソルを消去
#--------------------------------------------------------------------------
def self.cursor_hide
return unless @@sprite && !@@sprite.disposed?
@@sprite.visible = false
end
#--------------------------------------------------------------------------
# ○ 現在の画面のビットマップを取得時にマウスカーソルを一時消去
#--------------------------------------------------------------------------
def self.snap_to_bitmap
return yield unless @@sprite && !@@sprite.disposed?
temp = @@sprite.visible
@@sprite.visible = false
begin
return yield
ensure
@@sprite.visible = temp
end
end
#--------------------------------------------------------------------------
# ○ マウスカーソルが有効か判定
#--------------------------------------------------------------------------
def self.valid?
return !(x.nil? || y.nil?)
end
#--------------------------------------------------------------------------
# ○ マウスカーソルがゲーム画面内か判定
#--------------------------------------------------------------------------
def self.in_game_screen?
return false unless valid?
return x >= 0 && y >= 0 && x < Graphics.width && y < Graphics.height
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの移動
#--------------------------------------------------------------------------
def self.set_pos(new_x, new_y)
return false unless in_game_screen?
return false unless 0 <= new_x && new_x < Graphics.width
return false unless 0 <= new_y && new_y < Graphics.height
@@moved_by_input = true if @@last_x != x || @@last_y != y
InputMouse.set_pos(new_x, new_y)
@@last_x = x
@@last_y = y
return true
end
#--------------------------------------------------------------------------
# ○ フレーム更新
#--------------------------------------------------------------------------
def self.update
update_parameter
update_visible
update_mouse_cursor
end
# 以下は、内部処理
private
#--------------------------------------------------------------------------
# ○ 入力設定の更新
#--------------------------------------------------------------------------
def self.update_parameter
input_index = Array.new(LENGTH) {|i| i } # 条件(input_mouse == nil)を満たす i の配列
@@input_mouse = Array.new(LENGTH, nil)
@@obs_subject = Array.new(LENGTH, nil)
@@invalid_smp = Array.new(LENGTH, nil)
observed_subject_each do |value, subject|
input_index.reject! do |i|
symbol = value
symbol = convert_symbol(symbol, subject) if symbol
symbol = symbol[0] if @@invalid_smp = symbol.kind_of?(Array)
if symbol != nil
@@input_mouse = symbol
@@obs_subject = subject
next true
else
next false
end
end
break if input_index.empty?
end
# デバッグ用のグローバル変数
if $TEST
$debug_input_mouse = @@input_mouse
$debug_obs_subject = @@obs_subject.collect do |subject|
next subject.kind_of?(Scene_Base) ? subject.class : subject
end
$debug_invalid_smp = @@invalid_smp
end
end
#--------------------------------------------------------------------------
# ○ マウス入力の設定とその対象を優先度順に出力するイテレータ
#--------------------------------------------------------------------------
def self.observed_subject_each
# アクティブなウィンドウを取得
active_windows = get_active_windows
# デバッグ用のグローバル変数
if $TEST
$debug_active_windows = active_windows
end
begin
OBSERVED_SUBJECT_WINDOW.reverse.each do |value|
next unless value
if value[0].kind_of?(String) # クラス名の部分が文字列の場合
next unless eval(value[0]) rescue next
windows = active_windows
subject = windows.find {|window| window.reader_ok_enabled? }
subject = windows[0] unless subject
yield value[1, LENGTH], subject
next
end
klass = const_get(value[0]) # ウィンドウのクラス(サブクラス)の場合
if klass <= Window
windows = active_windows.select {|window| window.kind_of?(klass) }
next if windows.empty?
subject = windows.find {|window| window.reader_ok_enabled? }
subject = windows[0] unless subject
yield value[1, LENGTH], subject
next
elsif klass <= Scene_Base # シーンベースのクラス(サブクラス)の場合
subject = SceneManager.scene
next unless subject.kind_of?(klass)
yield value[1, LENGTH], subject
next
end
end
rescue
puts "# 警告 : 通用鼠标脚本"
puts "# 鼠标操作的设定出现问题。"
puts "# 有可能你指定了一个不存在的类。"
ensure
return self
end
end
#--------------------------------------------------------------------------
# ○ アクティブなウィンドウの配列を取得
#--------------------------------------------------------------------------
def self.get_active_windows
return Window.get_all_windows.select do |window|
next eval(Calt::ACTIVE_WINDOW_CRITERION)
end
end
#--------------------------------------------------------------------------
# ○ 特殊なシンボルの変換
#--------------------------------------------------------------------------
def self.convert_symbol(symbol, subject)
# ▼ 裏機能(説明には載せてない)
# ◇ 配列を使って特殊なキーを設定
# 偶数の要素にシンボル、その次の要素に判定式を文字列で記述する。判別式が無い
# 場合は判別式が真として扱う。判別式が真の場合、そのシンボルが出力される。
# C_PLUS = [:C, "subject.mouse_in_cursor?", :CURSOR] ※ :CPLUS と同じ動作をするキー
# C_PLUS_EX = [:C , "subject.mouse_in_cursor?" ,
# :UP , "subject.mouse_in_upper_padding?",
# :DOWN , "subject.mouse_in_under_padding?",
# :CURSOR]
# ◇判別式の例
# マウスカーソルがウィンドウのカーソルの範囲内
# "subject.mouse_in_cursor?"
# マウスカーソルがウィンドウの上の余白の範囲内
# "subject.mouse_in_upper_padding?"
# マウスカーソルがウィンドウの下の余白の範囲内
# "subject.mouse_in_under_padding?"
# マウスカーソルがウィンドウの左の余白の範囲内
# "subject.mouse_in_left_padding?"
# マウスカーソルがウィンドウの右の余白の範囲内
# "subject.mouse_in_right_padding?"
# マウスカーソルがウィンドウの範囲内
# "subject.mouse_in_window?"
if symbol.kind_of?(Array) && symbol.size >= 2
(symbol.size / 2).times do |i|
index = i * 2
criterion = symbol[index + 1] # 判別式(文字列)
if !criterion || eval(criterion) # 判別式なし or 判別式が真
symbol = symbol[index]
break
end
end
end
# カーソル移動用
equal_sym = :SE_UP
if symbol == equal_sym || symbol.kind_of?(Array) && symbol[0] == equal_sym
# if subject.handle?(:pagedown) && subject.handle?(:pageup)
# return_sym = :L
# return symbol.kind_of?(Array) ? [return_sym] : return_sym
# elsif subject.item_max > subject.page_item_max
# return_sym = :L
# return symbol.kind_of?(Array) ? [return_sym] : return_sym
# elsif subject.col_max >= 2
if subject.col_max >= 2
return_sym = :LEFT
return symbol.kind_of?(Array) ? [return_sym] : return_sym
else
return_sym = :UP
return symbol.kind_of?(Array) ? [return_sym] : return_sym
end
end
equal_sym = :SE_DO
if symbol == equal_sym || symbol.kind_of?(Array) && symbol[0] == equal_sym
# if subject.handle?(:pagedown) && subject.handle?(:pageup)
# return_sym = :R
# return symbol.kind_of?(Array) ? [return_sym] : return_sym
# elsif subject.item_max > subject.page_item_max
# return_sym = :R
# return symbol.kind_of?(Array) ? [return_sym] : return_sym
# elsif subject.col_max >= 2
if subject.col_max >= 2
return_sym = :RIGHT
return symbol.kind_of?(Array) ? [return_sym] : return_sym
else
return_sym = :DOWN
return symbol.kind_of?(Array) ? [return_sym] : return_sym
end
end
# 決定キーの拡張版
equal_sym = :CPLUS
if symbol == equal_sym || symbol.kind_of?(Array) && symbol[0] == equal_sym
if subject.mouse_in_cursor?
return_sym = :C
return symbol.kind_of?(Array) ? [return_sym] : return_sym
else
return_sym = :CURSOR
return symbol.kind_of?(Array) ? [return_sym] : return_sym
end
end
return symbol
end
#--------------------------------------------------------------------------
# ○ 表示状態の更新
#--------------------------------------------------------------------------
def self.update_visible
@@active = @@input_mouse[6] # アクティブを更新
if !@@active
@@visible = false # マウスカーソルを非表示の場合
elsif @@moved_by_input || InputMouse.input? || (@@last_x != x || @@last_y != y) && @@last_x && @@last_y
@@visible = true # マウスカーソルが移動してる場合
@@visible_count = 0
elsif !Calt::MOUSE_CURSOR_COUNT
@@visible = true # マウスカーソルを常に表示の場合
elsif Calt::MOUSE_CURSOR_COUNT >= 0
if @@visible_count >= Calt::MOUSE_CURSOR_COUNT
@@visible = false # 入力を確認するまで非表示にする
else
@@visible = true
@@visible_count += 1 # 非表示までのカウントを進める
end
end
@@last_x = x
@@last_y = y
@@moved_by_input = false
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの表示の更新
#--------------------------------------------------------------------------
def self.update_mouse_cursor
if Calt::MOUSE_CURSOR_TYPE == 0 # ピクチャーのカーソル
@@sprite = Sprite_Mouse.new if !@@sprite || @@sprite.disposed?
if in_game_screen?
if @@visible
if @@sprite.visible
@@sprite.opacity = [255, @@sprite.opacity + 15].min
else
@@sprite.opacity = 0
end
else
if @@sprite.visible
@@sprite.opacity = [ 0, @@sprite.opacity - 15].max
else
@@sprite.opacity = 0
end
end
@@sprite.visible = @@visible || @@sprite.opacity > 0
else
@@sprite.visible = false
end
@@sprite.update
elsif Calt::MOUSE_CURSOR_TYPE == 1 # デフォルトのカーソル
InputMouse.show if @@visible
end
end
end
#==============================================================================
# ■ Graphics
#------------------------------------------------------------------------------
# グラフィック全体にかかわる処理を行うモジュール。
#==============================================================================
module Graphics
#--------------------------------------------------------------------------
# ○ クラス変数
#--------------------------------------------------------------------------
@@all_frame_count = 0 unless $!
#--------------------------------------------------------------------------
# ● alias
#--------------------------------------------------------------------------
class << self
unless $!
alias :__Mouse__fadeout :fadeout
alias :__Mouse__fadein :fadein
alias :__Mouse__freeze :freeze
alias :__Mouse__transition :transition
alias :__Mouse__snap_to_bitmap :snap_to_bitmap
alias :__Mouse__frame_count :frame_count=
end
end
#--------------------------------------------------------------------------
# ● 画面のフェードアウト
#--------------------------------------------------------------------------
def self.fadeout(duration)
MouseCursor.cursor_hide
__Mouse__fadeout(duration)
end
#--------------------------------------------------------------------------
# ● 画面のフェードイン
#--------------------------------------------------------------------------
def self.fadein(duration)
MouseCursor.cursor_hide
__Mouse__fadein(duration)
end
#--------------------------------------------------------------------------
# ● 画面のフリーズ
#--------------------------------------------------------------------------
def self.freeze
MouseCursor.cursor_hide
__Mouse__freeze
end
#--------------------------------------------------------------------------
# ● 画面のトランジション
#--------------------------------------------------------------------------
def self.transition(*args)
MouseCursor.cursor_hide
__Mouse__transition(*args)
end
#--------------------------------------------------------------------------
# ● 現在の画面のビットマップを取得
#--------------------------------------------------------------------------
def self.snap_to_bitmap
return MouseCursor.snap_to_bitmap { __Mouse__snap_to_bitmap }
end
#--------------------------------------------------------------------------
# ● 画面の更新回数のカウントの設定
#--------------------------------------------------------------------------
def self.frame_count=(count)
@@all_frame_count = all_frame_count - count
__Mouse__frame_count(count)
end
#--------------------------------------------------------------------------
# ○ ゲーム起動時からの画面の更新回数のカウント
#--------------------------------------------------------------------------
def self.all_frame_count
return @@all_frame_count + frame_count
end
end
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ▲ 以上、マウスカーソルの管理に関する定義
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ▼ 以下、マウスカーソルのスプライトの定義
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#==============================================================================
# ■ Sprite_Mouse
#------------------------------------------------------------------------------
# マウスカーソルのスプライトです。設定を監視し、自動的に変化します。
#==============================================================================
class Sprite_Mouse < Sprite
#--------------------------------------------------------------------------
# ○ オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
super
@bitmap_name = nil
@anime_pattern = MouseCursor.anime_pattern
@anime_index = 0
@anime_count = 0
self.z = 9999
self.visible = false
self.opacity = 0
create_bitmap
create_src_rect
end
#--------------------------------------------------------------------------
# ○ ビットマップの生成
#--------------------------------------------------------------------------
def create_bitmap
@bitmap_name = MouseCursor.bitmap_name
self.bitmap = Bitmap.new(@bitmap_name)
end
#--------------------------------------------------------------------------
# ○ 矩形の生成
#--------------------------------------------------------------------------
def create_src_rect
rect_i = @anime_pattern[@anime_index]
rect_w = MouseCursor.width
rect_h = MouseCursor.height
x_size = bitmap.width / rect_w
rect_x = rect_w * (rect_i % x_size)
rect_y = rect_h * (rect_i / x_size)
self.src_rect = Rect.new(rect_x, rect_y, rect_w, rect_h)
end
#--------------------------------------------------------------------------
# ○ 解放
#--------------------------------------------------------------------------
def dispose
unless self.bitmap && !self.bitmap.disposed?
self.bitmap.dispose
self.bitmap = nil
end
super
end
#--------------------------------------------------------------------------
# ○ フレーム更新
#--------------------------------------------------------------------------
def update
super
self.x = MouseCursor.x || -1
self.y = MouseCursor.y || -1
self.ox = MouseCursor.ox
self.oy = MouseCursor.oy
update_bitmap
update_anime
end
#--------------------------------------------------------------------------
# ○ ビットマップの更新
#--------------------------------------------------------------------------
def update_bitmap
unless @bitmap_name == MouseCursor.bitmap_name
self.bitmap.dispose if self.bitmap && !self.bitmap.disposed?
create_bitmap
@anime_index = 0
@anime_count = 0
end
end
#--------------------------------------------------------------------------
# ○ アニメーションの更新
#--------------------------------------------------------------------------
def update_anime
if !@anime_pattern.equal?(MouseCursor.anime_pattern)
# アニメーションパターンのオブジェクトが違う場合
@anime_pattern = MouseCursor.anime_pattern
@anime_index = 0
@anime_count = 0
create_src_rect
elsif @anime_count > MouseCursor.anime_count
@anime_index += 1
@anime_index = 0 unless @anime_index < @anime_pattern.size
@anime_count = 0
create_src_rect
end
@anime_count += 1
end
end
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ▲ 以上、マウスカーソルのスプライトの定義
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ▼ 以下、マウス入力情報の処理に関する定義
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#==============================================================================
# ■ Input
#------------------------------------------------------------------------------
# ゲームパッドやキーボードからの入力情報を扱うモジュール。
#==============================================================================
module Input
#--------------------------------------------------------------------------
# ○ 定数
#--------------------------------------------------------------------------
PRESET_SYMBOL = [:SHIFT, :CTRL, :ALT, # プリセットのシンボル
:DOWN, :LEFT, :RIGHT, :UP,
:A, :B, :C, :X, :Y, :Z, :L, :R,
:F5, :F6, :F7, :F8, :F9]
VK_MOUSE_L = InputMouse::VK_LBUTTON # 左マウスボタン
VK_MOUSE_R = InputMouse::VK_RBUTTON # 右マウスボタン
VK_MOUSE_M = InputMouse::VK_MBUTTON # ホイールボタン
VK_MOUSE_X1 = InputMouse::VK_XBUTTON1 # X1 mouse button
VK_MOUSE_X2 = InputMouse::VK_XBUTTON2 # X2 mouse button
#--------------------------------------------------------------------------
# ○ クラス変数
#--------------------------------------------------------------------------
@@input_result_dir4 = nil # dir4 の出力を記憶
@@input_result_dir8 = nil # dir8 の出力を記憶
@@input_table = {} # 入力情報のテーブル
@@input_a_fix = {} # :A の固定フラグをシーン毎に記憶
@@start_move = false # :MOVE で使用。移動入力開始フラグ
@@wheel_count = 0 # マウスホイールのリピート判定時間
@@wheel_rotate = 0 # マウスホイールの回転数
@@last_frame_count = -1 # 最後のフレーム更新時のカウント
#--------------------------------------------------------------------------
# ● alias
#--------------------------------------------------------------------------
class << self
unless $!
alias :__Mouse__update :update
alias :__Mouse__press? :press?
alias :__Mouse__trigger? :trigger?
alias :__Mouse__repeat? :repeat?
alias :__Mouse__dir4 :dir4
alias :__Mouse__dir8 :dir8
end
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def self.update
__Mouse__update
InputMouse.update
clear_input_result
update_input_table
end
#--------------------------------------------------------------------------
# ★ press?
#--------------------------------------------------------------------------
def self.press?(sym)
return @@input_table[sym] ? true : false
end
#--------------------------------------------------------------------------
# ★ trigger?
#--------------------------------------------------------------------------
def self.trigger?(sym)
return @@input_table[sym] == 0 ? true : false
end
#--------------------------------------------------------------------------
# ★ repeat?
#--------------------------------------------------------------------------
def self.repeat?(sym)
return false unless value = @@input_table[sym]
return value > 23 ? value % 6 == 5 : value % 23 == 0
end
#--------------------------------------------------------------------------
# ★ dir4
#--------------------------------------------------------------------------
def self.dir4
if @@input_result_dir4 == nil
vert = 0
horz = 0
vert += 8 if press?(:UP)
vert += 2 if press?(:DOWN)
horz += 4 if press?(:LEFT)
horz += 6 if press?(:RIGHT)
vert %= 10
horz %= 10
if vert == 0
@@input_result_dir4 = horz
elsif horz == 0
@@input_result_dir4 = vert
else
vert_value = vert == 8 ? @@input_table[:UP] : @@input_table[:DOWN]
horz_value = horz == 4 ? @@input_table[:LEFT] : @@input_table[:RIGHT]
@@input_result_dir4 = horz_value < vert_value ? horz : vert
end
end
return @@input_result_dir4
end
#--------------------------------------------------------------------------
# ★ dir8
#--------------------------------------------------------------------------
def self.dir8
if @@input_result_dir8 == nil
vert = 0
horz = 0
vert += 8 if press?(:UP)
vert += 2 if press?(:DOWN)
horz += 4 if press?(:LEFT)
horz += 6 if press?(:RIGHT)
vert %= 10
horz %= 10
if vert == 0
@@input_result_dir8 = horz
elsif horz == 0
@@input_result_dir8 = vert
else
@@input_result_dir8 = horz + vert - 5
end
end
return @@input_result_dir8
end
# 以下は、内部処理
private
#--------------------------------------------------------------------------
# ○ プレイヤーから見たマウスカーソルの方向(4方向)を取得 ※現在は未使用
#--------------------------------------------------------------------------
def self.dir4_mouse
return 0 unless MouseCursor.valid?
mx = (MouseCursor.x - 16 + $game_map.display_x * 32) / 32.0
my = (MouseCursor.y - 16 + $game_map.display_y * 32) / 32.0
dx = $game_player.distance_x_from(mx)
dy = $game_player.distance_y_from(my)
dx_abs = dx.abs
dy_abs = dy.abs
return 0 if dx_abs <= 0.5 && dy_abs <= 0.5
if dx_abs > dy_abs
return dx < 0 ? 6 : 4
else
return dy < 0 ? 2 : 8
end
end
#--------------------------------------------------------------------------
# ○ プレイヤーから見たマウスカーソルの方向(8方向)を取得
#--------------------------------------------------------------------------
def self.dir8_mouse
return 0 unless MouseCursor.valid?
mx = (MouseCursor.x - 16 + $game_map.display_x * 32) / 32.0
my = (MouseCursor.y - 16 + $game_map.display_y * 32) / 32.0
dx = $game_player.distance_x_from(mx)
dy = $game_player.distance_y_from(my)
dx_abs = dx.abs
dy_abs = dy.abs
return 0 if dx_abs <= 0.5 && dy_abs <= 0.5
if dy_abs <= 0.5 || dx_abs > dy_abs * 2
return dx < 0 ? 6 : 4
elsif dx_abs <= 0.5 || dx_abs * 2 < dy_abs
return dy < 0 ? 2 : 8
else
return dx < 0 ? (dy < 0 ? 3 : 9) : (dy < 0 ? 1 : 7)
end
end
#--------------------------------------------------------------------------
# ○ 出力の記憶を消去
#--------------------------------------------------------------------------
def self.clear_input_result
@@input_result_dir4 = nil
@@input_result_dir8 = nil
end
#--------------------------------------------------------------------------
# ○ 入力情報を更新
#--------------------------------------------------------------------------
def self.update_input_table
# 有効な設定を取得
input_mouse = MouseCursor.input_mouse # 現在、有効なマウス入力の設定の配列
obs_subject = MouseCursor.obs_subject # 設定の対象の配列(一部の特殊なシンボルで使用)
invalid_smp = MouseCursor.invalid_smp # マウスカーソルの移動無効フラグの配列
# @@input_table の要素は -1 以上の値を想定
# nil = press? == F, trigger? == F, repeat? == F
# -1 = press? == T, trigger? == F, repeat? == F ※扱いは nil と同様
# 0 = press? == T, trigger? == T, repeat? == T
# 1 ~ 22 = press? == T, trigger? == F, repeat? == F
# 23 = press? == T, trigger? == F, repeat? == T
old_input_table = @@input_table.clone # 前フレームの入力情報
@@input_table.clear
# フレーム更新の確認(0 と 1 は通常の更新、2 以上は前フレームの情報をクリア)
rem_frame_count = Graphics.all_frame_count - @@last_frame_count
if rem_frame_count >= 2
old_input_table.clear
@@wheel_rotate = 0
@@wheel_count = 0
end
@@last_frame_count += rem_frame_count
# マウスの入力情報(ボタン)
if symbol = input_mouse[0] and InputMouse.press?(VK_MOUSE_L)
Window.invalid_set_mouse_pos = true if invalid_smp[0]
if symbol == :CURSOR
obs_subject[0].reserve_set_mouse_pos = true if InputMouse.trigger?(VK_MOUSE_L)
elsif count = old_input_table[symbol] and count >= 0
@@input_table[symbol] = count + 1
else
@@input_table[symbol] = InputMouse.input_time(VK_MOUSE_L)
end
end
if symbol = input_mouse[1] and InputMouse.press?(VK_MOUSE_R)
Window.invalid_set_mouse_pos = true if invalid_smp[1]
if symbol == :CURSOR
obs_subject[1].reserve_set_mouse_pos = true if InputMouse.trigger?(VK_MOUSE_R)
elsif count = old_input_table[symbol] and count >= 0
@@input_table[symbol] = count + 1
else
@@input_table[symbol] = InputMouse.input_time(VK_MOUSE_R)
end
end
if symbol = input_mouse[2] and InputMouse.press?(VK_MOUSE_M)
Window.invalid_set_mouse_pos = true if invalid_smp[2]
if symbol == :CURSOR
obs_subject[2].reserve_set_mouse_pos = true if InputMouse.trigger?(VK_MOUSE_M)
elsif count = old_input_table[symbol] and count >= 0
@@input_table[symbol] = count + 1
else
@@input_table[symbol] = InputMouse.input_time(VK_MOUSE_M)
end
end
if symbol = input_mouse[7] and InputMouse.press?(VK_MOUSE_X1)
Window.invalid_set_mouse_pos = true if invalid_smp[7]
if symbol == :CURSOR
obs_subject[7].reserve_set_mouse_pos = true if InputMouse.trigger?(VK_MOUSE_X1)
elsif count = old_input_table[symbol] and count >= 0
@@input_table[symbol] = count + 1
else
@@input_table[symbol] = InputMouse.input_time(VK_MOUSE_X1)
end
end
if symbol = input_mouse[8] and InputMouse.press?(VK_MOUSE_X2)
Window.invalid_set_mouse_pos = true if invalid_smp[8]
if symbol == :CURSOR
obs_subject[8].reserve_set_mouse_pos = true if InputMouse.trigger?(VK_MOUSE_X2)
elsif count = old_input_table[symbol] and count >= 0
@@input_table[symbol] = count + 1
else
@@input_table[symbol] = InputMouse.input_time(VK_MOUSE_X2)
end
end
# マウスの入力情報(ホイール)
if @@wheel_rotate == 0
@@wheel_rotate = (InputMouse.wheel_delta / 120).to_i
elsif @@wheel_rotate > 0
new_rotate = (InputMouse.wheel_delta / 120).to_i
@@wheel_rotate = new_rotate >= 0 ? @@wheel_rotate + new_rotate : new_rotate
else
new_rotate = (InputMouse.wheel_delta / 120).to_i
@@wheel_rotate = new_rotate <= 0 ? @@wheel_rotate + new_rotate : new_rotate
end
if symbol = input_mouse[3] and @@wheel_rotate > 0
Window.invalid_set_mouse_pos = true if invalid_smp[3]
if symbol == :CURSOR
obs_subject[3].reserve_set_mouse_pos = true
elsif rem_frame_count == 0
if count = old_input_table[symbol] and count >= 0
@@input_table[symbol] = count + 1
else
@@input_table[symbol] = @@wheel_count > 0 ? 23 : 0
end
else
if Calt::MOUSE_WHEEL_REPEAT_SYMBOL.include?(symbol)
count = old_input_table[symbol]
@@input_table[symbol] = (@@wheel_count > 0 || count && count >= 0) ? 23 : 0
else
@@input_table[symbol] = 0
end
end
end
if symbol = input_mouse[4] and @@wheel_rotate < 0
Window.invalid_set_mouse_pos = true if invalid_smp[4]
if symbol == :CURSOR
obs_subject[4].reserve_set_mouse_pos = true
elsif rem_frame_count == 0
if count = old_input_table[symbol] and count >= 0
@@input_table[symbol] = count + 1
else
@@input_table[symbol] = @@wheel_count > 0 ? 23 : 0
end
else
if Calt::MOUSE_WHEEL_REPEAT_SYMBOL.include?(symbol)
count = old_input_table[symbol]
@@input_table[symbol] = (@@wheel_count > 0 || count && count >= 0) ? 23 : 0
else
@@input_table[symbol] = 0
end
end
end
if @@wheel_rotate != 0
@@wheel_count = Calt::MOUSE_WHEEL_REPEAT
@@wheel_rotate = [[@@wheel_rotate, 30].min, -30].max if @@wheel_rotate.abs > 30
@@wheel_rotate += @@wheel_rotate < 0 ? 1 : -1 if rem_frame_count != 0
elsif @@wheel_count > 0
@@wheel_count -= 1
end
# マウスの入力情報(常時)
if symbol = input_mouse[5] and MouseCursor.visible && MouseCursor.in_game_screen?
Window.invalid_set_mouse_pos = true if invalid_smp[5]
count = old_input_table[symbol]
@@input_table[symbol] = count ? count + 1 : 0
obs_subject[5].reserve_set_mouse_pos = true if symbol == :CURSOR && !count
end
# プリセットの入力情報
PRESET_SYMBOL.each do |symbol|
next unless __Mouse__press?(symbol)
count = old_input_table[symbol]
@@input_table[symbol] = count ? count + 1 : 0
end
# :MOVE の処理
if @@input_table[:MOVE] and @@start_move ||
input_mouse[0] == :MOVE && InputMouse.trigger?(VK_MOUSE_L) ||
input_mouse[1] == :MOVE && InputMouse.trigger?(VK_MOUSE_R) ||
input_mouse[2] == :MOVE && InputMouse.trigger?(VK_MOUSE_M) ||
input_mouse[5] == :MOVE && MouseCursor.visible
direction = dir8_mouse
if [1, 2, 3].include?(direction)
symbol = :DOWN
count = old_input_table[symbol]
@@input_table[symbol] = count ? count + 1 : 0
end
if [7, 8, 9].include?(direction)
symbol = :UP
count = old_input_table[symbol]
@@input_table[symbol] = count ? count + 1 : 0
end
if [1, 4, 7].include?(direction)
symbol = :LEFT
count = old_input_table[symbol]
@@input_table[symbol] = count ? count + 1 : 0
end
if [3, 6, 9].include?(direction)
symbol = :RIGHT
count = old_input_table[symbol]
@@input_table[symbol] = count ? count + 1 : 0
end
@@start_move = true
else
@@start_move = false
end
# :DASH :WALK の処理
scene_class = SceneManager.scene.class
if @@input_a_fix[scene_class]
if @@input_table[:WALK] == 0 || @@input_table[:A]
@@input_a_fix[scene_class] = false
elsif input_mouse.include?(:DASH) && MouseCursor.visible
@@input_table[:A] = -1
end
else
if @@input_table[:DASH] == 0 && !@@input_table[:A]
@@input_a_fix[scene_class] = true
@@input_table[:A] = -1
end
end
# イベントコマンド『条件分岐 ボタン』からの入力に対応する為の処理
@@input_table[2] = @@input_table[:DOWN]
@@input_table[4] = @@input_table[:LEFT]
@@input_table[6] = @@input_table[:RIGHT]
@@input_table[8] = @@input_table[:UP]
@@input_table[11] = @@input_table[:A]
@@input_table[12] = @@input_table[:B]
@@input_table[13] = @@input_table[:C]
@@input_table[14] = @@input_table[:X]
@@input_table[15] = @@input_table[:Y]
@@input_table[16] = @@input_table[:Z]
@@input_table[17] = @@input_table[:L]
@@input_table[18] = @@input_table[:R]
end
end
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ▲ 以上、マウス入力情報の処理に関する定義
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ▼ 以下、マウスカーソルの処理に関する定義
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#==============================================================================
# ■ Window
#------------------------------------------------------------------------------
# ゲーム内のウィンドウのクラス。内部的には複数のスプライトで構成されています。
#==============================================================================
class Window
#--------------------------------------------------------------------------
# ○ クラス変数
#--------------------------------------------------------------------------
@@all_windows = [] # 全てのウィンドウ
@@invalid_set_mouse_pos = false # カーソルによるマウスカーソルの移動無効
@@invalid_set_cursor_index = false # マウスカーソルによるカーソルの移動無効
#--------------------------------------------------------------------------
# ○ 全てのウィンドウを取得
#--------------------------------------------------------------------------
def self.get_all_windows
@@all_windows.reject! {|window| window.disposed? }
return @@all_windows.clone
end
#--------------------------------------------------------------------------
# ○ カーソルによるマウスカーソルの移動無効の設定
#--------------------------------------------------------------------------
def self.invalid_set_mouse_pos=(invalid)
return @@invalid_set_mouse_pos = invalid
end
#--------------------------------------------------------------------------
# ○ マウスカーソルによるカーソルの移動無効の設定
#--------------------------------------------------------------------------
def self.invalid_set_cursor_index=(invalid)
return @@invalid_set_cursor_index = invalid
end
#--------------------------------------------------------------------------
# ○ 公開インスタンス変数
#--------------------------------------------------------------------------
attr_accessor :reserve_set_mouse_pos # マウスカーソルの移動の予約
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
alias :__Mouse__initialize :initialize unless $!
def initialize(x, y, width, height)
__Mouse__initialize(x, y, width, height)
@@all_windows.push self
@reserve_set_mouse_pos = false
@mouse_x = -1 # マウスカーソルの X 相対座標
@mouse_y = -1 # マウスカーソルの Y 相対座標
@absolute_x = -1 # ウィンドウの X 絶対座標
@absolute_y = -1 # ウィンドウの Y 絶対座標
@observed_absolute_x = -1 # ウィンドウの X 絶対座標を監視
@observed_absolute_y = -1 # ウィンドウの Y 絶対座標を監視
@observed_index = -1 # インデックスを監視
@change_active = true # アクティブになったフラグ
@window_moving = -1 # ウィンドウが移動中カウント
end
#--------------------------------------------------------------------------
# ● アクティブ状態の変更
#--------------------------------------------------------------------------
alias :__Mouse__active :active= unless $!
def active=(active)
__Mouse__active(active)
@change_active = active
end
#--------------------------------------------------------------------------
# ○ カーソルが存在するか判定
#--------------------------------------------------------------------------
def cursor_exist?
return cursor_rect.width > 0 && cursor_rect.height > 0
end
#--------------------------------------------------------------------------
# ○ 決定処理の有効状態を取得
#--------------------------------------------------------------------------
def reader_ok_enabled?
return false
end
#--------------------------------------------------------------------------
# ○ マウスカーソルがウィンドウの範囲内か判定
#--------------------------------------------------------------------------
def mouse_in_window?
get_mouse_pos
return false unless 0 <= @mouse_x && @mouse_x < width
return false unless 0 <= @mouse_y && @mouse_y < height
return true
end
#--------------------------------------------------------------------------
# ○ マウスカーソルが上の余白の範囲内か判定
#--------------------------------------------------------------------------
def mouse_in_upper_padding?
get_mouse_pos
return false unless 0 <= @mouse_x && @mouse_x < width
return false unless 0 <= @mouse_y && @mouse_y < padding
return true
end
#--------------------------------------------------------------------------
# ○ マウスカーソルが下の余白の範囲内か判定
#--------------------------------------------------------------------------
def mouse_in_under_padding?
get_mouse_pos
return false unless 0 <= @mouse_x && @mouse_x < width
return false unless height - padding_bottom <= @mouse_y && @mouse_y < height
return true
end
#--------------------------------------------------------------------------
# ○ マウスカーソルが左の余白の範囲内か判定
#--------------------------------------------------------------------------
def mouse_in_left_padding?
get_mouse_pos
return false unless 0 <= @mouse_x && @mouse_x < padding
return false unless 0 <= @mouse_y && @mouse_y < height
return true
end
#--------------------------------------------------------------------------
# ○ マウスカーソルが右の余白の範囲内か判定
#--------------------------------------------------------------------------
def mouse_in_right_padding?
get_mouse_pos
return false unless width - padding <= @mouse_x && @mouse_x < width
return false unless 0 <= @mouse_y && @mouse_y < height
return true
end
#--------------------------------------------------------------------------
# ○ マウスカーソルがウィンドウの範囲内か判定(余白は含まない)
#--------------------------------------------------------------------------
def mouse_in_contents?
get_mouse_pos
return false unless padding <= @mouse_x && @mouse_x < width - padding
return false unless padding <= @mouse_y && @mouse_y < height - padding_bottom
return true
end
#--------------------------------------------------------------------------
# ○ マウスカーソルが現在のカーソルの範囲内か判定
#--------------------------------------------------------------------------
def mouse_in_cursor?
return false unless MouseCursor.valid?
get_mouse_pos
cursor_x = cursor_rect.x + padding - ox
cursor_y = cursor_rect.y + padding - oy
return false unless cursor_x <= @mouse_x && @mouse_x < cursor_x + cursor_rect.width
return false unless cursor_y <= @mouse_y && @mouse_y < cursor_y + cursor_rect.height
return true
end
#--------------------------------------------------------------------------
# ○ マウスカーソルを現在のカーソルの位置に設定
#--------------------------------------------------------------------------
def set_mouse_pos_from_cursor(force=false)
return false if @@invalid_set_mouse_pos || @window_moving >= 0 unless force
return false unless MouseCursor.in_game_screen?
get_absolute_pos
base_x = @absolute_x + padding + cursor_rect.x - ox
base_y = @absolute_y + padding + cursor_rect.y - oy
width = cursor_rect.width
height = cursor_rect.height
dest_x = eval(Calt::MOUSE_POS_X)
dest_y = eval(Calt::MOUSE_POS_Y)
MouseCursor.set_pos(dest_x, dest_y)
return true
end
#--------------------------------------------------------------------------
# ○ カーソルを現在のマウスカーソルの位置に設定
#--------------------------------------------------------------------------
def set_cursor_index_from_mouse(force=false)
return false if @@invalid_set_cursor_index || @window_moving == 0 || @change_active unless force
return false unless MouseCursor.in_game_screen?
return false unless MouseCursor.active
return false unless mouse_in_contents?
# get_mouse_pos # mouse_in_contents? に含まれるのでコメントアウト
relative_x = @mouse_x - padding + ox
relative_y = @mouse_y - padding + oy
rect = reader_item_rect(reader_index)
if rect.x <= relative_x && relative_x < rect.x + rect.width &&
rect.y <= relative_y && relative_y < rect.y + rect.height
return true
end
reader_item_max.times do |i|
rect = reader_item_rect(i)
next unless rect.x <= relative_x && relative_x < rect.x + rect.width
next unless rect.y <= relative_y && relative_y < rect.y + rect.height
self.writer_index = i
@observed_index = reader_index
unless @@invalid_set_mouse_pos
Sound.play_cursor
@@invalid_set_mouse_pos = true
end
return true
end
return false
end
#--------------------------------------------------------------------------
# ○ 更新内容の監視処理
#--------------------------------------------------------------------------
def observe_update
if @@invalid_set_mouse_pos
@reserve_set_mouse_pos = false
elsif reader_index != @observed_index || @change_active
@reserve_set_mouse_pos = true if active && cursor_exist?
end
get_absolute_pos
if @change_active ||
@absolute_x != @observed_absolute_x || @absolute_y != @observed_absolute_y
@window_moving += 1
else
@window_moving = -1
end
@observed_absolute_x = @absolute_x
@observed_absolute_y = @absolute_y
@observed_index = reader_index
@change_active = false
end
#--------------------------------------------------------------------------
# ○ 更新内容の監視後処理
#--------------------------------------------------------------------------
def post_observe_update
@reserve_set_mouse_pos = false if set_mouse_pos?
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの移動を実行するか判定
#--------------------------------------------------------------------------
def set_mouse_pos?
return @window_moving < 0 && @reserve_set_mouse_pos
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの相対座標を取得
#--------------------------------------------------------------------------
def get_mouse_pos
if MouseCursor.valid?
@mouse_x = MouseCursor.x - x
@mouse_y = MouseCursor.y - y
if viewport
@mouse_x -= viewport.rect.x - viewport.ox
@mouse_y -= viewport.rect.y - viewport.oy
end
else
@mouse_x = -1
@mouse_y = -1
end
end
#--------------------------------------------------------------------------
# ○ ウィンドウの絶対座標を取得
#--------------------------------------------------------------------------
def get_absolute_pos
@absolute_x = x
@absolute_y = y
if viewport
@absolute_x += viewport.rect.x - viewport.ox
@absolute_y += viewport.rect.y - viewport.oy
end
end
#--------------------------------------------------------------------------
# ○ 項目数の取得
#--------------------------------------------------------------------------
def reader_item_max
return 0
end
#--------------------------------------------------------------------------
# ○ 項目を描画する矩形の取得
#--------------------------------------------------------------------------
def reader_item_rect(index)
return cursor_rect
end
#--------------------------------------------------------------------------
# ○ カーソル位置の設定
#--------------------------------------------------------------------------
def writer_index=(index)
# nothing
end
#--------------------------------------------------------------------------
# ○ カーソル位置の取得
#--------------------------------------------------------------------------
def reader_index
return -1
end
end
#==============================================================================
# ■ Window_Selectable
#------------------------------------------------------------------------------
# カーソルの移動やスクロールの機能を持つウィンドウクラスです。
#==============================================================================
class Window_Selectable < Window_Base
#--------------------------------------------------------------------------
# ● カーソル位置の設定
#--------------------------------------------------------------------------
alias :__Mouse__index :index=
def index=(index)
__Mouse__index(index)
@@invalid_set_cursor_index = true
end
#--------------------------------------------------------------------------
# ● カーソルの移動処理
#--------------------------------------------------------------------------
alias :__Mouse__process_cursor_move :process_cursor_move
def process_cursor_move
last_index = @index
__Mouse__process_cursor_move
return unless @index == last_index && cursor_movable?
set_cursor_index_from_mouse
end
#--------------------------------------------------------------------------
# ○ 決定処理の有効状態を取得
#--------------------------------------------------------------------------
def reader_ok_enabled?
return ok_enabled?
end
#--------------------------------------------------------------------------
# ○ 項目数の取得
#--------------------------------------------------------------------------
def reader_item_max
return item_max
end
#--------------------------------------------------------------------------
# ○ 項目を描画する矩形の取得
#--------------------------------------------------------------------------
def reader_item_rect(index)
return item_rect(index)
end
#--------------------------------------------------------------------------
# ○ カーソル位置の設定
#--------------------------------------------------------------------------
def writer_index=(index)
self.index = index
end
#--------------------------------------------------------------------------
# ○ カーソル位置の取得
#--------------------------------------------------------------------------
def reader_index
return @index
end
end
#==============================================================================
# ■ Window_NumberInput
#------------------------------------------------------------------------------
# イベントコマンド[数値入力の処理]に使用するウィンドウです。
#==============================================================================
class Window_NumberInput < Window_Base
#--------------------------------------------------------------------------
# ● カーソルの移動処理
#--------------------------------------------------------------------------
alias :__Mouse__process_cursor_move :process_cursor_move
def process_cursor_move
last_index = @index
__Mouse__process_cursor_move
return unless @index == last_index && active && open?
set_cursor_index_from_mouse
end
#--------------------------------------------------------------------------
# ○ 決定処理の有効状態を取得
#--------------------------------------------------------------------------
def reader_ok_enabled?
return true
end
#--------------------------------------------------------------------------
# ○ 項目数の取得
#--------------------------------------------------------------------------
def reader_item_max
return @digits_max
end
#--------------------------------------------------------------------------
# ○ 項目を描画する矩形の取得
#--------------------------------------------------------------------------
def reader_item_rect(index)
return item_rect(index)
end
#--------------------------------------------------------------------------
# ○ カーソル位置の設定
#--------------------------------------------------------------------------
def writer_index=(index)
@index = index
end
#--------------------------------------------------------------------------
# ○ カーソル位置の取得
#--------------------------------------------------------------------------
def reader_index
return @index
end
end
#==============================================================================
# ■ Window_NameInput
#------------------------------------------------------------------------------
# 名前入力画面で、文字を選択するウィンドウです。
#==============================================================================
class Window_NameInput < Window_Selectable
#--------------------------------------------------------------------------
# ● 決定にジャンプ
#--------------------------------------------------------------------------
alias :__Mouse__process_jump :process_jump
def process_jump
__Mouse__process_jump
update_cursor
end
#--------------------------------------------------------------------------
# ○ 項目数の取得
#--------------------------------------------------------------------------
def reader_item_max
return 90
end
end
#==============================================================================
# ■ Window_SaveFile
#------------------------------------------------------------------------------
# セーブ画面およびロード画面で表示する、セーブファイルのウィンドウです。
#==============================================================================
class Window_SaveFile < Window_Base
#--------------------------------------------------------------------------
# ○ マウスカーソルが現在のカーソルの範囲内か判定
#--------------------------------------------------------------------------
def mouse_in_cursor?
return mouse_in_window?
end
end
#==============================================================================
# ■ Scene_File
#------------------------------------------------------------------------------
# セーブ画面とロード画面の共通処理を行うクラスです。
#==============================================================================
class Scene_File < Scene_MenuBase
#--------------------------------------------------------------------------
# ● 開始処理
#--------------------------------------------------------------------------
alias :__Mouse__start :start
def start
__Mouse__start
@observed_index = -1 # インデックスを監視
end
#--------------------------------------------------------------------------
# ● カーソルの更新
#--------------------------------------------------------------------------
alias :__Mouse__update_cursor :update_cursor
def update_cursor
last_index = @index
__Mouse__update_cursor
set_cursor_index_from_mouse if @index == last_index
end
#--------------------------------------------------------------------------
# ○ マウスカーソルを現在のカーソルの位置に設定
#--------------------------------------------------------------------------
def set_mouse_pos_from_cursor
@savefile_windows[@index].set_mouse_pos_from_cursor
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの位置からカーソル位置を設定
#--------------------------------------------------------------------------
def set_cursor_index_from_mouse
return false unless MouseCursor.in_game_screen?
return false unless MouseCursor.active
item_max.times do |i|
next unless @savefile_windows.mouse_in_window?
if @index != i
@savefile_windows[@index].selected = false
@index = i
@savefile_windows[@index].selected = true
Sound.play_cursor
Window.invalid_set_mouse_pos = true
end
return true
end
return false
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの更新
#--------------------------------------------------------------------------
def update_mouse_cursor
set_mouse_pos_from_cursor if @index != @observed_index
@observed_index = @index
super
end
end
#==============================================================================
# ■ Scene_Base
#------------------------------------------------------------------------------
# ゲーム中の全てのシーンのスーパークラスです。
#==============================================================================
class Scene_Base
#--------------------------------------------------------------------------
# ● フレーム更新(基本)
#--------------------------------------------------------------------------
alias :__Mouse__update_basic :update_basic
def update_basic
update_mouse_cursor # Graphics.update の直前で実行
MouseCursor.update
__Mouse__update_basic
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの更新
#--------------------------------------------------------------------------
def update_mouse_cursor
all_windows = Window.get_all_windows
set_windows = all_windows.select do |window|
window.observe_update
next window.set_mouse_pos?
end
unless set_windows.empty?
window = set_windows.find do |window|
next window.reader_ok_enabled? && window.active && window.open?
end
unless window
window = all_windows.find do |window|
next window.reader_ok_enabled? && window.active && window.open?
end
if window
window.reserve_set_mouse_pos = true
else
window = set_windows[0]
end
end
window.set_mouse_pos_from_cursor
end
all_windows.each {|window| window.post_observe_update }
Window.invalid_set_mouse_pos = false
Window.invalid_set_cursor_index = false
end
end
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ▲ 以上、マウスカーソルの処理に関する定義
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
[/pre]
|
|