#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ #_/ #_/ ■ 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 # :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[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 #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ #_/ #_/ ▲ 以上、マウスカーソルの処理に関する定義 #_/ #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/