gpt4 book ai didi

c++ - 我应该如何为 SDL 中的多个按钮缩放它?

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:53:34 26 4
gpt4 key购买 nike

我有一个简单的脚本,它显示一个按钮(这是一个 png 图像),当用户单击它时应用程序退出。

但我想添加多个按钮,我发现我目前的想法会导致很长的 if:else 情况,我想知道这是否是唯一的方法。

这就是我在 main.cpp 文件中设置当前菜单的方式。

bool handle_mouse_leftClick(int x, int y, SDL_Surface *button) {
if( ( ( mouseX > x ) && ( mouseX < x + button->w ) ) && ( ( mouseY > y ) && ( mouseY < y + button->h ) ) ) {
return true;
} else {
return false;
}
}

这是我的检测功能。

下面是我的主要功能,它充当我的游戏循环,我删除了不相关的代码以使其更容易理解:

//menu button
SDL_Surface *button;
button = IMG_Load("button.png");

while(!quit){
//handle events
while( SDL_PollEvent( &event ) ){
switch(event.type){
case SDL_QUIT: quit = true; break;
case SDL_MOUSEBUTTONDOWN:

if (event.button.button == SDL_BUTTON_LEFT) {
if(handle_mouse_leftClick(btnx,btny,button)){
quit = true;
}
}
break;
}
}

问题是我的 main.cpp 是否应该进行所有这些检查,当我添加更多按钮时会很快变得很长所以我想知道我是否错过了一个简化我的工作的技巧?

最佳答案

当您深入了解基本逻辑/计算时,我会说答案是否定的,您没有错过任何技巧。我从来没有找到一种方法来一次检查每个目标——至少在计算方面是这样。您可以通过多种方式使您的代码更干净。您可以拥有一个公开“bool IsIn( int x, int y )”方法的 GuiElement 类。那么你的大案例陈述看起来更像是:

bool handle_mouse_leftClick(int x, int y, SDL_Surface *button) 
{
if (Button1.IsIn( mouseX, mouseY )
{
// do this
}
else if (Button2.IsIn( mouseX, mouseY ))
{
// do that
}
else
{
return false;
}
}

然后您可以使用列表或表格进一步减少代码量:

int handle_mouse_leftClick(int x, int y, SDL_Surface *button) 
{
for (unsigned int i = 0; i < buttonList.size(); i++
{
if (buttonList[i].IsIn( mouseX, mouseY ))
{
return i; // return index of button pressed
}
return -1; // nothing pressed
}
}

但它最终仍会一次查看每个矩形。

注意事项:

  1. 我认为检查每个项目的命中框不会有太多实际的计算开销 - 除非您以某种疯狂的高帧率进行操作。

  2. 当然,您可以使用某种空间索引(例如按屏幕上按钮的位置组织的 b 树或四叉树)来优化检查,但是……请参阅 #1。 ;-)

如果您有 数千 而不是 10 或 15 个按钮/控件,那么您可能想要执行 #2,因为 #1 将不再成立。

********* 更新***********

这是可用于此目的的类的简短示例。至于 .h 与 main.cpp,典型的方法是将 header 放在“Button.h”中,将实现(代码)放在“Button.cpp”中,但您可以将其放在 main 的顶部.cpp 开始 - 它具有类定义中的所有逻辑。

您会注意到我并没有真正编写任何新代码。 “IsIn()”测试是您的逻辑逐字记录,我只是更改了变量名称以匹配类。由于您已经有了一个按钮,我假设您可以重用使用 Render() 方法呈现该按钮的代码。

最后,如果不是您熟悉的内容,您根本不必创建列表/vector 。呈现按钮的代码可以只调用“okButton.Render()”,然后调用“cancelButton.Render()”。

示例“按钮”类:

class Button
{
private:
int m_x, m_y; // coordinates of upper left corner of control
int m_width, m_height; // size of control

public:
Button(int x, int y, int width, int height, const char* caption)
{
m_x = x;
m_y = y;
m_width = width;
m_height = height;
// also store caption in variable of same type you're using now for button text
}

bool IsIn( int mouseX, int mouseY )
{
if (((mouseX > m_x) && (mouseX < m_x + m_width))
&& ((mouseY > m_y) && (mouseY < m_y + m_height ) ) ) {
return true;
} else {
return false;
}
}

void Render()
{
// use the same code you use now to render the button in OpenGL/SDL
}
};

然后创建它/它们(使用列表方法):

Button okButton( 10, 10, 100, 50, "OK" );
buttonList.push_back( okButton );

Button cancelButton( 150, 10, 100, 50, "Cancel" );
buttonList.push_back( cancelButton );

在你的渲染循环中:

void Update()
{
for (unsigned int i = 0; i < buttonList.size(); i++
{
buttonList[i].Render();
}
}

关于c++ - 我应该如何为 SDL 中的多个按钮缩放它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13131349/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com