У меня очень странная проблема с SDL и особенно с нажатиями клавиш. Я сделал простую программу, которая должна отображать различные сообщения на экране в зависимости от того, какая клавиша со стрелкой нажата, однако она отображает сообщения, только если я нажимаю клавиши со стрелками несколько раз подряд. Вот мой код:
#include "SDL/SDL.h"#include "SDL/SDL_image.h"#include "SDL/SDL_ttf.h"#include <iostream>
#include <string>
bool quit = false;
SDL_Event arrows;
SDL_Event xOut;
SDL_Surface *titleText;
SDL_Surface *keyText;
SDL_Surface *screen = NULL;
SDL_Surface *backgroundOPT = NULL;
const int screenW = 640;
const int screenH = 480;
const int screenBPP = 32;
SDL_Surface *loadIMG(std::string filename)
{
SDL_Surface *img = IMG_Load(filename.c_str());
SDL_Surface *imgOPT = SDL_DisplayFormat(img);
SDL_FreeSurface(img);
return imgOPT;
}
void blitIMG(int pX, int pY, SDL_Surface *window, SDL_Surface *image, int cpX, int cpY, int cpH, int cpW)
{
SDL_Rect positionIMG;
positionIMG.x = pX;
positionIMG.y = pY;
SDL_Rect clipP;
clipP.x = cpX;
clipP.y = cpY;
clipP.h = cpH;
clipP.w = cpW;
SDL_BlitSurface(image, &clipP, window, &positionIMG);
SDL_Flip(window);
}
SDL_Surface *loadText(int red, int blue, int green, std::string fontname, int fontSize, std::string text)
{
int color1 = red;
int color2 = blue;
int color3 = green;
SDL_Color textColor = {color1, color2, color3};
TTF_Font *font1 = TTF_OpenFont(fontname.c_str(), fontSize);
SDL_Surface *message1 = TTF_RenderText_Solid(font1, text.c_str(), textColor);
return message1;
}
int main(int argc, char* args[])
{
TTF_Init();
SDL_Init(SDL_INIT_EVERYTHING);
screen = SDL_SetVideoMode(screenW, screenH, screenBPP, SDL_SWSURFACE);
while(quit == false)
{
SDL_PollEvent(&arrows);
if(arrows.type == SDL_KEYDOWN)
{
switch(arrows.key.keysym.sym)
{
case SDLK_UP: keyText = loadText(255, 200, 50, "lazy.ttf", 50, "Up was pressed");
break;
case SDLK_DOWN: keyText = loadText(255, 200, 50, "lazy.ttf", 50, "Down was pressed");
break;
case SDLK_LEFT: keyText = loadText(255, 200, 50, "lazy.ttf", 50, "Left was pressed");
break;
case SDLK_RIGHT: keyText = loadText(255, 200, 50, "lazy.ttf", 50, "Right was pressed");
break;
default:;
}
}
blitIMG(0, 0, screen, backgroundOPT = loadIMG("hellsing.png"), 0, 0, 1000, 1000);
blitIMG(25, 20, screen, titleText = loadText(255, 200, 50, "lazy.ttf", 50, "Die, Freaks!"), 0, 0, 640, 480);
blitIMG(100, 300, screen, keyText, 0, 0, 640, 480);
SDL_PollEvent(&xOut);
if(xOut.type == SDL_QUIT)
{
quit = true;
}
}
SDL_FreeSurface(backgroundOPT);
SDL_FreeSurface(titleText);
SDL_FreeSurface(keyText);
SDL_Quit();
return 0;
}
Буду признателен за любую помощь, я застрял на этом в течение нескольких недель.
У вас есть пара проблем.
Nº1: SDL_PoolEvent должен быть в цикле while, который внутри содержит материал для обработки событий. Что-то вроде этого:
while(SDL_PollEvent(&event)){
if(event.type == SDL_KEYDOWN)
{
switch(event.key.keysym.sym)
{
case SDLK_UP: keyText = loadText(255, 200, 50, "lazy.ttf", 50, "Up was pressed");
break;
case SDLK_DOWN: keyText = loadText(255, 200, 50, "lazy.ttf", 50, "Down was pressed");
break;
case SDLK_LEFT: keyText = loadText(255, 200, 50, "lazy.ttf", 50, "Left was pressed");
break;
case SDLK_RIGHT: keyText = loadText(255, 200, 50, "lazy.ttf", 50, "Right was pressed");
break;
default:;
}
}
}
Nº2: Вам не нужно 2 SDL_Events, достаточно одного, но я не думаю, что это проблема, если у вас есть два, просто менее организованных и, возможно, медленнее. Вы бы просто поставить
if(xOut.type == SDL_QUIT)
{
quit = true;
}
в предыдущем цикле я показал вам.
№3: у вас не должно быть SLD_Flip (окна), в вашей функции рисования вы должны иметь в конце основного цикла, после того как вы все нарисовали.
Любые вопросы, не стесняйтесь спрашивать.