TTF_RenderText_Solid() 崩溃游戏和 Visual Studio [c++][sdl ttf]

TTF_RenderText_Solid() Crashing Game and Visual Studio [c++][sdl ttf]

堆栈跟踪:

所以,我正在尝试创建一个 2D 游戏,现在我正在尝试显示和移动图像,但是当我调试 game/run 它时,visual studio 和游戏死机并且无法退出,即使使用任务管理器将其杀死也无法退出。 解冻它的唯一方法是注销或重新启动电脑,这会强制它们都关闭。

我也遇到了一些奇怪的错误:

Unhandled exception at 0x71002A95 (SDL2_ttf.dll) in SDLGame.exe: 0xC0000005: Access violation reading location 0x00000000.

我不知道这意味着什么以及如何修复它,但我猜它与我需要更改的代码有关。

这是我的代码:

#include <iostream>
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_ttf.h>

// Macros
#define pause system("PAUSE"); // Works on windows only, removed in alpha / beta versions.

// Pre "init" of functions
void QuitGame();
int InitGame();
void processInput();
void InitRects();

// Variables
int FramesPassed = 0;
int FramesPerSecond = 0; // Not used yet

SDL_Renderer* renderer = nullptr;
SDL_Window* window = nullptr;
SDL_Event evnt;

SDL_Rect sprite1_Rect;
SDL_Rect FPS_Text_Rect;

TTF_Font* Sans = TTF_OpenFont("Fonts/Aaargh.ttf", 40);

SDL_Color Color_White = { 255, 255, 255 };

SDL_Surface* FPS_Text_Surface = nullptr;

SDL_Texture* FPS_Text = nullptr;
SDL_Texture* testImg = nullptr;

static bool isRunning = true;

int SDL_main(int argc, char* argv[])
{
    InitGame();
    InitRects();

    std::cout << "Displaying text on screen using SDL TTF doesn't work" << std::endl;
    std::cout << "This happens when the TTF Surface is being rendered on screen" << std::endl;
    std::cout << "check line : 123 and 124." << std::endl;

    while (isRunning)
    {
        FramesPassed++;

        processInput();
        SDL_RenderClear(renderer); // Clears the last/current frame?

        // Render testImage on screen. (needs to be between render present and clear.)
        SDL_RenderCopy(renderer, testImg, NULL, &sprite1_Rect);
        SDL_RenderCopy(renderer, FPS_Text, NULL, &FPS_Text_Rect);

        SDL_RenderPresent(renderer); // Pretty much draws everything again.
    }

    return 0;
    QuitGame();

}

int InitGame()
{

    std::cout << "Game Initializing..." << std::endl;
    std::cout << "TTF SDL Initializing..." << std::endl;

    if (TTF_Init() < 0)
    {
        std::cout << "SDL TTF Failed To Initialize : " << TTF_GetError() << std::endl;
        pause
        QuitGame();
    }
    else
    {

        std::cout << "SDL TTF Initialized Successfully" << std::endl;

        if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
        {
            std::cout << "SDL Initialization Failed : " << SDL_GetError() << std::endl;
            pause
                QuitGame();
        }
        else
        {
            std::cout << "SDL Initializing" << std::endl;

            window = SDL_CreateWindow("Game Title", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1024, 720, SDL_WINDOW_SHOWN);
            if (window == NULL)
            {
                std::cout << "Window Creation Failed : " << SDL_GetError() << std::endl;
                pause
                    QuitGame();
            }
            else
            {
                std::cout << "SDL Initialized Successfully" << std::endl;
                std::cout << "Renderer Initializing..." << std::endl;

                renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
                if (renderer == NULL)
                {
                    std::cout << "Renderer Creation Failed : " << SDL_GetError() << std::endl;
                    pause
                        QuitGame();
                }

                else
                {
                    std::cout << "Renderer Initialized Successfully" << std::endl;
                    // This line (under) crashes game, and crashes visual studio...
                    FPS_Text_Surface = TTF_RenderText_Solid(Sans, "Frames Passed : " + FramesPassed, Color_White);
                    testImg = IMG_LoadTexture(renderer, "images/test.bmp");
                    FPS_Text = SDL_CreateTextureFromSurface(renderer, FPS_Text_Surface);
                }
            }
        }

    }
    std::cout << "Game Has Successfully Initialized!" << std::endl;
    return 0;

}

void InitRects()
{

    sprite1_Rect.h = 32;
    sprite1_Rect.w = 32;
    sprite1_Rect.x = 10;
    sprite1_Rect.y = 10;

    FPS_Text_Rect.h = 100;
    FPS_Text_Rect.w = 50;
    FPS_Text_Rect.x = 2;
    FPS_Text_Rect.y = 2;

}

void processInput()
{
    if (SDL_PollEvent(&evnt)) {

        switch (evnt.type) {

            case SDL_QUIT:
                QuitGame();
                break;

            case SDL_KEYDOWN:

                switch (evnt.key.keysym.sym) {
                    case SDLK_a:
                        sprite1_Rect.x -= 1;
                        break;
                    case SDLK_d:
                        sprite1_Rect.x += 1;
                        break;
                    case SDLK_w:
                        sprite1_Rect.y-= 1;
                        break;
                    case SDLK_s:
                        sprite1_Rect.y += 1;
                        break;
                }

            break;

        }
    }
}

void QuitGame()
{
    isRunning = false;
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

问题是您将字体作为全局变量并立即加载它!

您需要先调用TTF_Init(),然后再加载字体!

通过使用全局变量,在初始化 SDL_TTF 之前加载它,这样 TTF_OpenFont() 将 return 一个 nullptr,如果您尝试读取 nullptr 会给出一个 Access违规读取位置0x00000000错误!

只需在函数 中调用 TTF_OpenFont() 并在 TTF_Init() 之后调用 即可!

提示您在使用 Sans 之前应检查它是否不是 nullptr!