SDL C++鼠标输入处理切换效果

  • 本文关键字:处理 C++ 鼠标 SDL c++ sdl
  • 更新时间 :
  • 英文 :


所以我正在做一个塔防游戏。我需要选择一个用户单击鼠标的磁贴(现在我只是在磁贴周围画一个边框(。现在我的代码有时可以工作,但我不确定如何让它更好地工作。 现在,当我单击某个区域时,使用我拥有的代码,磁贴被选中,有时它会立即取消选择,有时不会。几乎就像我按住鼠标一样,它只是不停地"点击"鼠标。我需要的是让它选择磁贴而不取消选择它,无论按下鼠标按钮多长时间。我的鼠标输入类是这样设置的:

鼠标输入.h

#pragma once
#include <SDL.h>
class MouseInput
{
public:
MouseInput();
~MouseInput();
void Update();
bool GetMouseButton(int index);
SDL_Event GetEvent();
bool GetPressed();
bool GetReleased();
private:
void GetButtonStates();
private:
bool mouseArray[3];
int x, y;
bool justReleased;
bool justPressed;
SDL_Event e;
};

鼠标输入.cpp

#include "Input.h"
MouseInput::MouseInput()
:
x(0),
y(0),
justReleased(false),
justPressed(false)
{
SDL_PumpEvents();
for (int i = 0; i < 3; i++)
{
mouseArray[i] = false;
}
}
MouseInput::~MouseInput()
{
}
void MouseInput::Update()
{
SDL_PollEvent(&e);
justReleased = false;
justPressed = false;
if (e.type == SDL_MOUSEBUTTONDOWN && e.button.button == SDL_BUTTON_LEFT)
justPressed = true;
else if (e.type == SDL_MOUSEBUTTONUP && e.button.button == SDL_BUTTON_LEFT)
justReleased = true;
}
bool MouseInput::GetPressed()
{
return justPressed;
}
bool MouseInput::GetReleased()
{
return justReleased;
}
bool MouseInput::GetMouseButton(int index)
{
if (index <= 3 && index >= 1)
{
return mouseArray[index - 1];
}
return false;
}
SDL_Event MouseInput::GetEvent()
{
return e;
}
void MouseInput::GetButtonStates()
{
SDL_PollEvent(&e);
if (e.type == SDL_MOUSEBUTTONDOWN)
{
// 1 = Left; 2 = Center; 3 = Right
mouseArray[e.button.button - 1] = true;
}
if (e.type == SDL_MOUSEBUTTONUP)
{
mouseArray[e.button.button - 1] = false;
}
}

在我的游戏类中,我已经设置了鼠标输入以及一个变量来存储单击的磁贴的坐标。我还有一个可变pressed来检查鼠标是否被按下。在我的更新功能中,我检查是否未按下鼠标。如果没有按下鼠标,那么我会检查鼠标是否被按下,这样游戏就可以获得鼠标位置的坐标。我知道这听起来很疯狂,所以这是我的一些代码:

std::pair<int, int> coords; // Will store the coordinates of the tile position that the mouse rests in
bool pressed; // If the mouse was pressed (i should call it toggle because it's true if the mouse was pressed once, then false if the mouse was pressed again, then true...ect.)

更新功能

鼠标类

bool clicked; // In my custom Mouse.h file and set to false in constructor
MouseInput input; // In my custom Mouse.h file

鼠标类更新((

input.Update(); // Calls the MouseInput updating
if (input.GetPressed() && !clicked)
{
clicked = !clicked;
printf("OK");
}
//else if (clicked && input.GetReleased())
else if (clicked && input.GetPressed()) // Somewhat works. It works almost like before. If I click the mouse it shows up then sometimes when I click again it works, and other times I have to click a couple times
{
clicked = !clicked;
}

在我的游戏课上,我只是检查鼠标点击是否为真,然后画出我需要的东西

if (mouse.GetClicked())
{
// Draw what I need here.
// Currently is only drawn when I hold down the mouse
// And not drawn when I release the mouse.
}

然后,当我在瓷砖周围绘制正方形时,我只在pressed = true时绘制它。否则不会绘制。 此代码有时有效,有时无效。为了得到我想要的效果,我必须真正快速点击鼠标。如果我不这样做,有时看起来好像我按住鼠标按钮,正方形只是闪烁。

问题是"鼠标按下"事件正是 - 一个事件。它应该发生一次,被处理,然后在再次物理按下按钮之前不会发生。使用您的代码,一旦按下,它将内部状态设置为"按下",然后在发布之前不会更改它。这没关系,除了你的代码轮询此内部状态将其视为事件,而不是状态,因此每次在按下鼠标按钮时运行更新函数时,它都会看到"新按钮按下"。

这(使用一个按钮的代码的简化版本以及仅在按下按钮时显示图像的想法(可能会帮助您可视化它:

bool buttonPressed = false;
bool imageShown = false;
while (true)
{
SDL_Event e;
SDL_PollEvent(&e);
if (e.type == SDL_MOUSEBUTTONDOWN)
buttonPressed = true;
else if (e.type == SDL_MOUSEBUTTONUP)
buttonPressed = false;
if (!imageShown && buttonPressed)
imageShown = true;
else if (buttonPressed)
imageShown = false;
}

您是否看到每次循环运行时,即使此迭代没有触发任何事件,状态仍然存在? 这将导致imageShown变量在每次迭代中不断打开和关闭,直到触发"按钮启动"事件以重置状态。

您可能应该对输入控制器进行一些返工 - 您需要公开一种方法来区分">现在按下的按钮"和"已按下一段时间的按钮"。

一个想法是提供例如。ButtonsPressedButtonsJustPressed成员(尽管我相信您可以想到更合适的名称(。每次调用GetButtonStates时,ButtonsJustPressed成员都应重置为false,因此只有在循环的特定迭代中,它们才true被按下,而ButtonsPressed成员正是您现在正在做的事情。

考虑到这一点,上述内容的调整版本:

bool buttonJustPressed = false;
bool buttonJustReleased = false;
bool imageShown = false;
while (true)
{
// As far as we know, this iteration no events have been fired
buttonJustPressed = false;
buttonJustReleased = false
SDL_Event e;
SDL_PollEvent(&e);
if (e.type == SDL_MOUSEBUTTONDOWN)
buttonJustPressed = true;
else if (e.type == SDL_MOUSEBUTTONUP)
buttonJustReleased = true;
if (!imageShown && buttonJustPressed)
imageShown = true;
else if (imageShown && buttonJustReleased)
imageShown = false;
}

了解此版本如何仅在刚刚按下/释放按钮时更改图像的可见性 - 如果按住按钮,则不会触发事件,因此状态保持false,并且图像的状态保持不变。

最新更新