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 5398
537 전투 전투 배경을 이미지로 설정하는 스크립트 20 file 아방스 2008.01.23 4889
536 메뉴 전투 결과 팝업 스크립트 12 file 카르와푸딩의아틀리에 2009.06.30 3381
535 메뉴 전투 결과 상세 표시 스크립트 (한글화) 15 file 강진수 2010.02.26 3344
534 파티 전에 아방스님이 올린 '파티 변경 시스템'을 한글화 했습니다. 17 file 아리엘 2008.09.16 3589
533 아이템 적과 만나지않는 아이템 12 file RPGbooster 2008.10.11 2718
532 기타 적 선택시 스킬창 비표시 + 타겟 플래쉬 7 훈덕 2009.06.14 2094
531 기타 장애물을 피하고 다가오게 하는 스크립트 5 file 박력남 2014.02.25 1877
530 이동 및 탈것 장소이동시 효과 없애기 10 file 허걱 2013.05.05 1960
529 장비 장비의 착용조건 설정 v1.0 27 file 까까까 2010.09.20 3740
528 장비 장비에 레벨제한 스크립트!! 21 ijsh515 2010.09.19 3040
527 장비 장비 확장 및 EP 기능 18 만들어보자꾸나 2008.06.10 3653
526 장비 장비 레벨 개념 추가 스크립트 14 아방스 2010.12.06 3275
525 기타 작은 게이지바 표시 스크립트 44 file 허걱 2009.02.05 5979
524 메뉴 자작 메뉴 스크립트 for VX(L's Simple Custom Menu VX ver.) 5 Alkaid 2010.09.02 4705
523 이동 및 탈것 자동 이동 시스템 20 file 허걱 2010.04.21 4303
» 키입력 입력 기능 확장 스크립트 추가. [전체키 스크립트] 22 아방스 2008.08.25 3772
521 메뉴 일본에서 만든 멋있는메뉴변경 스크립트 (한글 VX에서 쓰시면 자동으로 바뀜) 45 유칸지 2008.04.09 8861
520 기타 이벤트 제작용 소품 모음 스크립트 12 시트르산 2010.09.10 2209
519 기타 이벤트 위치 저장 스크립트 10 Tofuman 2008.12.11 2096
518 기타 이벤트 상세효과 9 file 사람이라면? 2010.08.15 2801
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