2017-10-29 9 views
-2

Ich habe einen seltsamen Fehler mit SDL_Rect bekommen. Jedes Mal, wenn ich rufe SDL_RenderFillRect, mit diesem Rechteck:SDL_Rect ist größer als angegeben

SDL_Rect rect = {100, 100, 100, 100}; 

ich immer mit dem Rechteck am Ende für die gesamten 800 x 600 Fenster.

Hier ist mein Programm:

#include "SDL.h" 
#include <iostream> 
#include <cstdlib> 
#include <ctime> 
#include <thread> 
#include <string> 

class Window 
{ 
public: 
    Window(std::string title, int width, int height); 
    void runEvents(SDL_Event event); 
    void drawRect(int x, int y, int h, int w); 
    bool closed = false; 
    SDL_Renderer *_renderer; 
    SDL_Window *_window; 

private: 
    int colour = 0; 
}; 

Window::Window(std::string title, int width, int height) 
{ 
    _window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0); 
    _renderer = SDL_CreateRenderer(_window, -1, 0); 
} 

// this function deals with rects (it's supposed to draw a rect when the mouse button is down): 
void Window::runEvents(SDL_Event event) 
{ 
    SDL_Rect rect = { 100, 100, 100, 100 }; 
    switch(event.type) 
    { 
    case SDL_QUIT: 
     closed = true; 
     break; 
    case SDL_KEYDOWN: 
     switch(event.key.keysym.sym) 
     { 
     case SDLK_ESCAPE: 
      closed = true; 
      break; 
     case SDLK_KP_1: 
      // set colour to blue 
      SDL_SetRenderDrawColor(_renderer, 0, 51, 204, 255); 
      std::cout << "Colour set to blue!" << std::endl; 
      colour = 1; 
      break; 
     case SDLK_KP_2: 
      // set colour to red 
      SDL_SetRenderDrawColor(_renderer, 255, 0, 0, 255); 
      std::cout << "Colour set to red!" << std::endl; 
      colour = 2; 
      break; 
     case SDLK_KP_3: 
      // set colour to green 
      SDL_SetRenderDrawColor(_renderer, 51, 204, 51, 255); 
      std::cout << "Colour set to green!" << std::endl; 
      colour = 3; 
      break; 
     case SDLK_KP_4: 
      SDL_SetRenderDrawColor(_renderer, 153, 0, 153, 255); 
      std::cout << "Colour set to purple!" << std::endl; 
      colour = 4; 
      break; 
     case SDLK_KP_0: 
      SDL_SetRenderDrawColor(_renderer, 255, 255, 255, 255); 
      std::cout << "Colour set to white!" << std::endl; 
      colour = 0; 
      break; 
     } 
     break; 
     //this draws the rectangle: 
    case SDL_MOUSEBUTTONDOWN: 
     SDL_SetRenderDrawColor(_renderer, 255, 0, 0, 255); 
     drawRect(rect.h, rect.y, rect.h, rect.w); 
     break; 
     //this removes it 
    case SDL_MOUSEBUTTONUP: 
     switch(colour) 
     { 
     case 1: 
      SDL_SetRenderDrawColor(_renderer, 0, 51, 204, 255); 
      break; 
     case 2: 
      SDL_SetRenderDrawColor(_renderer, 255, 0, 0, 255); 
      break; 
     case 3: 
      SDL_SetRenderDrawColor(_renderer, 51, 204, 51, 255); 
      break; 
     case 4: 
      SDL_SetRenderDrawColor(_renderer, 153, 0, 153, 255); 
      break; 
     case 0: 
      SDL_SetRenderDrawColor(_renderer, 255, 255, 255, 255); 
      break; 
     } 
     drawRect(rect.h, rect.y, rect.h, rect.w); 
     break; 
    } 
} 

//this function is supposed to draw the rect 
void Window::drawRect(int x, int y, int h, int w) 
{ 
    SDL_Rect rect = { x, y, w, h }; 
    SDL_RenderFillRect(_renderer, &rect); 
} 

bool running = true; 

void mouseCheck() 
{ 
    while(running) 
    { 
     int x; 
     int y; 
     SDL_GetMouseState(&x, &y); 
     printf("Mouse is at x: %i and y: %i\n", x, y); 
     SDL_Delay(5000); 
    } 
} 

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

    Window window("Hello World", 800, 600); 
    SDL_Event event; 

    SDL_SetRenderDrawColor(window._renderer, 255, 255, 255, 255); 

    std::thread mousePosition(mouseCheck); 
    mousePosition.detach(); 

    while(!window.closed) 
    { 
     SDL_RenderClear(window._renderer); 
     SDL_RenderPresent(window._renderer); 
     if(SDL_PollEvent(&event)) 
     { 
      window.runEvents(event); 

     } 
    } 
    return 0; 
} 

Antwort

1

