VX 스크립트

입력 기능 확장 스크립트 추가. [전체키 스크립트]
게임제작에 도움을 주는 스크립트라고 생각되어 추가 하게되었습니다.

사용예
# 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
end

module 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)
#================================================= =============================


Comment '22'
  • profile
    아방스 2008.08.25 12:29

    다른분이 올리신자료도있던데...

    그건 기존에 키입력처리가 가능했던 버튼들...즉 방향키나 결정키 등등 을 조건분기 하는데 문제가 있다더군요.

    이건문제가 없는것 같아서 올립니다.

    기존에 문제가 된 스크립트주소를 아래
    http://avangs.info/zbxe/178901

  • ?
    읽어버린세계 2008.10.18 12:46
    이스크립트는 문제가없다는거네요.
    http://avangs.info/zbxe/178901 여기에는 문제가있고요.
  • profile
    ⌒_⌒ 2008.08.27 18:19

    ...!! 일본어도 있다. ㅎㅎ 아무튼 감사합니다. 아방스님~!

  • ?
    푸른★ 2008.09.02 21:50
    무슨말임????????????????????????????????
  • ?
    ★찜찜 2008.09.17 10:29
    제가 찾고 있던 거임. 감사해요~
  • ?
    야즈아엘 2008.09.27 08:17
    오 감사합니다,,,
  • ?
    읽어버린세계 2008.10.18 12:53
    키보드 방향키는 어떻게해야되나요?
    조건분기로 아래를 눌렀다 이런거 안되던데...
  • ?
    다크아머 2008.10.25 10:50
    VX는 스크립도 조건분기가 가능하구나!
  • ?
    흑기사 2008.11.16 16:49
    안되는데요
    조건분기 스크립트에 # Input.trigger?(Input::A_Z["A"])  써넣고
    그속에 문장의표시 안녕 이라고 넣으면 A를 아무리 눌러도 안녕이라는 문구가 안뜨는데요.
  • ?
    방콕족의생활 2008.12.10 18:55
    안녕하세요. 정말오랫만에 접속하네요.
    몇몇 분들의 혼동이 있을까봐 미리 답글달아드려요.
    맨위의 사용예

    # Input.trigger?(Input::F2)          # F2를 누르거나 (F2 ~ F11)
    # Input.trigger?(Input::NUM[0])      # 0을 누르거나 (0 ~ 9)
    # Input.trigger?(Input::A_Z["A"])    # A를 누르거나 (A ~ Z)
    하고 사진을 첨부해주셨는데요

    사진에 # Input.trigger?(Input::F2)  이렇게 실수하셧더라구요
    입력할 땐 #을 빼고 해야 실행됩니다.; -> Input.trigger?(Input::F2)
    또한 흑기사님이 질문하셧던 것도 #을 빼고 쓰면 정상작동됩니다.

  • profile
    아방스 2009.02.15 01:43
    아....

    #  잊었군
  • ?
    하얀모자 2009.10.22 10:56
    이것처럼하니까 게임시작할때 '이 메모리는"read"될수없습니다 계속하시려면 확인 디버그하시려면 취소를 눌러주세요. '라는 문구가 뜨는데요
  • ?
    Aakerse 2009.01.15 17:47
    잘쓸게요
  • ?
    하얀모자 2009.09.13 17:59

    맵 만들때 마다 넣어야 하나요?

  • ?
    078656577er 2009.10.22 15:43

    잘 되는 군요

  • ?
    알피쥐초보자 2010.01.11 16:23

    와~!이런신의스크립트가있었다니!!아방스님짱!!

  • profile
    ★☆legend game☆★ 2010.01.30 15:21

    짱조은 스크립

  • ?
    미스터Joker 2010.02.12 11:32

    근데 엔터는 못쓰는 건가요????

  • profile
    아방스 2012.07.09 23:58
    스크립트에 너무 의존 하지마세요~
    엔터키는 기본으로 지원하지 않나요? ^___^
  • ?
    질풍처럼 2010.08.24 00:35

    오예!!!!!!!!!!!!!!!

    감사하다풍.

  • ?
    광우병 멧돼지 2011.03.06 10:30

    감사합니다

  • ?
    최닉네임 2011.06.14 21:05

    11


List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
공지 스크립트 자료 게시물 작성시 주의사항 3 습작 2012.12.24 5408
537 키입력 Key Simulator by Fantasist 습작 2013.05.01 1176
536 메뉴 kgc 파라미터 배분 09/07/25 13 시트르산 2010.09.24 2327
535 메뉴 KGC - 커스텀 메뉴 커멘드 (번역) 1 듀란테 2015.07.27 1079
534 기타 KGC counter 스크립트. 반격기 추가스크립트입니다. 4 우켈킁 2011.03.31 1812
533 기타 KGC 리버스 데미지! 28 루시페르 2009.04.13 2979
532 미니맵 KGC 미니 맵 22 file RPGbooster 2008.10.08 4036
531 미니맵 KGC 미니맵 스크립트 (한글번역) 45 file 레오 2009.02.01 6555
530 기타 KGC 스크립트 라이브러리 7 훈덕 2009.05.31 2611
529 장비 KGC 확장 장비 화면 2009/02/15 13 시트르산 2010.09.25 3113
528 아이템 KGC]아이템 합성 29 file 찌나 2008.03.08 5123
527 전투 KGC]전투형태 오버드라이브(턴알) 13 찌나 2008.03.08 5656
526 그래픽 KGC_BitmapExtension : 비트맵 클래스 확장 8 file soleone 2010.07.18 3176
525 타이틀/게임오버 KGC_TitleDirection 알기쉽게 설명추가 5 파이어 2011.01.03 2662
524 장비 KGC장비종류 추가 스크립트. 36 file 루시페르 2009.03.28 4674
523 기타 KGC파라미터배분 2 (VX전용) 20 file 카르와푸딩의아틀리에 2009.07.21 3269
522 기타 KGC패시브 스크립트 30 카르와푸딩의아틀리에 2009.10.07 3551
521 장비 KGC확장장비창 스크립트 15 file 티라엘 2009.03.27 3622
520 HUD KH HUD (HP MP 게이지바 스크립트) 41 아방스 2010.12.17 6422
519 Khai's Window Helper 1.4 1 Man... 2008.10.28 1272
518 KID's Luck Systems(무슨 뜻?) 4 Man... 2008.10.27 1378
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 32 Next
/ 32