确定按钮是否被单击的更好方法
Better way to determine if a button is clicked
我正在用 MonoGame 开发游戏,并决定创建自己的按钮 class。为了确定这些按钮是否被点击,我确定它们是否在按钮的范围内,以及鼠标左键是否按下。这导致了两个问题。
- 鼠标点击不需要在按钮内部开始,它会立即注册,而不是在释放鼠标按钮后(在按钮的边界内。)
- 当不同屏幕上的多个按钮位于同一区域时,由于鼠标按钮释放速度不够快,导致同时单击它们。
如何使点击行为更像 WinForm 按钮?
您可以使用 RoutedEvent
来调用元素树中多个侦听器的处理程序,而不仅仅是引发事件的对象。您可以阅读有关 RoutedEvents 的更多信息,因为 附加事件 的概念使您能够将特定事件的处理程序添加到任意元素,而不是实际定义或继承事件。当这些事件与元素无关时,例如 MouseDown
,既引发又监听事件。
所以 RoutedEvents 可能会帮助您解决问题
这是一个示例代码
public static readonly RoutedEvent SelectedEvent =
EventManager.RegisterRoutedEvent( "Selected", RoutingStrategy.Bubble,
typeof(RoutedEventHandler), typeof(MyCustomControl));
// .NET wrapper
public event RoutedEventHandler Selected
{
add { AddHandler(SelectedEvent, value); }
remove { RemoveHandler(SelectedEvent, value); }
}
// Raise the routed event "selected"
RaiseEvent(new RoutedEventArgs(MyCustomControl.SelectedEvent));
要使鼠标点击有效,您应该执行以下操作:
我们做的第一件事是创建一个 MouseInput class,这应该跟踪诸如 mouseState、lastMouseState、MouseX、MouseY 之类的东西。 mouseState 和 lastMouseState 共同处理 1 次单击。但现在您可以将此 class 添加到您的项目中:
class MouseInput
{
private static MouseState mouseState;
private static MouseState lastMouseState;
public static MouseState MouseState
{
get { return mouseState; }
set { mouseState = value; }
}
public static MouseState LastMouseState
{
get
{
return lastMouseState;
}
set
{
lastMouseState = value;
}
}
public MouseInput()
{
}
public static int getMouseX()
{
return Mouse.GetState().X;
}
public static int getMouseY()
{
return Mouse.GetState().Y;
}
}
完成后,您希望在每次执行更新方法时开始寻找鼠标点击:
MouseInput.LastMouseState = MouseInput.MouseState;
// Get the mouse state relevant for this frame
MouseInput.MouseState = Mouse.GetState();
完成这 2 个关键步骤后,您可以像这样继续并在任何地方使用您的代码:
if (MouseInput.LastMouseState.LeftButton == ButtonState.Released && MouseInput.MouseState.LeftButton == ButtonState.Pressed) {
//Execute code here
}
当然上面的if语句只检查玩家是否按下鼠标左键,你仍然需要检查鼠标位置是否在按钮内。
如有任何问题,欢迎随时提问
UI 适用于 XNA 4.0 like WinForms,从头开始编写。
创建表单并点击它,从 Game.Update() 方法调用 Form.Update()。
在 Game.Draw() 中首先调用 Form.Refresh(),然后 Form.Draw()。
为了处理鼠标和键盘输入,使用了 GameHelper.Input 库中的管理器。
我正在用 MonoGame 开发游戏,并决定创建自己的按钮 class。为了确定这些按钮是否被点击,我确定它们是否在按钮的范围内,以及鼠标左键是否按下。这导致了两个问题。
- 鼠标点击不需要在按钮内部开始,它会立即注册,而不是在释放鼠标按钮后(在按钮的边界内。)
- 当不同屏幕上的多个按钮位于同一区域时,由于鼠标按钮释放速度不够快,导致同时单击它们。
如何使点击行为更像 WinForm 按钮?
您可以使用 RoutedEvent
来调用元素树中多个侦听器的处理程序,而不仅仅是引发事件的对象。您可以阅读有关 RoutedEvents 的更多信息,因为 附加事件 的概念使您能够将特定事件的处理程序添加到任意元素,而不是实际定义或继承事件。当这些事件与元素无关时,例如 MouseDown
,既引发又监听事件。
所以 RoutedEvents 可能会帮助您解决问题
这是一个示例代码
public static readonly RoutedEvent SelectedEvent =
EventManager.RegisterRoutedEvent( "Selected", RoutingStrategy.Bubble,
typeof(RoutedEventHandler), typeof(MyCustomControl));
// .NET wrapper
public event RoutedEventHandler Selected
{
add { AddHandler(SelectedEvent, value); }
remove { RemoveHandler(SelectedEvent, value); }
}
// Raise the routed event "selected"
RaiseEvent(new RoutedEventArgs(MyCustomControl.SelectedEvent));
要使鼠标点击有效,您应该执行以下操作:
我们做的第一件事是创建一个 MouseInput class,这应该跟踪诸如 mouseState、lastMouseState、MouseX、MouseY 之类的东西。 mouseState 和 lastMouseState 共同处理 1 次单击。但现在您可以将此 class 添加到您的项目中:
class MouseInput
{
private static MouseState mouseState;
private static MouseState lastMouseState;
public static MouseState MouseState
{
get { return mouseState; }
set { mouseState = value; }
}
public static MouseState LastMouseState
{
get
{
return lastMouseState;
}
set
{
lastMouseState = value;
}
}
public MouseInput()
{
}
public static int getMouseX()
{
return Mouse.GetState().X;
}
public static int getMouseY()
{
return Mouse.GetState().Y;
}
}
完成后,您希望在每次执行更新方法时开始寻找鼠标点击:
MouseInput.LastMouseState = MouseInput.MouseState;
// Get the mouse state relevant for this frame
MouseInput.MouseState = Mouse.GetState();
完成这 2 个关键步骤后,您可以像这样继续并在任何地方使用您的代码:
if (MouseInput.LastMouseState.LeftButton == ButtonState.Released && MouseInput.MouseState.LeftButton == ButtonState.Pressed) {
//Execute code here
}
当然上面的if语句只检查玩家是否按下鼠标左键,你仍然需要检查鼠标位置是否在按钮内。
如有任何问题,欢迎随时提问
UI 适用于 XNA 4.0 like WinForms,从头开始编写。
创建表单并点击它,从 Game.Update() 方法调用 Form.Update()。 在 Game.Draw() 中首先调用 Form.Refresh(),然后 Form.Draw()。
为了处理鼠标和键盘输入,使用了 GameHelper.Input 库中的管理器。