Я работаю над клоном PONG и просто на экране заголовка. У меня есть класс для работы цикла заголовка конечного автомата, и он использует очень мало, только один спрайт и одно истинное сообщение типа шрифта. Но когда я вызываю функцию для рендеринга сообщения на SDL_Surface, он бросает мою программу в удар. Ошибка, которую я получаю, представляет собой Unhandled exception at 0x6F4C2A9D (SDL_ttf.dll) in Pong.exe: 0xC0000005: Access violation reading location 0x00000000.
Обычно это означает, что я не инициализировал что-то или не определял его в определении класса или что-то в этом роде, но все это выглядит по порядку. Поэтому я отправлю код здесь в надежде, что кто-то увидит, что происходит с функцией рендеринга или рядом с ней.
Чтобы быть совершенно ясным, исключение выбрано в этой строке:
Title_Message = TTF_RenderText_Solid (шрифт, "PONG", цвет);
//start code
/*CLASSES*/
class GameState
{
public:
virtual void events() = 0;
virtual void logic() = 0;
virtual void render() = 0;
virtual ~GameState(){};
};
class Button
{
public:
SDL_Rect button_clip[2];
SDL_Rect button;
SDL_Surface *button_sprite = NULL;
Button();
};
class Title : public GameState
{
private:
SDL_Surface *Title_Message = NULL;
SDL_Rect *clip;
Button Title_Button;
public:
void events();
void logic();
void render();
Title();
~Title();
};
/*FONTS*/
SDL_Color color = { 255, 255, 255 };
TTF_Font *font = NULL;
bool init()
{
//initialize all SDL subsystems
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
{
return false;
}
//set up screen
screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
//check screen
if (screen == NULL)
{
return false;
}
//init TTF
if (TTF_Init() == -1)
{
return false;
}
//set window caption
SDL_WM_SetCaption("PONG", NULL);
//if evetything worked
return true;
}
//load files
bool load_files()
{
font = TTF_OpenFont("PIXELITE.ttf", 45);
if (font == NULL)
{
return false;
}
return true;
}
/*CLASS DEFINITIONS*/
Button::Button()
{
}
Title::Title()
{
Title_Message = TTF_RenderText_Solid(font, "PONG", color);
Title_Button.button_sprite = load_image("Start.png");
Title_Button.button.x = 200;
Title_Button.button.y = 350;
Title_Button.button.w = 100;
Title_Button.button.h = 50;
//clips not hover
Title_Button.button_clip[0].x = 0;
Title_Button.button_clip[0].y = 0;
Title_Button.button_clip[0].w = 100;
Title_Button.button_clip[0].h = 50;
//clips hover
Title_Button.button_clip[1].x = 0;
Title_Button.button_clip[1].y = 50;
Title_Button.button_clip[1].w = 100;
Title_Button.button_clip[1].h = 50;
}
Title::~Title()
{
SDL_FreeSurface(Title_Message);
SDL_FreeSurface(Title_Button.button_sprite);
}
void Title::events()
{
int x = 0;
int y = 0;
while (SDL_PollEvent(&event))
{
if (event.type == SDL_MOUSEMOTION)
{
x = event.motion.x;
y = event.motion.y;
if ((x > Title_Button.button.x) && (x < (Title_Button.button.x + Title_Button.button.w)) && (y > Title_Button.button.y) && (y < (Title_Button.button.y + Title_Button.button.h)))
{
clip = &Title_Button.button_clip[1];
}
else
{
clip = &Title_Button.button_clip[0];
}
}
if (event.type == SDL_QUIT)
{
quit = true;
}
}
}
void Title::logic()
{
}
void Title::render()
{
apply_surface(Title_Button.button.x, Title_Button.button.y, Title_Button.button_sprite, screen, clip);
apply_surface((SCREEN_WIDTH - Title_Message->w) / 2, 100, Title_Message, screen);
}
У кого-нибудь появилась идея? Благодарю!
Я отправлю свои предложения из комментариев в качестве фактического ответа:
Title_Message = TTF_RenderText_Solid(font, "PONG", color);
строка Title_Message = TTF_RenderText_Solid(font, "PONG", color);
относится к глобальному переменному font
типа TTF_Font*
. Строка также является частью конструктора класса Title
.
main
выглядит следующим образом:
int main(int argc, char* args[])
{
//init SDL
init();
//load everything
load_files();
currentState = new Title;
//...
font
инициализируется в NULL
при объявлении, фактический объект присваивается только в load_files()
который выполняется в начале main
load_files()
до того, как Title
будет впервые создан.
Поэтому load_files()
должен назначить действительный указатель на font
, иначе следующая строка в main
вызовет нарушение прав доступа.
load_files()
предоставляет возвращаемое значение в зависимости от того, было ли успешным создание и назначение этого объекта. Однако main
функция никогда не проверяет это значение и, следовательно, не гарантируется, что font
является допустимым указателем.
Как указывал knefcy, проблема была неправильным именем файла в load_files()
.
true
илиfalse
зависимости от успешности инициализации, но вы никогда не проверяете возвращаемые значения вmain
. Откуда вы знаете, что инициализация вinit()
иload_files()
прошла успешно?