悬停时,我试图更改文本的颜色。我不明白为什么它不起作用。

我尝试了许多不同的事情,但似乎找不到解决我问题的方法。

也许我需要使用SDL_FreeSurface之后的其他内容?

这是代码:

int MainGame::mainMenu(){
    TTF_Font *font;
    TTF_Init();
    font = TTF_OpenFont("Myfont.TTF", 30);

    int x, y;
    const int NUMMENU = 2;
    const char* labels[NUMMENU] = { "Play", "Exit" };
    SDL_Surface* menus[NUMMENU];
    bool selected[NUMMENU] = { 0, 0 };
    SDL_Color color[2] = { { 255, 255, 255 }, { 255, 0, 0 } };

    SDL_Window* window = NULL;

    window = SDL_CreateWindow(
        "Main menu",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        1024,
        768,
        SDL_WINDOW_SHOWN
    );
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1,       SDL_RENDERER_ACCELERATED);


    menus[0] = TTF_RenderText_Solid(font, labels[0], color[0]);
    menus[1] = TTF_RenderText_Solid(font, labels[1], color[0]);

    SDL_Texture* Play = SDL_CreateTextureFromSurface(renderer, menus[0]);
    SDL_Texture* Exit = SDL_CreateTextureFromSurface(renderer, menus[1]);


    SDL_Rect pos[NUMMENU];
    pos[0].x = 330;
    pos[0].y = 250;
    pos[0].w = 200;
    pos[0].h = 100;
    pos[1].x = 330;
    pos[1].y = 380;
    pos[1].w = 200;
    pos[1].h = 100;

    SDL_Event event;


    while (1)
    {
        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, Play, NULL, &pos[0]);
        SDL_RenderCopy(renderer, Exit, NULL, &pos[1]);
        SDL_RenderPresent(renderer);
        t = SDL_GetTicks();

        while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
                case SDL_QUIT:
                    SDL_FreeSurface(menus[0]);
                    SDL_FreeSurface(menus[1]);
                    return 1;
                case SDL_MOUSEMOTION:
                    x = event.motion.x;
                    y = event.motion.y;

                    for (int i = 0; i < NUMMENU; i += 1) {
                        if (x >= pos[i].x && x <= pos[i].x + pos[i].w && y >= pos[i].y && y <= pos[i].y + pos[i].h)
                        {
                            if (!selected[i]) // this part
                            {
                                selected[i] = 1;
                                SDL_FreeSurface(menus[i]);
                                menus[i] = TTF_RenderText_Solid(font, labels[i], color[1]);
                            }
                        }
                        else
                        {
                            if (selected[i])
                            {
                                selected[i] = 0;
                                SDL_FreeSurface(menus[i]);
                                menus[i] = TTF_RenderText_Solid(font, labels[i], color[0]);
                            }
                        }
                    }
                    break;
                case SDL_MOUSEBUTTONDOWN:
                    x = event.button.x;
                    y = event.button.y;
                    for (int i = 0; i < NUMMENU; i += 1) {
                        if (x >= pos[i].x && x <= pos[i].x + pos[i].w && y >= pos[i].y && y <= pos[i].y + pos[i].h)
                        {
                            SDL_FreeSurface(menus[0]);
                            SDL_FreeSurface(menus[1]);
                            return i;
                        }
                    }
                    break;
                case SDL_KEYDOWN:
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                    {
                        SDL_FreeSurface(menus[0]);
                        SDL_FreeSurface(menus[1]);
                        return 0;
                    }
            }
        }
    }

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

最佳答案

您的问题确实在这里:

if (!selected[i]) // this part
{
    selected[i] = 1;
    SDL_FreeSurface(menus[i]);
    menus[i] = TTF_RenderText_Solid(font, labels[i], color[1]);
}

在这里,您正在更新menus[i] SDL_Surface。但是在渲染代码中,您可以执行以下操作:
SDL_RenderCopy(renderer, Play, NULL, &pos[0]);
SDL_RenderCopy(renderer, Exit, NULL, &pos[1]);

您永远不会更新PlayExit

您宁可从SDL_Texture中出错,也可以临时创建和销毁SDL_Surface:

在里面 :
SDL_Textue* menus[NUMMENU];

for (int i = 0; i < NUMMENU; i += 1)
{
    SDL_Surface* temp = TTF_RenderText_Solid(font, labels[i], color[i]);
    menus[0] = SDL_CreateTextureFromSurface(renderer, temp);
}

更新`SDL_Texture`:
if (!selected[i]) // this part
{
    selected[i] = 1;

    SDL_Surface* temp = TTF_RenderText_Solid(font, labels[i], color[1]);
    menus[i]  = SDL_CreateTextureFromSurface(renderer, temp);
    SDL_FreeSurface(temp);
}

渲染:
for (int i = 0; i < NUMMENU; i += 1)
    SDL_RenderCopy(renderer, menu[i], NULL, &pos[i]);

最后的建议是:创建一个示例,使人们无需修改代码即可运行。并使用标准字体。否则,您的font指针将为null,应用程序将为segfault

08-04 15:01