#image #animation #graphics #sdl #sprite
#изображение #Анимация #графика #sdl #спрайт
Вопрос:
Я загружаю PNG-файл (с некоторыми прозрачными местами) в свое SDL-приложение.
Поиск в Google о том, как это сделать, предоставил мне этот пример кода:
SDL_Surface *LoadImage(std::string filename)
{
SDL_Surface* loaded_image = 0, compatible_image = 0;
if (!filename.c_str())
return 0;
loaded_image = IMG_Load(filename.c_str());
if (!loaded_image)
return 0;
compatible_image = SDL_DisplayFormat(loaded_image);
SDL_FreeSurface(loaded_image);
return compatible_image;
}
Но при достижении строки compatible_image = SDL_DisplayFormat(loaded_image);
приложение останавливается с неуловимым исключением (даже try { /* ... */ } catch (...) { /* ... */ }
не помогает). Замена SDL_DisplayFormat()
на SDL_DisplayFormatAlpha()
тоже не помогла. Итак, я просто удалил строки, допускающие исключение, и запустил этот код, работающий для загрузки изображений:
SDL_Surface *LoadImage(std::string filename)
{
if (!filename.c_str())
return 0;
return IMG_Load(filename.c_str());
}
И я обнаружил такую неприятную вещь: когда один спрайт накладывается на прозрачные фрагменты другого, появляются артефакты. Что-то вроде этого:
Я анимирую своего «героя» с помощью этого простого алгоритма:
// SDL_Surface sprite = LoadImage("hero.bmp");
// hero.bmp contains animation frames followed one-by-one in a single line
// spriteFrameCnt is a number of animation frames
// spriteWidth and spriteHeight contain single frame params
SDL_Rect srcRect;
srcRect.x = spriteFrame * spriteWidth;
srcRect.w = spriteWidth;
srcRect.y = 0;
srcRect.h = spriteHeight;
spriteFrame = spriteFrame % spriteFrameCnt;
SDL_BlitSurface(sprite, amp;srcRect, screen, amp;rcSprite);
Как это можно объяснить и исправить?
Ответ №1:
Используйте SDL_DisplayFormatAlpha
вместо SDL_DisplayFormat
. Это должным образом сохраняет прозрачность.
Ответ №2:
Не уверен, что проблема в этом, но вы должны убедиться, что вызываете SDL_Init перед SDL_DisplayFormat
Комментарии:
1. Да, теперь исключение не генерируется. Благодаря тебе. Но артефакты не исчезали, как я ни старался…
Ответ №3:
Найдено решение: когда отрисовывается плитка с прозрачными фрагментами, а другой спрайт отрисовывается поверх первого, появляются артефакты. Конечно, они будут, потому что за этим первым спрайтом ничего не скрывается!
Первое и самое быстрое исправление — залить весь фон каким-либо цветом перед дальнейшими размытиями.
Второй и самый красивый способ (в моем случае) — нарисовать некоторое фоновое изображение (траву, как показано).
Вот результаты:
Как вы можете видеть, артефакты не отображаются. Я молодец! =)