5 Replies - 834 Views - Last Post: 22 January 2014 - 07:46 PM Rate Topic: -----

#1 Kairi Nightingale   User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 5
  • Joined: 22-January 14

SDL Window Auto-Closes When Image Changes. Please help.

Posted 22 January 2014 - 02:41 PM

Background:
I'm making a small game using CodeBlocks and SDL. All of the code resides in a class named Game - the only thing running in Main is the creation of the Game object and the class function execute(). So far, I've made a Start Menu with three clickable buttons. I'm in the midst of making one of the buttons - Load Game - change the game screen to the Load Game menu. Basically, when the user clicks the button, the image on screen changes according to the button they click.

Issue:
After successfully making the Load Game button change the image on the screen, I found that the SDL window mysteriously closes out several seconds after the image change. I've no idea what is causing this - the window stays on perfectly fine until the background image is changed and the only way to break the loop is for the player to click the x on the window. I've gone over the code several times and haven't found anything that might be the cause. Any help would be much appreciated.

Code:

Game.h file

#ifndef GAME_H
#define GAME_H

#include "SDL/SDL.h"
#include "SDL/SDL_ttf.h"

#include <iostream>
#include <cstdlib>

using namespace std;

//Global Constants

const int WINDOW_W = 840;
const int WINDOW_H = 580;
const int BIT_RES = 32;

class Game
{
    private:

        bool running; //variable for checking if the player quit
        int screen; //keeps track of which game screen is currently being used

        SDL_Event event;//for catching events during the game

        SDL_Surface* window;//the game window
        SDL_Surface* temp;//to fix formats
        SDL_Surface* background;//background image
        SDL_Surface* buttonSprites;//holds the button sprite sheet for blitting

        SDL_Rect dest; //for holding destination coordinates for images being drawn to the game window
        SDL_Rect src; //holds information for clipping source sprite sheets


    protected:
    public:
        Game();
        virtual ~Game();

        //game functions
        void execute();//holds the game loop

        //initialization functions
        void initBackground(int);//loads background image based on number passed
        void initButtons(int);

        //event functions
        void gameEvents(); //implements all events for the game
        void buttonEvents(); //implements button events

        //render functions
        void render();//renders images on the game window
        void renderBackground();//renders the background images on the game window
        void renderButtons();//renders any button icons
};

#endif // GAME_H


Game.cpp file

#include "Game.h"

Game::Game()
{
    SDL_Init(SDL_INIT_EVERYTHING);

    running = true;
    screen = 0;

    //create game window
    window = NULL;
    window = SDL_SetVideoMode(WINDOW_W, WINDOW_H, BIT_RES, SDL_HWSURFACE | SDL_DOUBLEBUF);

    //initialize surfaces
    background = NULL;

    temp = SDL_LoadBMP("./Graphics/buttons.bmp");
    buttonSprites = SDL_DisplayFormat(temp);

}

void Game::execute()
{

    screen = 1; //1 = start menu
    initBackground(1);

    while(running == true)
    {
        //poll event
        while(SDL_PollEvent(&event))
        {
            gameEvents();
        }

        render();
    }
}

void Game::initBackground(int num)
{
    switch(num)
    {
    //start menu
    case 1:
        //load image
        temp = SDL_LoadBMP("./Graphics/start screen.bmp");
        background = SDL_DisplayFormat(temp);
        break;

    //load screen
    case 2:
        temp = SDL_LoadBMP("./Graphics/load game screen.bmp");
        background = SDL_DisplayFormat(temp);
        break;
    }
}


void Game::gameEvents()
{
    //if the player X's out of the window, quit the game.
    switch(event.type)
    {
    case SDL_QUIT:
        running = false;
        break;
    }

    if(running == true)
    {
        switch(event.type)
        {
        //mouse click events
        case SDL_MOUSEBUTTONDOWN:
            buttonEvents();
            break;
        }
    }
}

void Game::buttonEvents()
{
    int x = event.button.x;
    int y = event.button.y;

    switch(screen)
    {

    //Start Menu button events
    case 1:
        if(event.button.button == SDL_BUTTON_LEFT)
        {

            //check load game button
            initButtons(2);
            if((x >= dest.x) && (x <= (dest.x + src.w)) && (y >= dest.y) && (y <= (dest.y + src.h)))
            {
                //change screen to Load Game Screen.
                screen = 2;
            }
        }
        break; 
    }
}

void Game::initButtons(int num)
{
    switch(num)
    {

    //Load Game button
    case 2:
        src.w = 218;
        src.h = 63;
        src.x = 220;
        src.y = 0;

        dest.x = 312;
        dest.y = 288;
        break;
    }
}

void Game::render()
{
    //render game screen
    renderBackground();

    //render buttons
    renderButtons();

    //update screen
    SDL_Flip(window);
}

void Game::renderBackground()
{
    switch(screen)
    {
    //for start menu screen
    case 1:
        initBackground(1);
        break;

    //for load menu screen
    case 2:
        initBackground(2);
        break;

    }
    dest.x = 0;
    dest.y = 0;

    SDL_BlitSurface(background, NULL, window, &dest);
}

