简体   繁体   中英

SDL button / event stops working

I've been following lazyfoo' Productions' tutorial step by step as I create a simple game. My current task is making the main menu, which is where my problem lies.

I have a passion against global variables, ergo I do not use them; I believe they're too hard to accurately keep track of and maintain, but that's besides the point. The tutorial uses global variables for the screen, as well as several other things. I've managed to work out a button class, but it only works for a certain amount of time (approx 7 seconds) before it refuses to change the sprite.

I can still exit normally, but the button's texture will remain the same as what it was at the stop time (if the mouse is over it, it will remain glowing, vice versa).

Here's my main thread, where I call the button's class functions:

//...

while(quit == false)
{
    if(SDL_PollEvent(&event))
    {
        if(event.type == SDL_QUIT)
        {
            quit = true;
        }
        else if(event.type == SDL_MOUSEMOTION)
        {
            button_newgame.handle_events(event);
        }
    }

    button_newgame.show();

    if(SDL_Flip(screen) == -1)
    {
        return 0;
    }
}

And here's the button functions

Button::Button(int x, int y, int w, int h, int buttonnum, SDL_Surface *screen)
{
box.x = x;
box.y = y;
box.w = w;
box.h = h;

m_screen = screen;

switch(buttonnum)
{
case 0:
    buttonclipinactive.x = 0;
    buttonclipinactive.y = 0;
    buttonclipinactive.w = 240;
    buttonclipinactive.h = 60;

    buttonclipactive.x = 0;
    //setting clips according to the button's identiffying number to find the correct sprite
}

void Button::handle_events(SDL_Event event)
{
//The mouse offsets
int mx = 0, my = 0;

SDL_Delay(5);

//Get the mouse offsets
mx = event.motion.x;
my = event.motion.y;

//If the mouse is over the button
if( ( mx > box.x ) && ( mx < box.x + box.w ) && ( my > box.y ) && ( my < box.y + box.h ) )
{
    //Set the button sprite
    clip = &buttonclipactive;
}
//If not
else
{
    //Set the button sprite
    clip = &buttonclipinactive;
}

SDL_Rect* Button::show()
{
    SDL_Surface *mainmenuoptionsheet = load_image("images/mainmenuoptionsheet.bmp");

    apply_surface(box.x, box.y, mainmenuoptionsheet, m_screen, clip);
}

You call Button::show() ever tick in your loop. But what exactly does that function do?

SDL_Surface *mainmenuoptionsheet = load_image("images/mainmenuoptionsheet.bmp");

So you are loading the bmp every single tick. Your program stops showing probably because it (predictably) runs out of memory to use, and is stuck on the last sprite shown. So instead, have a SDL_Surface pointer loaded ONCE at the beginning of your application, and then rendered each frame.

As an additional note, make sure you are using the more recent lazyfoo tutorials. His old ones are dated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM