擦除线条的SDL2功能?

SDL2 function that erases lines?

我正在制作一个创建线条的程序,如何删除线条?有它的功能吗?

我已经尝试使用 SDL_RenderClear() 但它没有用。 (请注意,我是初学者,我不是美国本土人,而且我只有 10 岁,所以请用简单的方式解释。)

这是我的行创建代码:

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

using namespace std;

int main( int argc, char * argv[] )
{
    SDL_Init(SDL_INIT_EVERYTHING);

    SDL_Window *janela = NULL;
    SDL_Renderer *renderer = NULL;
    bool roda = true;
    SDL_Event evento;
    int x;
    int y;
    int x2;
    int y2;
    janela = SDL_CreateWindow( "janela" , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,500 , 500 , SDL_WINDOW_RESIZABLE);
    renderer = SDL_CreateRenderer(janela , -1 , SDL_RENDERER_ACCELERATED);


    while (roda) {
    SDL_Event evento;
    while (SDL_PollEvent(&evento)) {
       switch(evento.type){

         case SDL_QUIT:
         roda = false;
         break;

         case SDL_MOUSEBUTTONDOWN:{
         x = evento.motion.x;
         y = evento.motion.y;
         break;}

         case SDL_MOUSEBUTTONUP:
         while(roda){
         x2 = evento.motion.x;
         y2 = evento.motion.y;
         SDL_SetRenderDrawColor(renderer , 255 , 0 , 0 , 255);
         SDL_SetRenderDrawColor(renderer , 125 , 234 , 253 , 255);
         SDL_RenderDrawLine(renderer , x , y , x2 , y2);
         SDL_RenderPresent(renderer);
         break;}

         case SDL_KEYDOWN:{
         switch(evento.key.keysym.sym){
         case SDLK_b:{


          SDL_RenderClear(renderer);


             }
            }
           }
          }
         }
        }


    SDL_DestroyWindow(janela);
    janela = NULL;
    SDL_DestroyRenderer(renderer);
    renderer = NULL;
    SDL_Quit();

    return 1;
}

我期望的是线条被擦除,但它并没有发生。

典型的主循环基本上是这样的:

while(!quit) {
    while(pool_event()) {
        // change state to react to event
    }

    clear_previous_frame();
    for each line {
        draw_line();
    }
    present();
}

因此,您应该始终清除并重新绘制线条,如果事件如此,则添加新的线条状态(但还没有绘制它 - 事件处理不应该这样做,否则它会变得非常 复杂)。保留前一帧的内容并添加更多行是有问题的;简短的解释是因为 SDL_RenderPresent documentationThe backbuffer should be considered invalidated after each present(而长的解释基本上是一个列表,说明为什么这样说)。

要跟踪要绘制的线条,您需要将它们保存在某个地方。 std::vector 可能是一个简单的选择,如果您的要求不反对的话。

总而言之,您的问题修改后的代码加上一些注释:

#include <vector>
#include <SDL.h>

struct line {
    int x0, y0, x1, y1;
};

int main( int argc, char * argv[] )
{
    SDL_Init(SDL_INIT_EVERYTHING);

    SDL_Window *janela = NULL;
    SDL_Renderer *renderer = NULL;
    bool roda = true;
    int x;
    int y;
    janela = SDL_CreateWindow( "janela" , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,500 , 500 , SDL_WINDOW_RESIZABLE);
    renderer = SDL_CreateRenderer(janela , -1 , SDL_RENDERER_ACCELERATED);

    std::vector<line> lines;

    while (roda) {
        SDL_Event evento;
        while (SDL_PollEvent(&evento)) {
            switch(evento.type){
            case SDL_QUIT:
                roda = false;
                break;

            case SDL_MOUSEBUTTONDOWN:
                // save starting coordinates
                x = evento.motion.x;
                y = evento.motion.y;
                break;

            case SDL_MOUSEBUTTONUP: {
                // add new line to draw
                line l = { x, y, evento.motion.x, evento.motion.y };
                lines.push_back(l);
            } break;

            case SDL_KEYDOWN:
                if(evento.key.keysym.sym == SDLK_b) {
                    // drop lines
                    lines.resize(0);
                }
                break;
            }
        }

        // clear previous contents - in most cases, screen content is
        // invalidated after RenderPresent and you need to draw again
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);    // your 'clear' colour
        SDL_RenderClear(renderer);

        // draw all accumulated lines
        SDL_SetRenderDrawColor(renderer, 125, 234, 253, 255);    // your lines colour
        for(const line &l : lines) {
            SDL_RenderDrawLine(renderer, l.x0, l.y0, l.x1, l.y1);
        }

        // all drawn - present
        SDL_RenderPresent(renderer);
    }


    SDL_DestroyWindow(janela);
    SDL_DestroyRenderer(renderer);
    SDL_Quit();

    return 0;   // 0 is 'success' return code, non-0 is failure
}