Help - Search - Members - Calendar
Full Version: ~Simple Input Script~
RPG RPG Revolution Forums > Scripting > Script Tutorials > RGSS2
YanXie
Simple Input Script
Version Version 1.0
Author Shun
Release Date Unknown

Introduction


I've seen a few topic asking about Input script,like using usual keyboard for calling menu,etc.So I decide to post this here.


Features


Enable the usage of keyboard key ranged from A~Z, 0~9, F2, F3, F4, F10 and F11 and also mouse support(Left click,Middle Click and Right Click).

Unfortunately,the script doesn't have ability for complete mouse system(no mouse_cursor sprite,etc)


Script


[Show/Hide] Simple Input Script
CODE
#==============================================================================
# ★ 入力機能拡張 var 1.0 (07.11.12)  by shun
#
#------------------------------------------------------------------------------
#   主に Input モジュールなどを拡張します。 (拡張の内容は最下部のサイトを参照)
# これにより使用キーを増やし、マウスによる入力も可能になります。
#==============================================================================

#==============================================================================
# ■ 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('RGSS2 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  # F10 キーに対応する番号
  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 = Bitmap.new(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)
#==============================================================================


Or download the script here:

Click to view attachment


How To Use


Like most of you know,the normal Input module only include:

QUOTE
DOWN LEFT RIGHT UP
Numbers corresponding to the directions down, left, right, and up.

A B C X Y Z L R
Numbers corresponding to the various controller buttons.

SHIFT CTRL ALT
Numbers directly corresponding to the keyboard's SHIFT, CTRL, and ALT keys.

F5 F6 F7 F8 F9
Numbers corresponding to the keyboard's function keys. The other function keys are reserved by the system and cannot be obtained.


And usually,the input code used is like this :

CODE
Input::C


So to use the script,do like this example :

CODE
Input.trigger?(Input::F2)          # Input for key F2  (F2~F11)
Input.trigger?(Input::NUM[0])      # Input for key 0 (0~9)
Input.trigger?(Input::A_Z["A"])    # Input for key A (A~Z)
Input.trigger?(Input::CLICK["L"])  # For mouse input
# Note: ("L")Left Click ("M") Middle Click ("R") Right Click




Compatibility


Unknown,but it is fully compatible with VX

Screen shot


Not needed

DEMO


Not needed

Installation


Just copy the script and paste it under material section.

FAQ


None yet.

Terms and Conditions


Credit to Shun for the script.
icecold49
Aww, yes. Finally an input script. I was getting tired of the pre-set controls. I'm not a good enough scripter to change them myself so this script is very useful for me. Thank you.

Edit: I'm a little confused about this script because of the japenese. Can you tell me exactly where to change the game controls?
SojaBird
I'm not realy getting what it does...?
What can I do with it?
Can I bind menu's to key or something?????/

Explain some more pls
YanXie
...lawl,ok

First,take a look at this code,which is taken from default Scene_Menu line 73 :

CODE
#--------------------------------------------------------------------------
# * Update Command Selection
#--------------------------------------------------------------------------
def update_command_selection
if Input.trigger?(Input::B)
Sound.play_cancel
$scene = Scene_Map.new
elsif Input.trigger?(Input::C)
if $game_party.members.size == 0 and @command_window.index < 4
Sound.play_buzzer
return
elsif $game_system.save_disabled and @command_window.index == 4
Sound.play_buzzer
return
end
Sound.play_decision
case @command_window.index
when 0 # Item
$scene = Scene_Item.new
when 1,2,3 # Skill, equipment, status
start_actor_selection
when 4 # Save
$scene = Scene_File.new(true, false, false)
when 5 # End Game
$scene = Scene_End.new
end
end
end


And now,compare it to this :

CODE
#--------------------------------------------------------------------------
# * Update Command Selection
#--------------------------------------------------------------------------
def update_command_selection
if Input.trigger?(Input::A_Z["T"])
Sound.play_cancel
$scene = Scene_Map.new
elsif Input.trigger?(Input::A_Z["Y"])
if $game_party.members.size == 0 and @command_window.index < 4
Sound.play_buzzer
return
elsif $game_system.save_disabled and @command_window.index == 4
Sound.play_buzzer
return
end
Sound.play_decision
case @command_window.index
when 0 # Item
$scene = Scene_Item.new
when 1,2,3 # Skill, equipment, status
start_actor_selection
when 4 # Save
$scene = Scene_File.new(true, false, false)
when 5 # End Game
$scene = Scene_End.new
end
end
end


Usually you will use default key,which on keyboard :

1.Input::B is key X
2.Input::C is key Z

Ok,

When you change to the "Input::B" to "Input::A_Z["T"]" and "Input ::C" to "Input::A_Z["Y"]",instead of using key X and Z,you'll need to press T and Y in the menu screen.

I can't explain anymore if any of you still didn't understand.


(╬ ಠ益ಠ)

cheers,puppeto4. :(
Daray
It works, i can define in every scene a key or a mouse click. But i didnt understand the Feature:

CODE
Feature

Input Module mainly to the expansion of the keys to growth and mouse input possible.
Written comment also politely as possible, so please try to take advantage.
The main features listed below.
For details, see Methods per comment please.

Example #
# Key acquisition
Input.trigger? (Input:: F2) # F2 is pressed (F2 or F11)
Input.trigger? (Input:: NUM [0]) is pressed or 0 # (0 to 9)
Input.trigger? (Input:: A_Z [ "A"]) is pressed or # A (A to Z)
Input.trigger? (Input:: CLICK [ "L"]) # clicked or
Left # ( "L") wheel ( "M") right ( "R") click

# Windows mouse cursor to completely erase
# Own cursor in the game when setting recommended
Graphics.cursor_visible = false

# Create MAUSUSUPURAITO
Picture shows up as a cursor to #
# Click when the filename + "_cl" If you say, I switch
# (For example, cursor01 => cursor01_cl
Mouse_sprite Sprite_MouseCursor.new = @ ( "cursor01")
Mouse_sprite.cursor_name @ = "cursor02" # Change graphics


Ini file contents #
# [Game field, reads data Title
# By default, only exist [Game]
API.read_ini ( "Game", "Title")


Did this mean i can define a mouse cursor to show and use or i am wrong?
SojaBird
nvm
Bo0pi
=[

i dont get it.
jens009
QUOTE (Bo0pi @ Aug 2 2008, 08:26 AM) *
=[
i dont get it.

It's a scripter's tool. You don't have to get it.

Simply put, instead of being limited to a small sets of keys in your keyboard, you are now able to code RGSS with input commands using the WHOLE keyboard.
It's really useful if you want to make a script that uses multiple keys.
Heck, you can even use this in events when you are coding for an event based ABS.

Bo0pi
QUOTE (jens009 @ Aug 3 2008, 06:59 AM) *
QUOTE (Bo0pi @ Aug 2 2008, 08:26 AM) *
=[
i dont get it.

It's a scripter's tool. You don't have to get it.

Simply put, instead of being limited to a small sets of keys in your keyboard, you are now able to code RGSS with input commands using the WHOLE keyboard.
It's really useful if you want to make a script that uses multiple keys.
Heck, you can even use this in events when you are coding for an event based ABS.


lol i mean do i paste it above main?

and where do i change the buttons so i can use them for whatever?

and whenever i CB it doesnt work for some halfass of a reason.
Twilight27
Sorry if this is considered reviving the topic, but...
With this script, will it be possible for me to 'link' a common event to an input button?

Example...a common event that increases your level by one once activated, linked to input button "T"; Will I be able to press "T" and increase my level by one?

Anyway, I'll like to know if this is possible and how?
Thanks! n_n
Omegas7
I didn't understand what was the command for checking if the player pressed the button CONTROL or SHIFT...
killerrin
QUOTE (Omegas7 @ Oct 11 2008, 09:22 PM) *
I didn't understand what was the command for checking if the player pressed the button CONTROL or SHIFT...

Can i use this to add more items like an event for horse minimap and more? cause i preaty much used all of the pre set controlls and i dont want to override say my horse or my minimap on/off and others

jens009
QUOTE (killerrin @ Jan 5 2009, 03:04 PM) *
QUOTE (Omegas7 @ Oct 11 2008, 09:22 PM) *
I didn't understand what was the command for checking if the player pressed the button CONTROL or SHIFT...

Can i use this to add more items like an event for horse minimap and more? cause i preaty much used all of the pre set controlls and i dont want to override say my horse or my minimap on/off and others

Yes. With this script, you have the whole keyboard to play around with.
Just follow the instructions.
(Set Call Script as conditional branch)
omegazion
Was this script originally for RMXP ?

because i saw this line at the Input.repeat? method
CODE
(count >= 15 and (count - 15) % 4 == 0)


I have tested it before and the refresh count before the second true return to Input.repeat? in RMVX is 23 frames pressed, not 15, as with this script, and as with RMXP. and the next preceding is 6 frames not 4.

Is this maybe supposedly
CODE
(count >= 23 and (count - 23) % 6 == 0)

?

And is it ok for the author if i include this on the release of my scripts? Proper credits to where it is due still. (Just asking)
killerrin
i need some help see i evented a cheat system i tested it with the Built in button controlls and it worked...
but when i move it over to use it with lets say "C" it doesnt work i tried both
Input.trigger?(Input::A_Z["C"]
and
Input::C
and
Input.trigger?(Input::A_Z["c"])
any help plz?
Bandito
I know this is necroposting, but I just have to say that thanks to this script I am able to make my own ABS on vx without using the all so complicated for me scripts. The script is also easy to understand thanks to your instructions, thanks man.
Pyro21
Are you able to set keys to conditional branches in events?

For example, if I want text to appear or a picture to appear when the C key on my keyboard is pressed, would I be able to make an event which goes:

conditional branch: When C is pressed
yadda yadda

Because I am not so good at scripting...so even if someone told me how to do this, I wouldn't get it. All I need to know is if I can use a conditional branch to detect key input.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2013 Invision Power Services, Inc.