SDL - object not drawing itself

Started by
10 comments, last by Deuce81 16 years, 7 months ago
Hi I'm working on a mini game, where a bunch of flies randomly pop up and you have o hit it with a hammer. Nothing great just to practice coding, anyway I started off with the flies being structs and all the logic and drawing was done by stand alone functions. I moved all of this to a fly class and I basically call one function in the main loop to do all of this. Now it stopped working, the flies are simply not being blitted onto the screen. This is the function being called in main.

void Fly::draw_fly(SDL_Surface* _screen)
{
    if ((this->isDead) && (this->isVisible))
    {
        if (this->deadTime.get_time() > 1000)
        {
            this->isVisible = false;
            this->visibleTime.reset();
        }
    }

    if (!this->isVisible)
    {
        if (this->visibleTime.get_time() > 2000)
        {
            this->get_random_pos();
            this->isDead = false;
            this->isVisible = false;
        }
    }

    if (this->isVisible)
    {
        if (this->isDead)
        {
            apply_surface(this->xPos, this->yPos, this->dead, _screen);
        }
        else
        {
            apply_surface(this->xPos, this->yPos, this->dead, _screen);
        }
    }
}
I just call it in main and pass it the screen surface. apply_surface is the same function from LazyFoo's tuts. I've stepped through the code and I know that it is calling apply_surface. Any ideas? Please, I've already got a bald patch from pulling out my hair.
Advertisement
Are you calling SDL_Flip(screen)?
AfroFire | Brin"The only thing that interferes with my learning is my education."-Albert Einstein
Yes. Other surfaces are being blitted to the screen and it works, just not the flies.
We'll need to see how draw_fly is being used.

Learn to make games with my SDL 2 Tutorials

Original post by TooLSHeD
...
void Fly::draw_fly(SDL_Surface* _screen){    ...    if (this->isVisible)    {        if (this->isDead)        {            apply_surface(this->xPos, this->yPos, this->dead, _screen);        }        else        {            apply_surface(this->xPos, this->yPos, this->dead, _screen);        }    }}

....

