「模组:制作指南/APIs/Input」修訂間的差異

出自Stardew Valley Wiki
跳至導覽 跳至搜尋
(翻译部分内容)
 
(未顯示同一使用者於中間所作的 1 次修訂)
行 30: 行 30:
 
| up
 
| up
 
| up
 
| up
| <samp> </samp>
+
| <samp>None</samp>
 
|-
 
|-
 
| up
 
| up
 
| down
 
| down
| <samp> 按下</samp>
+
| <samp>Pressed</samp>
 
|-
 
|-
 
| down
 
| down
 
| down
 
| down
| <samp> 按住</samp>
+
| <samp>Held</samp>
 
|-
 
|-
 
| down
 
| down
 
| up
 
| up
| <samp> 松开</samp>
+
| <samp>Released</samp>
 
|}
 
|}
 
</dd>
 
</dd>
行 89: 行 89:
 
 副作用:
 
 副作用:
 
<ul>
 
<ul>
<li>The [[Modding:Modder Guide/APIs/Events#Input.ButtonReleased|<samp>ButtonReleased</samp> event]] will be raised on the next tick for the suppressed input.</li>
+
<li>[[Modding:Modder Guide/APIs/Events#Input.ButtonReleased|<samp>ButtonReleased</samp> 事件]] 会在输入被抑制后的下一个 tick 触发。</li>
<li>Methods like <samp>helper.Input.IsDown(button)</samp> and <samp>helper.Input.GetState(button)</samp> will show the button as released for the duration of the suppression, even if it's physically still pressed. You can use <samp>helper.Input.IsSuppressed(button)</samp> to check if that's the case (it will only be true until the button is physically released):
+
<li> 在按键被抑制期间,类似 <samp>helper.Input.IsDown(button)</samp> <samp>helper.Input.GetState(button)</samp> 的方法会表明按键的状态是 released ,即使该按键在现实中处于被按下的状态。你可以使用 <samp>helper.Input.IsSuppressed(button)</samp> 来检查按键是否处于这种情况(它会一直返回 true 直到按键在现实中被松开):
 
<syntaxhighlight lang="c#">
 
<syntaxhighlight lang="c#">
 
bool isPhysicallyDown = helper.Input.IsDown(button) || helper.Input.IsSuppressed(button);
 
bool isPhysicallyDown = helper.Input.IsDown(button) || helper.Input.IsSuppressed(button);
行 96: 行 96:
 
</ul>
 
</ul>
  
==Data structures==
+
== 数据结构==
 
===SButton===
 
===SButton===
SMAPI's <samp>SButton</samp> is a constant which includes every [https://docs.microsoft.com/en-us/previous-versions/windows/xna/bb975202(v%3dxnagamestudio.40) controller], [https://docs.microsoft.com/en-us/previous-versions/windows/xna/bb197781(v%3dxnagamestudio.40) keyboard], and [https://docs.microsoft.com/en-us/previous-versions/windows/xna/bb198097(v%3dxnagamestudio.40) mouse] button. SMAPI events use this to let you handle button presses without needing separate code for each. See [[Modding:Player Guide/Key Bindings]] for a list of values.
+
SMAPI <samp>SButton</samp> 是一个涵盖了每种[https://docs.microsoft.com/en-us/previous-versions/windows/xna/bb975202(v%3dxnagamestudio.40) 控制器], [https://docs.microsoft.com/en-us/previous-versions/windows/xna/bb197781(v%3dxnagamestudio.40) 键盘] [https://docs.microsoft.com/en-us/previous-versions/windows/xna/bb198097(v%3dxnagamestudio.40) 鼠标] 的按键的常量。SMAPI 事件使用此常量,这允许你处理按键按下时不需要区分每种按键的代码。阅读 [[Modding:Player Guide/Key Bindings]] 来获取值列表。
  
SMAPI provides extensions to convert any of the other constants to <samp>SButton</samp>:
+
SMAPI 提供了把任意其他常量转换为 <samp>SButton</samp> 的扩展:
 
<syntaxhighlight lang="c#">
 
<syntaxhighlight lang="c#">
 
SButton key = Keys.A.ToSButton(); // SButton.A
 
SButton key = Keys.A.ToSButton(); // SButton.A
行 107: 行 107:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
You can also convert <samp>SButton</samp> to the other constants. This uses a <samp>TryGet</samp> approach since <samp>SButton</samp> is a superset of the others (''e.g.,'' you can't convert <samp>SButton.ControllerA</samp> to a keyboard value):
+
你也可以将 <samp>SButton</samp> 转换为其他常量。这将使用到 <samp>TryGet</samp> 的途径,因为 <samp>SButton</samp> 是其他常量的一个超集(比方说,你不能把 <samp>SButton.ControllerA</samp> 转换成一个 keyboard 值):
 
<syntaxhighlight lang="c#">
 
<syntaxhighlight lang="c#">
 
SButton value = SButton.A;
 
SButton value = SButton.A;
行 118: 行 118:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Two last extensions let you check how the button is mapped in the game:
+
最后两个扩展帮助你检查按键在游戏中如何布局:
 
<syntaxhighlight lang="c#">
 
<syntaxhighlight lang="c#">
 
SButton button = SButton.MouseLeft;
 
SButton button = SButton.MouseLeft;
 
if (button.IsUseToolButton())
 
if (button.IsUseToolButton())
   // use tool
+
   // 使用工具
 
else if (button.IsActionButton())
 
else if (button.IsActionButton())
   // perform action
+
   // 执行动作
 
</syntaxhighlight>
 
</syntaxhighlight>
  
You can use <samp>SButton</samp> values directly in your [[../Config|config model]], but <samp>[[#KeybindList|KeybindList]]</samp> is recommended instead in most cases.
+
你可以在[[../Config|config model]] 中直接使用 <samp>SButton</samp> 的值,但是大部分情况下推荐使用 <samp>[[#KeybindList|KeybindList]]</samp>
  
 
===KeybindList===
 
===KeybindList===
行 212: 行 212:
 
'''The pixel positions are ''not'' adjusted for [[Modding:Modder Guide/Game Fundamentals#UI scaling|UI scaling]]''' (''i.e.,'' they're non-UI mode). Whether you need UI or non-UI positions depends how you're using them, so you can use <samp>cursorPos.GetScaledAbsolutePixels()</samp> or <samp>cursorPos.GetScaledScreenPixels()</samp> to adjust them automatically for the current mode or <samp>Utility.ModifyCoordinatesForUIScale</samp> to always get UI mode coordinates.
 
'''The pixel positions are ''not'' adjusted for [[Modding:Modder Guide/Game Fundamentals#UI scaling|UI scaling]]''' (''i.e.,'' they're non-UI mode). Whether you need UI or non-UI positions depends how you're using them, so you can use <samp>cursorPos.GetScaledAbsolutePixels()</samp> or <samp>cursorPos.GetScaledScreenPixels()</samp> to adjust them automatically for the current mode or <samp>Utility.ModifyCoordinatesForUIScale</samp> to always get UI mode coordinates.
  
==See also==
+
== 另见==
 
* [[../Events#Input|Input events]]
 
* [[../Events#Input|Input events]]
* [[Modding:Player Guide/Key Bindings]] for a list of valid <samp>SButton</samp> values
+
* [[Modding:Player Guide/Key Bindings]] 中有一个可用的 <samp>SButton</samp> 值列表
  
 
[[en:Modding:Modder Guide/APIs/Input]]
 
[[en:Modding:Modder Guide/APIs/Input]]

於 2024年7月4日 (四) 14:50 的最新修訂

製作SMAPI模組 SMAPI mascot.png


模組:目錄

輸入 API 允許您檢查和抑制控制器/鍵盤/滑鼠狀態。

APIs

檢查按鍵狀態

IsDown
您可以通過調用 IsDown(button) 方法來檢查當前是否按下了任何控制器/鍵盤/滑鼠按鈕。 例如:
bool isShiftPressed = this.Helper.Input.IsDown(SButton.LeftShift) || this.Helper.Input.IsDown(SButton.RightShift);
GetState
要進行更精細的控制,您可以檢查相對於上一次遊戲 tick 的按鍵狀態:
SButtonState state = this.Helper.Input.GetState(SButton.LeftShift);
bool isDown = (state == SButtonState.Pressed || state == SButtonState.Held);

可用的按鍵狀態:

上一次 tick 當前 tick 最終狀態
up up None
up down Pressed
down down Held
down up Released
Robin building.png
“我這裡還有很多事情需要處理。”
— 羅賓

不完整的翻譯

本文或部分尚未完全翻譯成中文。 歡迎您通過編輯幫助其建設。
最後編輯Breadog0731於2024-07-04 14:50:14.

檢查光標位置

GetCursorPosition() 方法提供了三種坐標體系下的光標位置

例如:

// 在光标位置绘制文本
ICursorPosition cursorPos = this.Helper.Input.GetCursorPosition();
Game1.spriteBatch.DrawString(Game1.smallFont, "some text", cursorPos.ScreenPixels, Color.Black);

抑制輸入

你可以通過抑制輸入來阻止遊戲對控制器/鍵盤/滑鼠的響應。這種抑制會在玩家鬆開按鍵前持續生效。這種抑制不會阻止其他mod對輸入的處理。

方法 效果
Suppress 抑制給定的 SButton 值。
SuppressActiveKeybinds 對於給定的KeybindList,抑制其中的每個按鍵輸入。
IsSuppressed 檢查給定的 SButton 值是否正在受到抑制。

例如:

// 使游戏忽略LeftShift按键的动作
this.Helper.Input.Suppress(SButton.LeftShift);

// 鼠标单击也可以被抑制
this.Helper.Input.Suppress(SButton.MouseLeft);

// 检查某个按键是否被抑制
bool suppressed = this.Helper.Input.IsSuppressed(SButton.LeftShift);

副作用:

  • ButtonReleased 事件 會在輸入被抑制後的下一個 tick 觸發。
  • 在按鍵被抑制期間,類似 helper.Input.IsDown(button)helper.Input.GetState(button) 的方法會表明按鍵的狀態是 released,即使該按鍵在現實中處於被按下的狀態。你可以使用 helper.Input.IsSuppressed(button) 來檢查按鍵是否處於這種情況(它會一直返回 true 直到按鍵在現實中被鬆開):
    bool isPhysicallyDown = helper.Input.IsDown(button) || helper.Input.IsSuppressed(button);
    

數據結構

SButton

SMAPI 的 SButton 是一個涵蓋了每種控制器, 鍵盤滑鼠的按鍵的常量。SMAPI 事件使用此常量,這允許你處理按鍵按下時不需要區分每種按鍵的代碼。閱讀 Modding:Player Guide/Key Bindings 來獲取值列表。

SMAPI 提供了把任意其他常量轉換為 SButton 的擴展:

SButton key = Keys.A.ToSButton(); // SButton.A
SButton button = Buttons.A.ToSButton(); // SButton.ControllerA
SButton input = new InputButton(true).ToSButton(); // SButton.MouseLeft

你也可以將 SButton 轉換為其他常量。這將使用到 TryGet 的途徑,因為 SButton 是其他常量的一個超集(比方說,你不能把 SButton.ControllerA 轉換成一個 keyboard 值):

SButton value = SButton.A;
if (value.TryGetKeyboard(out Keys key))
   ...;
if (value.TryGetController(out Buttons button))
   ...;
if (value.TryGetStardewInput(out InputButton input))
   ...;

最後兩個擴展幫助你檢查按鍵在遊戲中如何布局:

SButton button = SButton.MouseLeft;
if (button.IsUseToolButton())
   // 使用工具
else if (button.IsActionButton())
   // 执行动作

你可以在config model中直接使用 SButton 的值,但是大部分情況下推薦使用 KeybindList

KeybindList

SMAPI's KeybindList utility lets you manage an arbitrary set of keybindings. A keybind list has any number of keybinds, each of which has any number of button codes. For example, the keybind list "F2, LeftShift + S" would be pressed if (a) F2 is pressed, or (b) both LeftShift and S are pressed.

You can use a KeybindList directly in your config.json model:

C# model   JSON file
class ModConfig
{
   public KeybindList ToggleKey { get; set; } = KeybindList.Parse("LeftShift + F2");
}
{
   "ToggleKey": "LeftShift + F2"
}

And you can then check whether it's pressed directly in your code. For example, in a ButtonsChanged event handler:

private void OnButtonsChanged(object sender, ButtonsChangedEventArgs e)
{
   if (this.Config.ToggleKey.JustPressed())
   {
      // perform desired action
   }
}

The KeybindList provides a number of methods depending on your use case:

member description
KeybindList.Parse(…)
KeybindList.TryParse(…)
Parse a keybind string like "F2, LeftShift + S" into a keybind list.
IsBound Whether the keybind list has any keys bound. For example, this would be false for the strings "None" or "".
Keybinds The individual keybinds. In most cases you shouldn't use these directly.
GetState() Get the overall keybind state relative to the previous tick. This state is transitive across keybinds; e.g., if the player releases one keybind and immediately presses another within the list, the overall state is Held.
IsDown() Get whether any keybind in the list is currently down (i.e., the player pressed or is holding down the keys).
JustPressed() Get whether the player just activated the keybind during the current tick (i.e., GetState() returns Pressed instead of Held).
GetKeybindCurrentlyDown() Get the individual Keybind in the list which is currently down, if any. If there are multiple keybinds down, the first one is returned.
ToString() Get a string representation of the input binding (e.g., "F2, LeftShift + S").

Caveats:

  • Don't use the ButtonPressed event to check keybinds, since it's raised once for each button pressed. If the player presses two keys at once, your keybind would be activated twice. Use ButtonsChanged instead.

ICursorPosition

SMAPI's ICursorPosition provides the cursor position in four coordinate systems:

  • AbsolutePixels is the pixel position relative to the top-left corner of the in-game map, adjusted for zoom but not UI scaling.
  • ScreenPixels is the pixel position relative to the top-left corner of the visible screen, adjusted for zoom but not UI scaling.
  • Tile is the tile position under the cursor.
  • GrabTile is the tile position that the game considers under the cursor for the purposes of clicking actions. This automatically accounts for controller mode. This may be different than Tile if that's too far from the player.

This is returned by the this.Helper.Input.GetCursorPosition() method and in the event args for some input events.

The pixel positions are not adjusted for UI scaling (i.e., they're non-UI mode). Whether you need UI or non-UI positions depends how you're using them, so you can use cursorPos.GetScaledAbsolutePixels() or cursorPos.GetScaledScreenPixels() to adjust them automatically for the current mode or Utility.ModifyCoordinatesForUIScale to always get UI mode coordinates.

另見