Mehrere Probleme:

  • Gerade jetzt Ihre Hauptfeld Schleife ist:

    1. Draw 
    2. Clear 
    3. Present 
    

    Sie wollen:

    1. (re)Set clear color 
    2. Clear 
    3. Draw 
    4. Present 
    
  • Nicht sicher, was Sie mit diesem mouseCheck() Thread versuchen, aber vermeiden, GUI-bezogene SDL-Funktionen von anderen Threads aufzurufen. Wenn Sie diese Informationen in einem anderen Thread benötigen, verwenden Sie thread-sichere Atomics/Queues/Nachrichten, um sie zu kommunizieren.

  • Sie rufen drawRect() in zwei Orten mit rect.h als den ersten Parameter anstelle von rect.x.

  • Ich würde gegen Interleaving-Eingabe Verarbeitung und Rendering empfehlen, wie Sie in runEvents() tun. Aktualisieren Sie den Systemstatus (shouldDrawRect & colour) beim Löschen der Ereigniswarteschlange (while(SDL_PollEvent())) und zeichnen Sie dann einen Rahmen mit dem neuen Status (Window::drawScene()).

  • Sie verarbeiten nur ein einzelnes Ereignis pro Bild. Leeren Sie die Ereigniswarteschlange für jeden Frame über , damit die Ereignisse nicht gesichert und gelöscht werden.

Alle zusammen:

#include "SDL.h" 
#include <iostream> 
#include <cstdlib> 
#include <ctime> 
#include <thread> 
#include <string> 

class Window 
{ 
public: 
    Window(std::string title, int width, int height); 
    void runEvents(SDL_Event event); 
    void drawScene(); 
    void drawRect(int x, int y, int h, int w); 
    bool closed = false; 
    SDL_Renderer *_renderer; 
    SDL_Window *_window; 

private: 
    bool shouldDrawRect; 
    int colour = 0; 
}; 

Window::Window(std::string title, int width, int height) 
{ 
    _window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0); 
    _renderer = SDL_CreateRenderer(_window, -1, 0); 
    shouldDrawRect = false; 
} 

void Window::drawScene() 
{ 
    if(shouldDrawRect) 
    { 
     switch(colour) 
     { 
     case 0: 
      SDL_SetRenderDrawColor(_renderer, 255, 0, 0, 255); 
      break; 
     case 1: 
      SDL_SetRenderDrawColor(_renderer, 0, 51, 204, 255); 
      break; 
     case 2: 
      SDL_SetRenderDrawColor(_renderer, 255, 0, 0, 255); 
      break; 
     case 3: 
      SDL_SetRenderDrawColor(_renderer, 51, 204, 51, 255); 
      break; 
     case 4: 
      SDL_SetRenderDrawColor(_renderer, 153, 0, 153, 255); 
      break; 
     } 

     SDL_Rect rect = { 100, 100, 100, 100 }; 
     drawRect(rect.x, rect.y, rect.h, rect.w); 
    } 
} 

//this function deals with rects (it's supposed to draw a rect when the mouse button is down): 
void Window::runEvents(SDL_Event event) 
{ 
    switch(event.type) 
    { 
    case SDL_QUIT: 
     closed = true; 
     break; 
    case SDL_KEYDOWN: 
     switch(event.key.keysym.sym) 
     { 
     case SDLK_ESCAPE: 
      closed = true; 
      break; 
     case SDLK_KP_1: 
      // set colour to blue 
      std::cout << "Colour set to blue!" << std::endl; 
      colour = 1; 
      break; 
     case SDLK_KP_2: 
      // set colour to red 
      std::cout << "Colour set to red!" << std::endl; 
      colour = 2; 
      break; 
     case SDLK_KP_3: 
      // set colour to green 
      std::cout << "Colour set to green!" << std::endl; 
      colour = 3; 
      break; 
     case SDLK_KP_4: 
      std::cout << "Colour set to purple!" << std::endl; 
      colour = 4; 
      break; 
     case SDLK_KP_0: 
      std::cout << "Colour set to white!" << std::endl; 
      colour = 0; 
      break; 
     } 
     break; 
     //this draws the rectangle: 
    case SDL_MOUSEBUTTONDOWN: 
     shouldDrawRect = true; 
     break; 
     //this removes it 
    case SDL_MOUSEBUTTONUP: 
     shouldDrawRect = false; 
     break; 
    } 
} 

//this function is supposed to draw the rect 
void Window::drawRect(int x, int y, int h, int w) 
{ 
    SDL_Rect rect = { x, y, w, h }; 
    SDL_RenderFillRect(_renderer, &rect); 
} 

bool running = true; 

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

    Window window("Hello World", 800, 600); 
    SDL_Event event; 

    while(!window.closed) 
    { 
     SDL_SetRenderDrawColor(window._renderer, 255, 255, 255, 255); 
     SDL_RenderClear(window._renderer); 

     while(SDL_PollEvent(&event)) 
     { 
      window.runEvents(event); 
     } 
     window.drawScene(); 

     SDL_RenderPresent(window._renderer); 
    } 
    return 0; 
} 
+0

Dies funktioniert wunderbar! vielen Dank. –