Необработанное исключение в функции визуализации шрифта C ++ SDL

0

Я работаю над клоном 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);
}

У кого-нибудь появилась идея? Благодарю!

  • 1
    Пример кода слишком сложный. Уменьшите его до минимума, все еще показывая ошибку. Тем не менее, у вас есть несколько функций инициализации, которые могут возвращать true или false зависимости от успешности инициализации, но вы никогда не проверяете возвращаемые значения в main . Откуда вы знаете, что инициализация в init() и load_files() прошла успешно?
  • 0
    На самом деле это не слишком много строк, но я вижу, что я могу сделать.
Показать ещё 3 комментария
Теги:
class
exception
sdl

1 ответ

1
Лучший ответ

Я отправлю свои предложения из комментариев в качестве фактического ответа:

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().

  • 0
    Как обычно бывает в случае этих проблем со шрифтом sdl +.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню