創作內容

3 GP

[RM RGSS] (從MV移植的)全按鍵 (最後更新:170424)

作者:未来ずら│2016-04-06 04:25:07│巴幣:6│人氣:734
2017/04/13:加了鍵值數組,減少update運算量
2017/04/21:補充數組缺乏的鍵值,新增update2、set_update_keys
2017/04/24:刪除一些通常鍵盤沒有的鍵值




直接把MV預設腳本照搬過來的全按鍵,官方腳本品質保證(?),XP~VA適用


因為我個人是用6R的全按鍵,然後其實有個問題,
判斷 trigger 的時候如果是同方法內連續用到好幾次"同按鍵"判斷,第二次以後會變false:
Kboard.trigger?(13) # true
Kboard.trigger?(13) # false
Kboard.trigger?(13) # false
.
.
.(直到放開再按下前永遠是false)

這對做指令多的遊戲有不小的麻煩
(用變數先儲存判定也是個辦法,不過我寫的時候還沒想到(爆)

以下腳本內容,複製貼上即可:

#==============================================================================
# ■ 全按鍵
#------------------------------------------------------------------------------
=begin
1.按著:
  Kboard.press?(鍵碼)

2.按一下:
  Kboard.trigger?(鍵碼)

3.按住一段時間:
  Kboard.repeat?(鍵碼)

例:
  Kboard.press?(13)  # 按著Enter鍵
  Kboard.trigger?(Kboard::R_Key_C)  # 按一下C鍵


4.指定要更新的按鍵:
  Kboard.set_update_keys(要更新的按鍵)
例:
  Kboard.set_update_keys([13,67,88]) # 只更新Enter、C、X鍵狀態
  Kboard.set_update_keys             # 還原預設值
  
=end
#==============================================================================
module Kboard
  module_function
  # 從6R全按鍵和MSDN來的鍵值表
  Keys = [
    Rmouse_BUTTON_L = 0x01,        # left mouse button
    Rmouse_BUTTON_R = 0x02,       # right mouse button
    Rmouse_BUTTON_M = 0x04,        # middle mouse button
    Rmouse_BUTTON_4 = 0x05,        # 4th mouse button
    Rmouse_BUTTON_5 = 0x06,        # 5th mouse button
    #--------------------------------------------------------------------------
    R_Key_BACK      = 0x08,        # BACKSPACE key
    R_Key_TAB       = 0x09,        # TAB key
    R_Key_RETURN    = 0x0D,        # ENTER key
    R_Key_SHIFT     = 0x10,        # SHIFT key
    R_Key_CTLR      = 0x11,        # CTLR key
    R_Key_ALT       = 0x12,        # ALT key
    R_Key_PAUSE     = 0x13,        # PAUSE key
    R_Key_CAPITAL   = 0x14,        # CAPS LOCK key
    R_Key_ESCAPE    = 0x1B,        # ESC key
    R_Key_SPACE     = 0x20,        # SPACEBAR
    R_Key_PRIOR     = 0x21,        # PAGE UP key
    R_Key_NEXT      = 0x22,        # PAGE DOWN key
    R_Key_END       = 0x23,        # END key
    R_Key_HOME      = 0x24,        # HOME key
    R_Key_LEFT      = 0x25,        # LEFT ARROW key
    R_Key_UP        = 0x26,        # UP ARROW key
    R_Key_RIGHT     = 0x27,        # RIGHT ARROW key
    R_Key_DOWN      = 0x28,        # DOWN ARROW key
    R_Key_SELECT    = 0x29,        # SELECT key
    R_Key_PRINT     = 0x2A,        # PRINT key
    R_Key_SNAPSHOT  = 0x2C,        # PRINT SCREEN key
    R_Key_INSERT    = 0x2D,        # INS key
    R_Key_DELETE    = 0x2E,        # DEL key
    #--------------------------------------------------------------------------
    R_Key_0         = 0x30,        # 0 key
    R_Key_1         = 0x31,        # 1 key
    R_Key_2         = 0x32,        # 2 key
    R_Key_3         = 0x33,        # 3 key
    R_Key_4         = 0x34,        # 4 key
    R_Key_5         = 0x35,        # 5 key
    R_Key_6         = 0x36,        # 6 key
    R_Key_7         = 0x37,        # 7 key
    R_Key_8         = 0x38,        # 8 key
    R_Key_9         = 0x39,        # 9 key
    #--------------------------------------------------------------------------
    R_Key_A         = 0x41,        # A key
    R_Key_B         = 0x42,        # B key
    R_Key_C         = 0x43,        # C key
    R_Key_D         = 0x44,        # D key
    R_Key_E         = 0x45,        # E key
    R_Key_F         = 0x46,        # F key
    R_Key_G         = 0x47,        # G key
    R_Key_H         = 0x48,        # H key
    R_Key_I         = 0x49,        # I key
    R_Key_J         = 0x4A,        # J key
    R_Key_K         = 0x4B,        # K key
    R_Key_L         = 0x4C,        # L key
    R_Key_M         = 0x4D,        # M key
    R_Key_N         = 0x4E,        # N key
    R_Key_O         = 0x4F,        # O key
    R_Key_P         = 0x50,        # P key
    R_Key_Q         = 0x51,        # Q key
    R_Key_R         = 0x52,        # R key
    R_Key_S         = 0x53,        # S key
    R_Key_T         = 0x54,        # T key
    R_Key_U         = 0x55,        # U key
    R_Key_V         = 0x56,        # V key
    R_Key_W         = 0x57,        # W key
    R_Key_X         = 0x58,        # X key
    R_Key_Y         = 0x59,        # Y key
    R_Key_Z         = 0x5A,        # Z key
    #--------------------------------------------------------------------------
    R_Key_LWIN      = 0x5B,        # Left Windows key (Microsoft Natural keyboard)
    R_Key_RWIN      = 0x5C,        # Right Windows key (Natural keyboard)
    R_Key_APPS      = 0x5D,        # Applications key (Natural keyboard)
    #--------------------------------------------------------------------------
    R_Key_NUMPAD0   = 0x60,        # Numeric keypad 0 key
    R_Key_NUMPAD1   = 0x61,        # Numeric keypad 1 key
    R_Key_NUMPAD2   = 0x62,        # Numeric keypad 2 key
    R_Key_NUMPAD3   = 0x63,        # Numeric keypad 3 key
    R_Key_NUMPAD4   = 0x64,        # Numeric keypad 4 key
    R_Key_NUMPAD5   = 0x65,        # Numeric keypad 5 key
    R_Key_NUMPAD6   = 0x66,        # Numeric keypad 6 key
    R_Key_NUMPAD7   = 0x67,        # Numeric keypad 7 key
    R_Key_NUMPAD8   = 0x68,        # Numeric keypad 8 key
    R_Key_NUMPAD9  = 0x69,        # Numeric keypad 9 key
    R_Key_MULTIPLY  = 0x6A,        # Multiply key (*)
    R_Key_ADD       = 0x6B,        # Add key (+)
    R_Key_SEPARATOR = 0x6C,        # Separator key
    R_Key_SUBTRACT  = 0x6D,        # Subtract key (-)
    R_Key_DECIMAL   = 0x6E,        # Decimal key
    R_Key_DIVIDE    = 0x6F,        # Divide key (/)
    #--------------------------------------------------------------------------
    R_Key_F1        = 0x70,        # F1 key
    R_Key_F2        = 0x71,        # F2 key
    R_Key_F3        = 0x72,        # F3 key
    R_Key_F4        = 0x73,        # F4 key
    R_Key_F5        = 0x74,        # F5 key
    R_Key_F6        = 0x75,        # F6 key
    R_Key_F7        = 0x76,        # F7 key
    R_Key_F8        = 0x77,        # F8 key
    R_Key_F9        = 0x78,        # F9 key
    R_Key_F10       = 0x79,        # F10 key
    R_Key_F11       = 0x7A,        # F11 key
    R_Key_F12       = 0x7B,        # F12 key
    #--------------------------------------------------------------------------
    R_Key_NUMLOCK   = 0x90,        # NUM LOCK key
    R_Key_SCROLL    = 0x91,        # SCROLL LOCK key
    #--------------------------------------------------------------------------
    R_Key_LSHIFT    = 0xA0,        # Left SHIFT key
    R_Key_RSHIFT    = 0xA1,        # Right SHIFT key
    R_Key_LCONTROL  = 0xA2,        # Left CONTROL key
    R_Key_RCONTROL  = 0xA3,        # Right CONTROL key
    R_Key_L_ALT    = 0xA4,        # Left ALT key
    R_Key_R_ALT    = 0xA5,        # Right ALT key
    #--------------------------------------------------------------------------
    R_Key_SEP      = 0xBC,        # , key
    R_Key_DASH      = 0xBD,        # - key
    R_Key_DOTT      = 0xBE        # . Key

    R_Key_OEM_1 = 0xBA,          #  :; key
    R_Key_OEM_PLUS = 0xBB,       #  + key
    R_Key_OEM_2 = 0xBF,          #  /? key
    R_Key_OEM_3 = 0xC0,          #  `~ key
    R_Key_OEM_4 = 0xDB,          #  [{ key
    R_Key_OEM_5 = 0xDC,          #  \| key
    R_Key_OEM_6 = 0xDD,          #  ]} key
    R_Key_OEM_7 = 0xDE,          #  '和"  key

  ]
  #--------------------------------------------------------------------------
  # ● 常量
  #--------------------------------------------------------------------------
  GetKeyState = Win32API.new("user32","GetAsyncKeyState",['I'],'I')
  KeyStates = Array.new(256, 0).pack('c*') # 調用↓需要256 byte的數組
  GetAllKeyState = Win32API.new("user32","GetKeyboardState",'p','I')
  KeyRepeatWait = 20  # 長按時,第一次等待時間
  KeyRepeatInterval = 6  # 長按時,第二次以後的等待時間
  #--------------------------------------------------------------------------
  # ● 初始化
  #--------------------------------------------------------------------------
  @currentState = {}
  @previousState = {}
  @latestButton = nil
  @pressedTime = 0
  @update_keys = Keys
  @use_update2 = true
  #--------------------------------------------------------------------------
  # ● 指定要更新的按鍵,省資源
  #    keys:(數組)要更新的按鍵
  #--------------------------------------------------------------------------
  def set_update_keys(keys=nil)
    @update_keys = keys ? keys : Keys
    # 要更新的按鍵數超過20時,update效率輸update2
    @use_update2 = @update_keys.size > 20
  end
  #--------------------------------------------------------------------------
  # ● 定期更新(每個鍵使用 GetAsyncKeyState 做比較)
  #--------------------------------------------------------------------------
  def update
    if @use_update2
      update2
    else
      for key in @update_keys
        if GetKeyState.call(key) & 0x8000 == 0
          @currentState[key] = false
        else
          @currentState[key] = true
        end
      end
      
      if @currentState[@latestButton]
        @pressedTime += 1
      else
        @latestButton = nil
      end

      for key in @currentState.keys
        if (@currentState[key] && !@previousState[key])
            # 記憶最後按鍵(trigger判斷用)
            @latestButton = key
            @pressedTime = 0
        end
        @previousState[key] = @currentState[key]
      end
      # updateDirection
    end
  end
  #--------------------------------------------------------------------------
  # ● 定期更新  ver2 (使用 GetKeyboardState 取得全按鍵狀態再比較)
  #--------------------------------------------------------------------------
  def update2
    array = GetAllKeyState.call(KeyStates)
    state = KeyStates.unpack('c*')
    for key in @update_keys
      if (state[key] & 0x0080) == 0
        @currentState[key] = false
      else
        @currentState[key] = true
      end
    end

    if @currentState[@latestButton]
      @pressedTime += 1
    else
      @latestButton = nil
    end
    for key in @currentState.keys
      if (@currentState[key] && !@previousState[key])
    # 記憶最後按鍵(trigger判斷用)
          @latestButton = key
          @pressedTime = 0
      end
      @previousState[key] = @currentState[key]
    end
end
  #--------------------------------------------------------------------------
  # ● 按了
  #--------------------------------------------------------------------------
def press?(rkey)
   return @currentState[rkey]
end
  #--------------------------------------------------------------------------
  # ● 按下
  #--------------------------------------------------------------------------
def trigger?(rkey)
   return (@latestButton == rkey && @pressedTime == 0)
end
  #--------------------------------------------------------------------------
  # ● 按住
  #--------------------------------------------------------------------------
  def repeat?(rkey)
    return (@latestButton == rkey &&
            (@pressedTime == 0 ||
            (@pressedTime >= KeyRepeatWait && @pressedTime % KeyRepeatInterval == 0)))
  end
end

  #--------------------------------------------------------------------------
  # ● 定期更新
  #--------------------------------------------------------------------------
class << Input
  alias :allkey_update :update unless method_defined?("allkey_update")
  def update
     allkey_update
     Kboard.update
  end
end


使用法

依照情況使用下列條件分歧:

按下(瞬間):
Kboard.trigger?(鍵值)

按著:
Kboard.press?(鍵值)

長按:
Kboard.repeat?(鍵值)


例--按下Enter:
Kboard.trigger?(13)



鍵值表就自行google,或是用腳本附的鍵值,例:
Kboard.press?(Kboard::R_Key_Z)



4/21新增:
Kboard.set_update_keys(要更新的按鍵數組)

指定一個鍵值數組,以後只更新這些按鍵的狀態,例:
Kboard.set_update_keys([13,67,88])   # 只更新Enter、C、X鍵狀態
Kboard.set_update_keys                     # 還原預設值






引用網址:https://home.gamer.com.tw/TrackBack.php?sn=3151536
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:RM|RGSS

留言共 4 篇留言

尼哭哭
想..想問一下..
我用 Kboard.trigger?(:C) 完全沒反應欸..
但也沒跳出錯誤
我有貼了上面提到的"全按鍵腳本" 並在其後面幾行的地方貼上"方法2" @@"

07-31 11:01

未来ずら
不啊,鍵值是數字。像Enter是13、C是67這樣。
google圖片找鍵值表就有一大堆對照圖了07-31 15:59
尼哭哭
原來如此 XDDD" 感謝

07-31 16:13

REI
請問若要禁用ALT按鍵,這個腳本該如何修改?

11-13 00:05

未来ずら
額,是說暫時禁用嗎,在你的ALT判斷追加一些條件,像:

if Kboard.trigger?(18) && !$game_switches[20]
(內容)
end

這樣 20 號開關打開時就會禁用11-13 15:04
REI
你好,我是爬文看到PROJECT1那裏有人說透過全鍵盤腳本,來禁用ALT,進而能讓ALT+ENTER的全螢幕組合鍵失效,因為自己的作品不適用這種方式切換,正在尋找方法中

11-15 13:33

未来ずら
查了一下似乎要用別的API去擋,這個我也不會,不好意思11-15 15:17
我要留言提醒:您尚未登入,請先登入再留言

3喜歡★qootm2 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:[RMMV] 1.1.0... 後一篇:[RMVA RGSS] ...

追蹤私訊切換新版閱覽

作品資料夾

Charles021來此小屋參觀的觀眾
白封作者回歸,新篇小說上線,有興趣的觀眾歡迎來看(被學務主任喜歡的壞學生)的最新章節,最新頁數看更多我要大聲說昨天07:09


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】