Question

after running my asteroids game for several minutes the SDL_Surface representing my ship disappears. Somehow the surface that holds the rotated image (rot) of the ship is getting set to NULL. I can't figure out why! Before I added the line if(rot != NULL && image != NULL) the program would crash after running for a about a minute an thirty seconds, but now the image just disappears. I can't seem to figure out whats wrong! Thanks in advance!

Sprite Class functions involving rotation and rendering.

void Sprite::Rotate(double angleAdd)
{
    rotated = true;
    double temp = 0;
    angle += angleAdd;
    temp = angleAdd + angle;
    if (temp >= 360)
        angleAdd = temp - 360;
    if (temp <= 360)
        angleAdd = temp + 360;

    rot = rotozoomSurface(image, angle , 1.0, 1);
}

void Sprite::Draw(SDL_Surface* screen)
{
    if(image == NULL)
        SDL_FillRect(screen, &rect, color);
    else
    {
        if (rotated)
        {
            rotRect.x = x;
            rotRect.y = y;
            //Center the image
            if(rot != NULL && image != NULL){
                rotRect.x -= ((rot->w/2) - (image->w/2));
                rotRect.y -= ((rot->h/2) - (image->h/2));
            }
            SDL_BlitSurface(rot, NULL, screen, &rotRect);
        }
        else
            SDL_BlitSurface(image, NULL, screen, &rect);
    }
}

bool Sprite::SetImage(std::string fileName)
{
    imageFileName = fileName;
    SDL_Surface* loadedImage = NULL;
    loadedImage = SDL_LoadBMP(fileName.c_str());
    if(loadedImage == NULL)
    {
        if (debugEnabled)
            printf("Failed to load image: %s\n", fileName.c_str());
            SDL_FreeSurface(loadedImage);
        return false;
    }
    else
    {
        image = SDL_DisplayFormat(loadedImage);

        SDL_FreeSurface(loadedImage);
        return true;
    }

}

Main:

    if (arrowPressed[0])
    {
        ship.SetImage(shipFor.GetImage());
        if(!phase)
            ship.Accel(-moveSpeed);
        else
            ship.Accel(-moveSpeed * 2);
    }
    if (arrowPressed[1])
    {
        ship.Rotate(turnSpeed);
        ship.SetImage(shipRig.GetImage());
    }
    if (arrowPressed[3])
    {
        ship.Rotate(-turnSpeed);
        ship.SetImage(shipLef.GetImage());
    }

    if (arrowPressed[0] && arrowPressed[1])
        ship.SetImage(shipForRig.GetImage());
    if (arrowPressed[0] && arrowPressed[3])
        ship.SetImage(shipForLef.GetImage());
    if (!arrowPressed[0] && !arrowPressed[1] && !arrowPressed[3])
        ship.SetImage(shipNor.GetImage());

    if (ship.GetCenterX() >= RESX - 40)
        ship.SetPosCentered(50, ship.GetCenterY());
    if (ship.GetCenterX() <= 40)
        ship.SetPosCentered(RESX - 50, ship.GetCenterY());
    if (ship.GetCenterY() >= RESY - 40)
        ship.SetPosCentered(ship.GetCenterX(), 50);
    if (ship.GetCenterY() <= 40)
        ship.SetPosCentered(ship.GetCenterX(), RESY - 150);
Was it helpful?

Solution

It seems that you are not freeing the last rotated image. Check for null, and free the surface before creating a new one:

void Sprite::Rotate(double angleAdd)
{
    if(rot != NULL)
        SDL_FreeSurface(rot);

    rotated = true;
    double temp = 0;
    angle += angleAdd;
    temp = angleAdd + angle;
    if (temp >= 360)
        angleAdd = temp - 360;
    if (temp <= 360)
        angleAdd = temp + 360;

    rot = rotozoomSurface(image, angle , 1.0, 1);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top