【NVL】鍵盤、搖桿控制筆記

  這篇是流水帳式的筆記,主要是來記錄修改程式使遊戲能支援鍵盤和搖桿操作的部分。因為我自己是主機遊戲愛好者,所以還是比較喜歡用搖桿玩遊戲,或是最少要有鍵盤可以按比較不會手痠XD

  其實KRKR本身就有內建支援鍵盤操作了,一般沒特別更改過操作的遊戲應該都還是能夠用空白鍵來進行對話,不過如果是NVL內有大量自製選單情況下,就要調整一些設定了。

  不過KRKR/NVL最主要還是以滑鼠操作最方便容易,鍵盤/搖桿頂多只能作為輔助,如果想要完全像主機遊戲那種操作模式,還是得靠自己寫相關的操作程式碼以及介面設計的配合才會更好。這邊修改後頂多讓玩家可以多一個操作方式,不能完全取代滑鼠。

  內容和程式碼不見得能適合所有遊戲,不過修改的概念還是可以作為參考,那麼筆記部分下收。


  KRKR基本上支援Windows的按鍵,可以到微軟官方文件查詢 Virtual Key Code(連結點此)

  裡面寫的「Constant」就是我們需要的東西了,旁邊都有描述可以判斷它是指哪顆鍵,比方說 VK_BACK 就是指 BACKSPACE key,也就是很常用的「←/倒退鍵」,所以在KRKR裡面,如果有需要使用這個鍵,在程式裡寫上 VK_BACK 就可以了。搖桿的部分則是 VK_PAD1 ~ VK_PAD10,搖桿對應的按鈕可能直接測試手邊的搖桿來看會更直接。(我手邊的羅技搖桿,後面有X和D模式,兩種設置起來不太一樣)

  要將鍵盤和搖桿的部分對應起來的話,可以更改以下的部分(以PS的搖桿操作方式為例):

[資料夾&檔案位置] THE_NVL_Maker\project\Project_name\Data\system\MainWindow.tjs

[function名稱] createPadKeyMap()

[修改內容] 搖桿按鈕對應的鍵盤按鈕

VK_PADLEFT => VK_LEFT,
VK_PADRIGHT => VK_RIGHT,
VK_PADUP => VK_UP,
VK_PADDOWN => VK_DOWN,
//搖桿的X,PS的□(對應歷史訊息)
VK_PAD1 =>
function(ev) {
showHistoryByKey(this);
},
//搖桿的A,PS的╳(對應取消鍵)
VK_PAD2 => VK_ESCAPE,
//搖桿的B,PS的○(對應確定鍵)
VK_PAD3 => VK_RETURN,
//搖桿的Y,PS的△(對應主選單)
VK_PAD4 => VK_BACK,

//前一頁 L1(目前僅作用於歷史選單)
VK_PAD5 => VK_PRIOR,
//下一頁 R1(目前僅作用於歷史選單)
VK_PAD6 => VK_NEXT,
//L2 AUTO(自動閱讀)
VK_PAD7 => VK_A,
//R2 SKIP(略過閱讀)
VK_PAD8 => VK_Q,
//搖桿BACK鍵 對應系統設定選單
VK_PAD9 => VK_O,
//搖桿的START鍵 對應存檔
VK_PAD10 => VK_S,

  搖桿對應鍵盤按鈕的部分設置完成後,就要將鍵盤按鈕對應的功能加上去了。


  先從確定/取消鍵開始,原本確定鍵僅支援ENTER(VK_RETURN)和SPACE(VK_SPACE),在此增加Z鍵(VK_Z)。而取消鍵只支援ESC(VK_ESCAPE),在此增加X鍵(VK_X)。作法可以利用Notepad++來按CTRL+SHIFT+F尋找專案資料夾/子資料夾,找出對應的關鍵字加上即可。


  另外在操作鍵盤/搖桿的時候,會預設把滑鼠指標隱藏,這邊就看個人需求調整了,我的話目前就先註解掉:

[資料夾&檔案位置] THE_NVL_Maker\project\work_SM\Data\system\MessageLayer.tjs

[function名稱] processClick()

[修改內容] 操作鍵盤時,將滑鼠指標隱藏(不想隱藏的話加入註解即可)

if (window.getKeyState(VK_RETURN) || window.getKeyState(VK_SPACE) || window.getKeyState(VK_CONTROL))
  //window.hideMouseCursor();


  接著是開啟Auto Mode、SKIP、主選單、存讀檔選單等按鈕。

[資料夾&檔案位置] THE_NVL_Maker\project\Project_name\Data\system\MainWindow.tjs

[function名稱] onPrimaryRightClick()

[修改內容] 修改進入AUTO MODE的鍵盤按鈕

function onPrimaryRightClick()

{

// プライマリレイヤで右クリックされたときに呼ばれる(改成A)

if(!callHook(rightClickHook))

{

if(getKeyState(VK_A))

{

enterAutoMode();

return;

}

if(!rightClickEnabled) return;

if(inStable)

{

if(rightClickJump)

jumpToRightClickTarget();

else if(rightClickCall && conductor == mainConductor)

callRightClickSubRoutine();

else

switchMessageLayerHiddenByUser();

}

setMenuAccessibleAll();

}

}

 

接著是其他指令,新增的有以下:

 

BACKSPACE:開啟主選單

Q:開啟SKIP模式

S/L:開啟存讀檔選單

O:開啟OPTION選單

I:開啟ITEM選單

 

[資料夾&檔案位置] THE_NVL_Maker\project\Project_name\Data\scenario\AfterInit.tjs內

[修改內容] 新增鍵盤指令

function myKeyDownHook(key, shift){

if(kag.inStable ==true ){

if(key == VK_BACK) //按下Backspace

{

//開啟主選單
kag.callExtraConductor(‘main_menu.ks’, ‘*start’);

return true;

}

if(key == VK_S) //按下S

{

//開啟存檔頁面
kag.callExtraConductor(‘save.ks’, ‘*start’);

return true;

}

if(key == VK_L) //按下L

{

//開啟讀檔頁面

kag.callExtraConductor(‘load.ks’, ‘*start’);

return true;

}

if(key == VK_O) //按下O

{

//開啟系統選項頁面
kag.callExtraConductor(‘option.ks’, ‘*start’);

return true;

}

if(key == VK_I) //按下I

{

//開啟道具頁面
kag.callExtraConductor(‘other.ks’, ‘*start’);

return true;

}

if(key == VK_H) //按下H

{

//開啟歷史頁面
kag.onShowHistoryMenuItemClick();

return true;

}

if(key == VK_Q) //按下 Q

{

 

//開啟SKIP模式
kag.onSkipToNextStopMenuItemClick();

return true;

}

}

}

 

  各個檔名依照實際內容修改即可,其中 kag.inStable 很重要,是用來讓對話還在顯示的時候不讓玩家按按鈕用的。要確保程式目前是穩定狀態才能按按鈕。開啟歷史頁面跟SKIP模式如法炮製就照上面那樣新增就大致不會有問題了。

  接著啟用這個函式,在最初的劇本(prelogue.ks)寫上下列程式碼即可:

[eval exp=”kag.keyDownHook.add(myKeyDownHook)”]


  比較需要再額外處理的是NVL/自製介面的部分(比方說道具介面、任務筆記介面),同樣在上面一樣的地方新增好程式碼之後,雖然還是能運作,但如果讓玩家在已經開啟選單的情況下又按下開啟選單的按鈕,會導致一些系統顯示上的問題所以要針對每個系統介面的檔案來調整:

  • main_menu.ks(主選單)
  • option.ks(系統設定)
  • load.ks(讀檔)
  • other.ks(道具介面)
  • save.ks(存檔)

 

在每個檔案的*start之後,寫上:

[eval exp=”kag.keyDownHook.remove(myKeyDownHook)”]

這樣就可以在介面中防止玩家再度按下快捷鍵而造成錯誤。

每個都寫好之後,最後在main_menu.ks中的*返回寫上以下內容即可:

[eval exp=”kag.keyDownHook.add(myKeyDownHook)”]


  最後就是PgUp、PgDn的設置,原本只有在歷史記錄有作用,現在要加入到存讀檔、道具介面讓它們也可以用來換頁。

[資料夾&檔案位置] THE_NVL_Maker\project\Project_name\Data\scenario\AfterInit.tjs內

[修改內容] 多新增一個函式來增加道具介面鍵盤換頁指令

[iscript]

function itemKeyDownHook(key, shift){
if(kag.inStable ==true ){
  if(key == VK_PRIOR) //按下PgUp
  {
   if (f.當前物品頁>1){
    f.當前物品頁–;
    dm(‘物品欄上一頁’);
    kag.callExtraConductor(‘other.ks’, ‘*刷新畫面’); //記得跳至other.ks(道具介面)的刷新畫面
   }
  }
  if(key == VK_NEXT) //按下PgUp
  {
   if (f.當前物品頁<f.物品總頁數){
    f.當前物品頁++;
    dm(‘物品欄下一頁’);
    kag.process(‘other.ks’, ‘*刷新畫面’);         //記得跳至other.ks(道具介面)的刷新畫面
   }
  }
 }
}

[endscript]

[修改內容]存讀檔適用的換頁操控

function SLKeyDownHook(key, shift){
  if(kag.inStable ==true ){
    if(key == VK_PRIOR) //按下PgUp
    {
      if (sf.最近存儲頁>1){
      sf.最近存儲頁– ;
      dm(‘存檔上一頁’);
      kag.callExtraConductor(‘save.ks’, ‘*刷新畫面’);
      }
    }
   if(key == VK_NEXT) //按下PgUp
   {
     if (sf.最近存儲頁<(kag.numBookMarks/f.config_slpos.locate.count))
     {
      sf.最近存儲頁++;
      dm(‘存檔下一頁’);
      kag.process(‘save.ks’, ‘*刷新畫面’);        
     }
   }
  }
}

  加入之後一樣在需要的地方使用對應的函式即可。

  〔道具介面〕

  〔存讀檔介面〕

  這樣就能用鍵盤搖桿控制存讀檔、道具頁面的上一頁/下一頁了。


  最後一個小地方調整,如果直接從標題畫面進入讀檔頁面後,讓玩家按下其他快捷鍵會出問題,所以要修改以下地方:

[資料夾&檔案位置] THE_NVL_Maker\project\Project_name\Data\system\MainWindow.tjs

[fuction名稱] restoreFlags()

[修改內容]

加入 kag.keyDownHook.remove(SLKeyDownHook); 即可!

完成!