sacred-ritual-academy/Scripts/RGSS3_Script_UniversalMouse_.rb
2025-03-18 19:45:34 -05:00

2174 lines
No EOL
99 KiB
Ruby
Raw Permalink Blame History

This file contains invisible Unicode characters

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

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

#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ■ RGSS3 Script UniversalMouse - 汎用マウス操作 -
#_/----------------------------------------------------------------------------
#_/ 制 作 者 : CanariAlternate
#_/ 配 布 元 : カルトの鳥篭 (http://canarialt.blog.fc2.com)
#_/----------------------------------------------------------------------------
#_/ □ 概要 : マウスでゲームが出来るようにするスクリプトです。設定を弄る程度で
#_/ プリセット以外でもある程度は対応できるようにしたつもりです。
#_/ ※ マウス操作の設定には多少、スクリプトに関する知識を要します。
#_/
#_/ □ 必須 : CAMouse.dllをSystemフォルダに配置
#_/
#_/ □ 位置 : 「▼ 素材」より下
#_/----------------------------------------------------------------------------
#_/ 現在、確認している問題
#_/ 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 = 0
#
#----------------------------------------------------------------------------
# ▼ マウスカーソル用の画像の設定
#
# マウスカーソルの画像はここで設定した横幅×縦幅の画像を連ねたものを用意します。
# キャラクター画像等のように並べてもいいですし、ひたすら横に並べても大丈夫です。
#
# ◇ マウスカーソルの画像名(拡張子は含まない)
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
# マウスカーソル画像の先っぽの位置を設定する項目。
# 例えば、横幅32の画像の場合、0で左端、31で右端が先っぽになる。
#
# ◇ マウスカーソルの転送元原点の Y 座標(この値だけ上に移動した位置に表示)
MOUSE_CURSOR_OY = 18
# マウスカーソル画像の先っぽの位置を設定する項目。
# 例えば、縦幅32の画像の場合、0で上端、31で下端が先っぽになる。
#
# ◇ マウスカーソルのアニメーションパターンの配列(配列のサイズは 1 以上)
MOUSE_ANIME_PATTERN = [34, 35, 34, 33]
# 左から順番に番号に対応する画像が表示されます。
# 右端まで表示し終わったら左端に戻って再び左から順番に表示していきます。
# 番号は画像の左上が 0 で右に向かって 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()で処理し、結果が真の場合に有効。
#
# 左ボタン = 左マウスボタン。
#
# 右ボタン = 右マウスボタン。
#
# ホイール押 = マウスホイールボタン。
#
# ホイール↑ = マウスホイールの奥に回転させた場合。
#
# ホイール↓ = マウスホイールの手前に回転させた場合。
#
# 常時 = ここに設定したキーはマウスカーソルが表示中の間、キーが押され続けている判定になる。
# :MOVEでの使用を想定して実装したが使い勝手が悪かったので初期設定では使用していない。
#
# 表示 = マウスカーソルの表示・非表示・未定(true / false / nil)を設定します。
# 特定のウィンドウでマウスカーソルを非表示にしたい場合等に非表示を設定する。
#
# X1ボタン = マウスの拡張ボタン。
# ブラウザ等における「戻る」が割り当てられている場合が多い。
#
# X2ボタン = マウスの拡張ボタン。
# ブラウザ等における「次へ」が割り当てられている場合が多い。
#
OBSERVED_SUBJECT_WINDOW = [
# 優先度:低
# [ クラス名(シンボル) , 左ボタン, 右ボタン, ホイール押, ホイール↑, ホイール↓, 常時 , 表示 , X1ボタン, X2ボタン]
[:Scene_Base , false , false , false , false , false , false , false , false , false ], # 全てのシーンのベース
[:Scene_Map , :MOVE , :C , :B , :ALT , :ALT , false , true , :Y , :X ], # マップ画面
[:Scene_Battle , :C , :C , :C , :ALT , :ALT , false , true , :L , :R ], # バトル画面
# ["$game_switches[99]", :C , :B , :A , :LEFT , :RIGHT, false , true , :L , :R ], # スイッチ99番がONの時
[:Scene_Gameover , :C , :B , :A , false , false , false , true , :L , :R ], # ゲームオーバー画面
[:Window_Message , :C , :CTRL , :CTRL , :ALT , :SHIFT , 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 , :RIGHT ,:LEFT , 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 が押されると解除されます。
# ※ :A の固定状態は :DASH が入力に存在してる時のみです。
# 例えば、より優先度の高いメニューウィンドウなどがアクティブになり
# :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
# :F5F9 = ファンクションキー( 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[i] == 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[i]
symbol = convert_symbol(symbol, subject) if symbol
symbol = symbol[0] if @@invalid_smp[i] = symbol.kind_of?(Array)
if symbol != nil
@@input_mouse[i] = symbol
@@obs_subject[i] = 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[i].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
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ▲ 以上、マウスカーソルの処理に関する定義
#_/
#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/