Nothing to do with your problem I think but are you sure you want to draw the dead picture even if the Objekt is not dead? Looks like a copy and paste error.
“Always programm as if the person who will be maintaining your program is a violent psychopath that knows where you live”
just reading the code logically i found that in your second if statment, you need to set isVisible to true, not false; its already false, and since its not visible, its not being drawn.

   if (!this->isVisible)    {        if (this->visibleTime.get_time() > 2000)        {            this->get_random_pos();            this->isDead = false;            //set isVisible to true            //this->isVisible = false;            this->isVisible = true;        }    }


i think this is your issue. i may have misread your purpose.
but it looks like you want to redraw the fly if its dead after 2000ms
Quote:Original post by Lazy Foo
We'll need to see how draw_fly is being used.

It's basically being called in the main loop with the global screen surface being passed to it, right after the background is blitted onto the screen.

Quote:Original post by dragongame
Quote:Original post by TooLSHeD
...
*** Source Snippet Removed ***
....


Nothing to do with your problem I think but are you sure you want to draw the dead picture even if the Objekt is not dead? Looks like a copy and paste error.

Ah yes thanks, it is a copy and paste error.

And thanks mindrot, I changed it, but it still doesn't work.
sounds awkward but can you post the entire amount of code?
Here it is, please note: still work in progress, please criticize anything else while you're at it.

main.cpp
#ifdef __cplusplus    #include <cstdlib>#else    #include <stdlib.h>#endif#ifdef __APPLE__#include <SDL/SDL.h>#include <SDL/SDL_image.h>#include <SDL/SDL_ttf.h>#else#include <SDL.h>#include <SDL_image.h>#include <SDL_ttf.h>#endif#include <string>#include <sstream>#include <ctime>#include "Timer.h"#include "functions.h"#include "Fly.h"// Some global(BAD!) constants.const int SCREEN_WIDTH = 640;const int SCREEN_HEIGHT = 480;const int SCREEN_BPP = 32;// Maximum flies allowed on the screen.#define MAX_FLIES 10//The surfaces that will be used.SDL_Surface* screen = NULL;SDL_Surface* background = NULL;SDL_Surface* fpsText = NULL;// Hammer struct, this combines all the variables neededtypedef struct{    int posX;           // x position.    int posY;           // y position.    int width;          // Width.    int height;         // Height.    SDL_Surface* up;    // Up position.    SDL_Surface* down;  // Down position.    bool isDown;        // Down if true, else up.} Hammer;// Instance of Hammer, this is the main hammer.Hammer hammer;// flyCount, records the number of alive fliesint flyCount = 0;// flyAlive and flyDead holds the respective surfaces// so that it isn't loaded everytime a new fly is created.SDL_Surface* flyAlive = NULL;SDL_Surface* flyDead = NULL;// The TTF fonts.TTF_Font *fpsFont = NULL;   // Font used to display the frames per second.// Font Colors.SDL_Color fpsFGTextColor = {255, 0, 0};     // Color for the fps foreground font.SDL_Color fpsBGTextColor = {255, 255, 255}; // Color for the fps background font.// Handle events.SDL_Event event;// get_random_x returns a random value between 25 and 590.int get_random_x(){    return((rand()%590) + 25);}// get_random_y returns a random value between 25 and 430.int get_random_y(){    return((rand()%430) + 25);}// load_image, loads any image format and converts it// to a SDL_Surface, thanks LazyFoo.SDL_Surface* load_image(std::string filename){    // The image that is loaded    SDL_Surface* loadedImage = NULL;    // The optimized image that will be used.    SDL_Surface* optimizedImage = NULL;    // Load the image using SDL_image.    loadedImage = IMG_Load(filename.c_str());    if (loadedImage != NULL)    {        // Create optimized image.        optimizedImage = SDL_DisplayFormat(loadedImage);        // Free the old image.        SDL_FreeSurface(loadedImage);    }    if (optimizedImage != NULL)    {        // Create a color key so that a chosen color can be transparent.        Uint32 colorKey = SDL_MapRGB(optimizedImage->format, 0, 0xFF, 0xFF);        // Set all  the pixel with the color value of        // 00FFFF to be transparent        SDL_SetColorKey(optimizedImage, SDL_RLEACCEL | SDL_SRCCOLORKEY, colorKey);    }    return(optimizedImage);}// apply_surface blits one surface onto another// thanks again LazyFoo!void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination){    // Make a temporary rectangle to hold the offsets.    SDL_Rect offset;    // Give the offsets to the rectangle.    offset.x = x;    offset.y = y;    // Blit the surface.    SDL_BlitSurface(source, NULL, destination, &offset);}// Initializes everythingbool init(){    // Seed the random number generator.    srand(time(0));    // Initialize SDL.    if (SDL_Init(SDL_INIT_EVERYTHING) == -1)    {        printf("SDL_init FAILED: %s", SDL_GetError());        return(false);    }    // Set up the screen.    screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);    // Check if there was an error.    if (screen == NULL)    {        printf("SDL_SetVideoMode FAILED: %s", SDL_GetError());        return(false);    }    // Initialize TTF    if (TTF_Init() == -1)    {        printf("TTF_Init FAILED: %s", SDL_GetError());        return(false);    }    // Set the window caption.    SDL_WM_SetCaption("Splat", NULL);    // Initialize all the hammer variables    hammer.down = NULL;    hammer.up   = NULL;    hammer.isDown = false;    hammer.posX = 0;    hammer.posY = 0;    hammer.width = 50;    hammer.height = 50;    // Initialize the flies, this is the only case when    // the files aren't loaded in load_files().    flyAlive = load_image("images/fly_alive.png");    if (flyAlive == NULL)    {        printf("load_image FAILED: %s", SDL_GetError());        return(false);    }    flyDead = load_image("images/fly_dead.png");    if (flyDead == NULL)    {        printf("load_image FAILED: %s", SDL_GetError());        return(false);    }    // Hide the cursor    SDL_ShowCursor(SDL_DISABLE);    return(true);}// Load all the needed filesbool load_files(){    // Load the background.    background = load_image("images/background.png");    if (background == NULL)    {        printf("load_image FAILED: %s", SDL_GetError());        return(false);    }    // Load the hammer up position    hammer.up = load_image("images/hammer_up.png");    if (hammer.up == NULL)    {        printf("load_image FAILED: %s", SDL_GetError());        return(false);    }    // Load the hammer up position    hammer.down = load_image("images/hammer_down.png");    if (hammer.up == NULL)    {        printf("load_image FAILED: %s", SDL_GetError());        return(false);    }    // Load the font.    fpsFont = TTF_OpenFont("images/comic.ttf", 12);    if (fpsFont == NULL)    {        printf("TTF_OpenFont FAILED: %s", SDL_GetError());        return(false);    }    return(true);}// clean_up, free all the surfaces and quit.void clean_up(){    // Free the background surface.    SDL_FreeSurface(background);    // Free the text surface.    SDL_FreeSurface(fpsText);    SDL_FreeSurface(flyAlive);    SDL_FreeSurface(flyDead);    SDL_FreeSurface(hammer.down);    SDL_FreeSurface(hammer.up);    // Free the fornt.    TTF_CloseFont(fpsFont);    // Quit TTF.    TTF_Quit();    // Quit SDL.    SDL_Quit();}int main (int argc, char** argv){    // Quit flag;    bool quit = false;    bool mouseDown = false; // Is the mouse button being held down?    // Mouse coords    int mouseX = 0;    int mouseY = 0;    Fly fly(flyAlive, flyDead);    // Timer instance.    Timer time = Timer();    int frameCount = 0; // The number of frames per second.    // Used to output the fps.    std::stringstream fps;    if (!init())    {        return 1;    }    if (!load_files())    {        return 1;    }    // Apply the background to the screen.    apply_surface(0, 0, background, screen);    // Update the screen    if (SDL_Flip(screen) == -1)    {        printf(SDL_GetError());        SDL_Quit();        return 1;    }    time.start();    fps << "FPS: 0";    while (quit == false)    {        while (SDL_PollEvent(&event))        {            if (event.type == SDL_QUIT)            {                quit = true;            }            // Check if the mouse button is being pressed.            if (event.type == SDL_MOUSEBUTTONDOWN)            {                hammer.isDown = true;                if (!mouseDown)                {                    fly.is_hit(event.motion.x, event.motion.y);                }                mouseDown = true;            }            if (event.type == SDL_MOUSEBUTTONUP)            {                hammer.isDown = false;                mouseDown = false;            }            // Track the mouse motion            if (event.type == SDL_MOUSEMOTION)            {                mouseX = event.motion.x;                mouseY = event.motion.y;            }        }        fpsText = TTF_RenderText_Shaded(fpsFont, fps.str().c_str(), fpsFGTextColor,                                        fpsBGTextColor);        // Apply the background to the screen.        apply_surface(0, 0, background, screen);        fly.draw_fly(screen);        // Apply the hammer.        // set the pointer in the middle of the hammer, thus position - 25.        if (hammer.isDown)        {            apply_surface(mouseX - 25, mouseY - 25, hammer.down, screen);        }        else        {            apply_surface(mouseX - 25, mouseY - 25, hammer.up, screen);        }        // Apply the fps text.        apply_surface(20, 450, fpsText, screen);        // Update the screen.        if (SDL_Flip(screen) == -1)        {            printf(SDL_GetError());            clean_up();            return 1;        }        // Calculate the frames per second.        if (time.get_time() >= 1000)        {            // If the time elapsed is greater than 1s            // then reset the timer.            time.reset();            // Clear the string.            fps.str("");            fps << "FPS: " << frameCount;            frameCount = 0;        }        frameCount++;    }    clean_up();    return 0;}


fly.h
#ifdef __cplusplus    #include <cstdlib>#else    #include <stdlib.h>#endif#ifdef __APPLE__#include <SDL/SDL.h>#include <SDL/SDL_image.h>#include <SDL/SDL_ttf.h>#else#include <SDL.h>#include <SDL_image.h>#include <SDL_ttf.h>#endif#include <string>#include <sstream>#include <ctime>#include "Timer.h"#include "functions.h"class Fly{    private:    int xPos;           // X position.    int yPos;           // Y position.    int width;          // Width.    int height;         // Height.    bool isDead;        // Dead if true;    bool isVisible;     // Visible is true;    SDL_Surface* dead;  // Dead surface.    SDL_Surface* alive; // Alive surface.    Timer visibleTime;  // Makes dead flies invisible.    Timer deadTime;     // Makes dead & invisible flies alive.    public:    // Default constructor.    Fly();    Fly(SDL_Surface* _alive, SDL_Surface* _dead) ;    bool is_hit(int _mouseX, int _mouseY);    void get_random_pos();    void draw_fly(SDL_Surface* _screen);    bool is_dead();    bool is_visible();    ~Fly();};

fly.cpp
#include "Fly.h"Fly::Fly(){    this->alive = NULL;    this->dead = NULL;    this->isDead = true;    this->isVisible = false;    this->height = 50;    this->width = 50;    this->visibleTime = Timer();    this->visibleTime.start();    this->deadTime = Timer();    this->deadTime.start();    get_random_pos();}Fly::Fly(SDL_Surface* _alive, SDL_Surface* _dead){    this->alive = _alive;    this->dead = _dead;    this->isDead = false;    this->isVisible = true;    this->height = 50;    this->width = 50;    this->visibleTime = Timer();    this->visibleTime.start();    this->deadTime = Timer();    this->deadTime.start();    get_random_pos();}bool Fly::is_hit(int _mouseX, int _mouseY){    if ((_mouseX > this->xPos) && (_mouseX < (this->xPos + this->width)) &&        (_mouseY > this->yPos) && (_mouseY < (this->yPos + this->width)))    {        if (!this->isDead)        {            this->isDead = true;            this->deadTime.reset();            return(true);        }    }    return false;}void Fly::get_random_pos(){    this->xPos = (rand()%590 + 25);    this->yPos = (rand()%430 + 25);}void Fly::draw_fly(SDL_Surface* _screen){    if ((this->isDead) && (this->isVisible))    {        if (this->deadTime.get_time() > 1000)        {            this->isVisible = false;            this->visibleTime.reset();        }    }    if (!this->isVisible)    {        if (this->visibleTime.get_time() > 2000)        {            this->get_random_pos();            this->isDead = false;            this->isVisible = true;        }    }    if (this->isVisible)    {        if (this->isDead)        {            apply_surface(this->xPos, this->yPos, this->dead, _screen);        }        else        {            apply_surface(this->xPos, this->yPos, this->alive, _screen);        }    }}bool Fly::is_dead(){    return(this->isDead);}bool Fly::is_visible(){    return(this->isVisible);}Fly::~Fly(){    SDL_FreeSurface(this->alive);    SDL_FreeSurface(this->dead);}


At the moment I'm only trying to draw one fly, as soon as I sort out this problem then I'll have multiple flies.
First glance - I notice you call SDL_FreeSurface twice, once in the clean_up() function and another in the deconstructor of fly - that might cause problems in the future, and the fact that you didn't mention that it is crashing or anything on exit kind of hinted at the idea that something is going wrong with your surface loading, and I found your problem in main().

You're constructing your fly with two NULL surfaces before you call init().

Just move it to right after, and you should be okay :)
AfroFire | Brin"The only thing that interferes with my learning is my education."-Albert Einstein

This topic is closed to new replies.

Advertisement