после запуска моей игры астероидов в течение нескольких минут исчезает SDL_Surface, представляющий мой корабль. Каким-то образом поверхность, содержащая повернутое изображение (гниль) корабля, устанавливается в NULL. Я не могу понять, почему! Прежде чем я добавил строку if(rot != NULL && image != NULL)
программа будет аварийно завершена после запуска в течение примерно минуты тридцать секунд, но теперь изображение просто исчезает. Я не могу понять, что не так! Заранее спасибо!
Функции класса Sprite, включающие вращение и рендеринг.
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;
}
}
Главный:
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);
Кажется, вы не освобождаете последнее повернутое изображение. Проверьте на нулевое значение и освободите поверхность перед созданием нового:
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);
}
Других решений пока нет …