void Game::renderButtons()
{
    switch(screen)
    {
    //render buttons for Start Screen
    case 1:
        for(int cnt = 1; cnt <= 3; cnt++)
        {
            //initialize button info
            initButtons(cnt);
            //render buttons
            SDL_BlitSurface(buttonSprites, &src, window, &dest);
        }
        break;
    
    }
}



Output:
- Window with an Start Menu image and a button with the words "Load Game".
- If user clicks the X on the window, the window closes.
- If user clicks "Load Game" button, Start Menu image changes to Load Game image. After about seven seconds, the window automatically closes out. This isn't supposed to happen.

This post has been edited by JackOfAllTrades: 22 January 2014 - 04:00 PM
Reason for edit:: Added missing braces to initButtons and initBackground


Is This A Good Question/Topic? 0
  • +

Replies To: SDL Window Auto-Closes When Image Changes. Please help.

#2 #define   User is offline

  • Duke of Err
  • member icon

Reputation: 1855
  • View blog
  • Posts: 6,678
  • Joined: 19-February 09

Re: SDL Window Auto-Closes When Image Changes. Please help.

Posted 22 January 2014 - 03:16 PM

Hi, welcome to DIC. initButtons has a curly bracket missing, which I would expect to give a compiler error.
Was This Post Helpful? 1
  • +
  • -

#3 Kairi Nightingale   User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 5
  • Joined: 22-January 14

Re: SDL Window Auto-Closes When Image Changes. Please help.

Posted 22 January 2014 - 03:26 PM

View Post#define, on 22 January 2014 - 03:16 PM, said:

Hi, welcome to DIC. initButtons has a curly bracket missing, which I would expect to give a compiler error.


Oops. I'm afraid the missing bracket was a copy&paste error. Sorry about that. I get no compiler errors when I run my code so I'm afraid it isn't something as simple as a missing bracket. But thank you for pointing that out. Is there a way to edit my post to fix it?
Was This Post Helpful? 0
  • +
  • -

#4 #define   User is offline

  • Duke of Err
  • member icon

Reputation: 1855
  • View blog
  • Posts: 6,678
  • Joined: 19-February 09

Re: SDL Window Auto-Closes When Image Changes. Please help.

Posted 22 January 2014 - 04:04 PM

You wont be able to edit your posts until you have made about 20 posts, it is to stop people just deleting their code etc.

I think you may be filling up the memory because you keep loading the backgrounds from disk when rendering. The render function calls renderBackground which calls initBackground which calls SDL_LoadBMP. If on windows the task manager would show the memory usage.

What you want to do is load both the background images into memory once (initialization). Give each background a surface pointer, and when you want to change the background, set the background pointer to point to the correct background image/surface.

  SDL_Surface* start_background;
  SDL_Surface* loadgame_background;

  //...

  // change the background
  background = loadgame_background;




That's just a quick explanation, we can help a bit more if needed.
You could have a button class.

Edit:
It is proper to free the suface memory when finished - SDL_FreeSurface.
Aarons Game Programming Tutorials - Putting SDL calls into classes

.

This post has been edited by #define: 22 January 2014 - 04:13 PM

Was This Post Helpful? 1
  • +
  • -

#5 Kairi Nightingale   User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 5
  • Joined: 22-January 14

Re: SDL Window Auto-Closes When Image Changes. Please help.

Posted 22 January 2014 - 06:42 PM

View Post#define, on 22 January 2014 - 04:04 PM, said:

You wont be able to edit your posts until you have made about 20 posts, it is to stop people just deleting their code etc.

I think you may be filling up the memory because you keep loading the backgrounds from disk when rendering. The render function calls renderBackground which calls initBackground which calls SDL_LoadBMP. If on windows the task manager would show the memory usage.

What you want to do is load both the background images into memory once (initialization). Give each background a surface pointer, and when you want to change the background, set the background pointer to point to the correct background image/surface.

  SDL_Surface* start_background;
  SDL_Surface* loadgame_background;

  //...

  // change the background
  background = loadgame_background;




That's just a quick explanation, we can help a bit more if needed.
You could have a button class.

Edit:
It is proper to free the suface memory when finished - SDL_FreeSurface.
Aarons Game Programming Tutorials - Putting SDL calls into classes

.


It worked! Thank you so, so much. I would have never thought to check the memory usage. I really appreciate your help.

As a side note, I did actually free the surfaces in the destructor, I just forgot to copy and paste that part in. Sorry. ^.^; But thank you for the link to that tutorial - it's one I haven't looked at yet and it looks like it'll be very useful.

I thought about using a button class but wasn't sure if it was worth it until now. I'll definitely reconsider after this, though. Thank you again for the help and advice.
Was This Post Helpful? 1
  • +
  • -

#6 #define   User is offline

  • Duke of Err
  • member icon

Reputation: 1855
  • View blog
  • Posts: 6,678
  • Joined: 19-February 09

Re: SDL Window Auto-Closes When Image Changes. Please help.

Posted 22 January 2014 - 07:46 PM

It worked that's great! I was wondering whether you were freeing the surfaces - just checking.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1