SMAPI
提供了一些事件,比如游戏的内容、显示、输入等事件。这些事件可以让我们在游戏中添加自己的逻辑。这一节我们就来看看如何使用这些事件。
在SMAPI
中,我们可以通过IModHelper
的Events
属性来注册事件。比如我们要注册游戏启动事件,可以这样写:
public override void Entry(IModHelper helper)
{
helper.Events.GameLoop.GameLaunched += OnLaunched;
}
private void OnLaunched(object? sender, GameLaunchedEventArgs e)
{
}
这样我们就注册了一个游戏启动事件。当游戏启动时,OnLaunched
方法就会被调用,它有两个参数,第一个是事件的发送者,它是一个可空的对象,第二个是事件的参数,它是一个GameLaunchedEventArgs
对象。这个对象里面没有任何属性,只是一个空的类。
先来看一下按键按下或释放的事件。
public override void Entry(IModHelper helper)
{
helper.Events.Input.ButtonPressed += OnPress;
}
private void OnPress(object? sender, ButtonPressedEventArgs e)
{
Monitor.Log($"{e.Button} Press", LogLevel.Debug);
}
这样我们就注册了一个按键按下事件。当按键按下时,OnPress
方法就会被调用,它有两个参数,第一个是事件的发送者,它是一个可空的对象,第二个是事件的参数,它是一个ButtonPressedEventArgs
对象。这个对象有一个属性Button
,它是一个SButton
枚举,表示按下的按键。
public override void Entry(IModHelper helper)
{
helper.Events.Input.ButtonReleased += OnReleased;
}
private void OnReleased(object? sender, ButtonReleasedEventArgs e)
{
Monitor.Log($"{e.Button} Released", LogLevel.Debug);
}
这样我们就注册了一个按键释放事件。当按键释放时,OnReleased
方法就会被调用,它有两个参数,第一个是事件的发送者,它是一个可空的对象,第二个是事件的参数,它是一个ButtonReleasedEventArgs
对象。这个对象有一个属性Button
,它是一个SButton
枚举,表示释放的按键。
上面这些按键事件只能获取一个按键,如果要获取多个按键,可以使用ButtonsChanged
事件。
public override void Entry(IModHelper helper)
{
helper.Events.Input.ButtonsChanged += OnChanged;
}
private void OnChanged(object? sender, ButtonsChangedEventArgs e)
{
if (e.Pressed.Any())
{
Monitor.Log($"{string.Join(",", e.Pressed)} Press", LogLevel.Debug);
}
if (e.Released.Any())
{
Monitor.Log($"{string.Join(",", e.Released)} Released", LogLevel.Debug);
}
}
当事件被触发时,Pressed
属性表示按下的按键,Released
属性表示释放的按键,之后我们判断按键是否为空,如果不为空,就输出按键。
我们还可以使用KeyBindList
来判断这些按键是否被按下。
private void OnChanged(object? sender, ButtonsChangedEventArgs e)
{
var keyBindList = KeybindList.Parse("LeftControl + A");
if (keyBindList.JustPressed())
{
Monitor.Log("Keybind Just Pressed", LogLevel.Debug);
}
}
这样就可以判断LeftControl
和A
是否被按下。
SMAPI
还提供了一些显示事件,比如MenuChanged
事件,在游戏中所有和菜单有关的事件都会触发这个事件。
public override void Entry(IModHelper helper)
{
helper.Events.Display.MenuChanged += OnMenuChanged;
}
private void OnMenuChanged(object? sender, MenuChangedEventArgs e)
{
Monitor.Log($"{e.OldMenu} -> {e.NewMenu}", LogLevel.Debug);
}
比如我们打开背包,就会是一个空的菜单到StardewValley.Menus.GameMenu
,这样就会输出 -> StardewValley.Menus.GameMenu
,关闭背包就会输出StardewValley.Menus.GameMenu ->
。
显示事件中其他的一些事件都和游戏的图形绘制有关,这里就不多介绍了。
public override void Entry(IModHelper helper)
{
helper.Events.Content.AssetRequested += OnAssetRequested;
}
private void OnAssetRequested(object? sender, AssetRequestedEventArgs e)
{
Monitor.Log(e.Name.Name, LogLevel.Debug);
}
当游戏加载一个资源时,就会触发这个事件。
好了,上面介绍了部分事件,其他事件可以参考SMAPI
的文档。