게임제작에 도움을 주는 스크립트라고 생각되어 추가 하게되었습니다.
사용예
# Input.trigger?(Input::F2) # F2를 누르거나 (F2 ~ F11)
# Input.trigger?(Input::NUM[0]) # 0을 누르거나 (0 ~ 9)
# Input.trigger?(Input::A_Z["A"]) # A를 누르거나 (A ~ Z)
조건 분기에서 아래와 같이 사용가능
위와 같이 사용할경우 F2번 키를 눌렀을대를 검사하여 조건분기를 실행할수 있다.
#================================================= =============================
# ★ 입력 기능 확장 var 1.0 (07.11.12) by shun
#------------------------------------------------- -----------------------------
# 주로 Input 모듈을 확장합니다. (확장의 내용은 하단의 사이트 참조)
# 이렇게하면 사용 키를 늘려 마우스 통한 입력 수있습니다.
#================================================= =============================
# 사용 예
# Input.trigger?(Input::F2) # F2를 누르거나 (F2 ~ F11)
# Input.trigger?(Input::NUM[0]) # 0을 누르거나 (0 ~ 9)
# Input.trigger?(Input::A_Z["A"]) # A를 누르거나 (A ~ Z)
#================================================= =============================
# ■ API
#------------------------------------------------- -----------------------------
# Win32API 대한 모듈입니다.
#================================================= =============================module API
#--------------------------------------------------------------------------
# ● 定数
#--------------------------------------------------------------------------
INI_FILE = '.Game.ini' # 使用する ini ファイルのパス
#--------------------------------------------------------------------------
# ● モジュール変数
#--------------------------------------------------------------------------
# Win32API の関数を取得
@@screen_to_client =
Win32API.new('user32', 'ScreenToClient', ['l', 'p'], 'i')
#--------------------------------------------------------------------------
# 以降、モジュール関数として定義
#--------------------------------------------------------------------------
module_function
#--------------------------------------------------------------------------
# ● ini ファイルの情報を取得
# sec : セクション名
# key : キーワード名
# default : 取得に失敗した際に返す文字列
# size : 情報バッファのサイズ (取得する文字数の上限)
#--------------------------------------------------------------------------
def read_ini(sec, key, default = "", size = 0xfff)
# GetPrivateProfileStringA を取得していないなら取得
unless defined?(@@get_private_profile_string)
ary = ['p', 'p', 'p', 'p', 'l', 'p']
@@get_private_profile_string =
Win32API.new('kernel32', 'GetPrivateProfileStringA', ary, 'l')
end
# 情報バッファにヌル文字 (文字コード 0) を設定
buffer = 0.chr
# GetPrivateProfileStringA をコール
@@get_private_profile_string.call(sec, key, default, buffer, size, INI_FILE)
return buffer
end
#--------------------------------------------------------------------------
# ● ゲームのタイトルを取得
#--------------------------------------------------------------------------
def get_title
# 既に取得されている場合
return @@title if defined?(@@title) and not @@title == ""
# ini ファイルを読み込む
@@title = read_ini("Game", "Title")
return @@title
end
#--------------------------------------------------------------------------
# ● ウィンドウハンドルを取得
#--------------------------------------------------------------------------
def get_hwnd
# 既に取得されている場合
return @@hwnd if defined?(@@hwnd) and not @@hwnd == 0
# FindWindowA を取得・コール
find_window = Win32API.new('user32', 'FindWindowA', ['p', 'p'], 'l')
@@hwnd = find_window.call('RGSS Player', get_title)
return @@hwnd
end
#--------------------------------------------------------------------------
# ● スクリーン座標をクライアント座標に変換
# pos : スクリーン座標が格納 (パック) されている POINT 構造体
#--------------------------------------------------------------------------
def to_client(pos)
# 処理に時間がかかると強制終了してしまうので、
# 別のスレッドで ScreenToClient をコールして結果を取得する
@result = 0
Thread.new(9) {@result = @@screen_to_client.call(get_hwnd, pos)}.join
# エラーの場合
if @result == 0
return nil, nil
else
# 変換されたクライアント座標をアンパック
return pos.unpack('ll')
end
end
#--------------------------------------------------------------------------
# ● クライアント座標をスクリーン座標に変換
# pos : クライアント座標が格納 (パック) されている POINT 構造体
#--------------------------------------------------------------------------
def to_screen(pos)
# ClientToScreenA を取得していないなら取得
unless defined?(@@client_to_screen)
@@client_to_screen =
Win32API.new('user32', 'ClientToScreenA', ['l', 'p'], 'i')
end
# エラーの場合
if @@client_to_screen.call(get_hwnd, pos) == 0
return nil, nil
else
# 変換されたスクリーン座標をアンパック
return pos.unpack('ll')
end
end
end
#==============================================================================
# ■ Graphics (追加定義)
#------------------------------------------------------------------------------
# グラフィック全体にかかわる処理を行うモジュールです。
#==============================================================================module Graphics
#--------------------------------------------------------------------------
# ○ マウスカーソルの表示設定
# visible : カーソルの可視状態 (真のとき可視)
#--------------------------------------------------------------------------
def self.cursor_visible=(visible)
# ShowCursor を取得していないなら取得
unless defined?(@@show_cursor)
@@show_cursor = Win32API.new('user32', 'ShowCursor', 'l', 'l')
end
# ShowCursor をコールして、表示カウントを設定
count = (visible ? 1 : 0)
@@show_cursor.call(count)
end
end
#==============================================================================
# ■ Input (追加定義)
#------------------------------------------------------------------------------
# ゲームパッドやキーボードからの入力情報を扱うモジュールです。
#==============================================================================#------------------------------------------------------------------------------
# ○ Input モジュール関数のエイリアス
#------------------------------------------------------------------------------
# F12 による再起動対策
# (ゲーム停止のための例外が発生させられ、その位置の情報が $@ に代入される)
unless $@
class << Input
# キー入力判定メソッド (既存のキーの場合、呼び戻す)
alias :__orig_press? :press?
alias :__orig_trigger? :trigger?
alias :__orig_repeat? :repeat?
# フレーム更新を拡張する
alias :__orig_update :update
end
endmodule Input
#--------------------------------------------------------------------------
# ● 定数
#--------------------------------------------------------------------------
F2 = 90 # F2 キーに対応する番号
F3 = 91 # F3 キーに対応する番号
F4 = 92 # F4 キーに対応する番号
F10 = 98 # F11 キーに対応する番号
F11 = 99 # F11 キーに対応する番号
# 数字キー (0..9) 対応する番号の配列
NUM = [100, 101, 102, 103, 104, 105, 106, 107, 108, 109]
# A キーから Z キーまでに対応する番号のハッシュ
A_Z = {
"A" => 110, "B" => 111, "C" => 112, "D" => 113, "E" => 114,
"F" => 115, "G" => 116, "H" => 117, "I" => 118, "J" => 119,
"K" => 120, "L" => 121, "M" => 122, "N" => 123, "O" => 124,
"P" => 125, "Q" => 126, "R" => 127, "S" => 128, "T" => 129,
"U" => 130, "V" => 131, "W" => 132, "X" => 133, "Y" => 134, "Z" => 135
}
# クリックに対応する番号のハッシュ
CLICK = {"L" => 136, "R" => 137, "M" => 139}
# 仮想キーコードの配列
# [F1キー, 0キー, A キー, 左クリック]
VK = [0x70, 0x30, 0x41, 0x01]
#--------------------------------------------------------------------------
# ○ モジュール変数
#--------------------------------------------------------------------------
# Win32API の関数を取得
@@get_keystate = Win32API.new('user32', 'GetAsyncKeyState', 'i', 'i')
@@get_cursor_pos = Win32API.new('user32', 'GetCursorPos', 'p', 'i')
# キーの押下フレーム数のハッシュ (仮想キーコード => フレーム数)
@@press_count = {}
#--------------------------------------------------------------------------
# 以降、モジュール関数として定義
#--------------------------------------------------------------------------
module_function
#--------------------------------------------------------------------------
# ○ 仮想キーコードを取得
# num : キーに対応する番号
#--------------------------------------------------------------------------
def vkey(num)
case num
when 89..99 # ファンクションキー (F2..F4, F10, F11)
return VK[0] + num - 89
when 100..109 # 数字キー
return VK[1] + num - 100
when 110..135 # A から Z キー
return VK[2] + num - 110
when 136..139 # クリック
return VK[3] + num - 136
end
end
#--------------------------------------------------------------------------
# ○ キーの押下状態を取得
# vk_code : 仮想キーコード
#--------------------------------------------------------------------------
def key_state(vk_code)
# GetAsyncKeyState をコール
state = @@get_keystate.call(vk_code)
# 現在押されているまたは前回の取得以降に押された場合、真を返す
return (state.abs == 0x8000 or state.abs == 0x8001)
end
#--------------------------------------------------------------------------
# ● 押下判定
# num :キーに対応する番号
#--------------------------------------------------------------------------
def press?(num)
# 既存のキーの場合、呼び戻す
return __orig_press?(num) if num < 85
vk = vkey(num)
# 既に押されているか確認できない場合
if @@press_count[vk].nil?
# キーの押下状態を取得
if key_state(vk)
@@press_count[vk] = 0
return true
else
return false
end
# 既に押されている場合、真を返す
else
return true
end
end
#--------------------------------------------------------------------------
# ● 新規押下判定
# num :キーに対応する番号
#--------------------------------------------------------------------------
def trigger?(num)
# 既存のキーの場合、呼び戻す
return __orig_trigger?(num) if num < 85
# 直前に押されていないかどうかを取得
count = @@press_count[vkey(num)]
# 既に新規で押されていることが確認された場合、真を返す
return true if count == 0
# それ以外で直前に押されておらず現在押されている場合、真を返す
return (count.nil? and press?(num))
end
#--------------------------------------------------------------------------
# ● 新規押下判定 (リピートを含む)
# num :キーに対応する番号
#--------------------------------------------------------------------------
def repeat?(num)
# 既存のキーの場合、呼び戻す
return __orig_repeat?(num) if num < 85
# 新たに押された場合、真を返す
return true if trigger?(num)
# 既に押されていることが確認できない場合、偽を返す
count = @@press_count[vkey(num)]
return false if count.nil?
# リピート判定を行う
return (count >= 15 and (count - 15) % 4 == 0)
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの座標を取得
# anywhere : ウィンドウ外でも、座標を返す
#--------------------------------------------------------------------------
def cursor_pos(anywhere=true)
# 格納する POINT 構造体を定義
pos = [0, 0].pack('ll')
# エラーの場合
if @@get_cursor_pos.call(pos) == 0
return nil, nil
else
# ウィンドウ内でない場合
if not anywhere and
not ((0..640).include?(pos[0]) and (0..480).include?(pos[1]))
return nil, nil
end
# スクリーン座標をクライアント座標に修正して返す
return API.to_client(pos)
end
end
#--------------------------------------------------------------------------
# ○ マウスカーソルの座標を設定
# coord : 座標の配列 [X 座標, Y 座標]
#--------------------------------------------------------------------------
def cursor_pos=(coord)
# スクリーン座標に変換
x, y = API.to_screen(coord.pack('ll'))
# 座標が無効なら、中断
return unless x.is_a?(Integer) and y.is_a?(Integer)
# SetCursorPosA を取得していないなら取得
unless defined?(@@set_cursor_pos)
@@set_cursor_pos =
Win32API.new('user32', 'SetCursorPosA', ['i', 'i'], 'i')
end
@@set_cursor_pos.call(x, y)
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
# 呼び戻す
__orig_update
# マウス入力の押下フレーム数を更新
@@press_count.each {|vk, count|
next if count.nil?
@@press_count[vk] = (key_state(vk) ? count + 1 : nil)
}
end
end
#==============================================================================
# □ Sprite_MouseCursor
#------------------------------------------------------------------------------
# マウスカーソル表示用のスプライトです。Input モジュールによりマウスカーソル
# の座標を監視し、スプライトの状態を自動的に変化させます。
#==============================================================================class Sprite_MouseCursor < Sprite
#--------------------------------------------------------------------------
# ● クラス変数
#--------------------------------------------------------------------------
# 使用不可能なグラフィックファイル名の配列
@@unavailable_file = []
#--------------------------------------------------------------------------
# ● オブジェクト初期化
# filename : カーソルグラフィック (ピクチャ) のファイル名
#--------------------------------------------------------------------------
def initialize(filename = "")
super()
@cursor_name = [filename, filename + "_cl"]
self.bitmap = RPG::Cache.picture(filename)
self.z = 10001
update
end
#--------------------------------------------------------------------------
# ● 解放
#--------------------------------------------------------------------------
def dispose
self.bitmap.dispose
super
end
#--------------------------------------------------------------------------
# ● グラフィックを変更
# filename : カーソルグラフィック (ピクチャ) のファイル名
#--------------------------------------------------------------------------
def cursor_name=(filename)
# 変更が無い場合
return if @filename == filename
@filename = filename
# ファイルが存在しないなどで、読み込めない場合を考慮
begin
return if @@unavailable_file.include?(filename)
self.bitmap = RPG::Cache.picture(filename)
rescue
@@unavailable_file.push(filename)
end
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
super
# 左クリックが押されている場合、画像を変更
num = (Input.press?(Input::CLICK["L"]) ? 1 : 0)
self.cursor_name = @cursor_name[num]
# カーソルの座標を取得
x, y = Input.cursor_pos(false)
# 座標が無効でなければ、スプライトの座標を更新
self.x, self.y = x, y unless x.nil? or y.nil?
end
end#================================================= =============================
# ★ 정보
#------------------------------------------------- -----------------------------
# 제작
# shun
# HP : Simp (http://simp.u-abel.net)
#================================================= =============================