I can't make SDL wait for a an event. When I try to the window just briefly flashes on my screen and then disappears, I don't get any errors or anything in my IDE, nothing in the build log either. I looked at lazyfoo and the SDL wiki, but no help. I'm using Code blocks and SDL 2.0.3 Here's what I have so far:
while(&event != NULL && !quit)
{
while(SDL_PollEvent(&event) > 0)
{
if(event.type == SDL_QUIT)
{
quit = true;
}
else
{
if(event.type == SDL_KEYDOWN)
{
switch(event.key.keysym.sym)
{
case SDLK_LEFT:
currentSurface = keyPressSurfaces[KEY_PRESS_LEFT];
break;
case SDLK_UP:
currentSurface = keyPressSurfaces[KEY_PRESS_UP];
break;
case SDLK_RIGHT:
currentSurface = keyPressSurfaces[KEY_PRESS_RIGHT];
break;
case SDLK_DOWN:
currentSurface = keyPressSurfaces[KEY_PRESS_DOWN];
break;
default:
currentSurface = keyPressSurfaces[KEY_PRESS_DEFAULT];
break;
}
}
}
}
}
Any suggestions?
you are polling for an event SDL_PollEvent, if you want to wait for an event, you should use SDL_WaitEvent
First, is quit false before you enter this loop?
If there are no events to poll, I believe event is NULL, causing your program to exit the next time it sees while(&event != NULL && !quit). If there are no immediate events on startup, you might not ever make it into that loop. Edit: Whoops - thought event was a pointer:
The while (SDL_PollEvent(&event)) line will loop through until all pending events have been handled. The outter while (!quit) would then keep your program open even if there are no events to process at the moment.
Related
I am having trouble dealing with input from the keyboard. Somehow all the letter ones are extremely slow(always a big delay), most of the time it just doesn't load at all. But the up down left right and number keys all work really well. Does anyone know why?
This is my program:
while (!quit)
{
while (SDL_PollEvent(&e) != 0 )
{
SDL_StartTextInput();
//User requests quit
switch (e.type) {
case SDL_QUIT:
quit = true;
break;
case SDL_TEXTINPUT:
if (e.key.keysym.sym == SDLK_w)
std::cout << "w ";
break;
case SDL_KEYDOWN:
if (e.key.keysym.sym == SDLK_1)
std::cout << "1 ";
break;
}
As already mentioned in your comments, you never check the event type.
event.type can be SDL_TEXTINPUT or SDL_KEYDOWN for example.
Here I have a typical event loop copied from one of my projects:
while (SDL_PollEvent(&event)) {
SDL_StartTextInput();
switch (event.type) {
case SDL_QUIT:
appRunning = false;
break;
case SDL_TEXTINPUT:
// here you can use event.text.text; to
break;
case SDL_KEYDOWN:
char keyDown = event.key.keysym.scancode;
break;
}
}
Here is the official list of SDL_Events: https://wiki.libsdl.org/SDL2/SDL_Event
SDL provides event handlers for keyboard input.
SDL_Event e;
.
.
/* Poll for events. SDL_PollEvent() returns 0 when there are no */
/* more events on the event queue, our while loop will exit when */
/* that occurs. */
while(SDL_PollEvent(&e)){
/* We are only worried about SDL_KEYDOWN and SDL_KEYUP events */
switch(event.type){
case SDL_KEYDOWN:
//Keypress
break;
case SDL_KEYUP:
//Key Release
break;
default:
break;
}
Then, you can get the value of key->keysym.sym for the keyboard input.
I'm developing a simple game in OpenGL and using the SDL library to handle my input.
The game uses several keyboard buttons for input. Two arrow keys, the space bar, the 'r' button to reset the game and escape to close it.
What's currently happening is that the output or the methods being called when these buttons are pressed when I first launch the game are mismatched. (i.e left arrow performs the right arrow's method). This random behaviour ends once I press each of the buttons the game uses apart from the escape button once.
I'm wondering if there is something I'm missing as it feels like I have to 'assign' each button on each launch of the game. I've provided my input handling code below.
if (e.type == SDL_KEYDOWN) {
switch (e.key.keysym.sym) {
case SDLK_ESCAPE:
m_isClosed = true;
break;
case SDLK_SPACE:
m_selection = true;
break;
case SDLK_LEFT:
m_leftPressed = true;
break;
case SDLK_RIGHT:
m_rightPressed = true;
break;
case SDLK_r:
m_reset = true;
break;
}
}
if(e.type == SDL_KEYUP)
switch (e.key.keysym.sym)
{
case SDLK_LEFT:
m_leftPressed = false;
m_keydown = false;
break;
case SDLK_RIGHT:
m_rightPressed = false;
m_keydown = false;
break;
case SDLK_SPACE:
m_selection = false;
m_keydown = false;
break;
case SDLK_r:
m_reset = false;
m_keydown = false;
break;
}
}
Each event handler simply sets a boolean used for the game logic in another class. If you think you need to see anymore code in order to help me let me know.
It turns out that I had not initialised the booleans corresponding to the button listeners to false. A silly mistake but I thought I should provide the solution nonetheless.
I have this piece of code:
while (SDL_PollEvent(&event)) {
if (event.type == SDL_KEYDOWN) {
switch(event.key.keysym.sym) {
case SLDK_UP: dir=1; break;
case SLDK_DOWN: dir=2; break;
case SLDK_RIGHT: dir=3; break;
case SLDK_LEFT: dir=4; break;
default: break;
}
}
else if (event.type == SDL_QUIT)
quit = true;
in order to manage key presses for a game i'm writing. (BTW I'm following lazy foo's 8th tut for that)
The thing is that the compiler complains about SLDK_UP, SLDK_DOWN and so on. It states that they are not declared in this scope. Any suggestions?
You've got a simple typo with SLDK_* which should be SDLK_*.
I am making an RTS in C++ using SDL for graphics.
Every time I run the game, it crashes without errors or anything in the compiler debug window. It doesn't crash immediately or consistently, sometimes taking 10 seconds to crash and other times taking 2 minutes to crash.
When I played around with return values (at the end of the main function) it turned out it wasn't crashing, but rather quitting as the return values were consistent with what I changed it to.
The only theory that I have is that my poll event loop is glitching and telling the program to quit when it isn't supposed to.
Here is my event loop, contained within my game loop:
if( SDL_PollEvent( &event ) )
{
if( event.type == SDL_MOUSEMOTION )
{
mx = event.motion.x;
my = event.motion.y;
}
if( event.type == SDL_MOUSEBUTTONDOWN )
{
if( hut.getselected() && hut.getplacable() )
{
hut.place( map );
}
}
if( event.type == SDL_QUIT )
{
quit = true;
}
switch( event.key.keysym.sym )
{
case SDLK_ESCAPE: quit = true; break;
}
}
Is it possible that when the mouse moves or clicks, that it is confusing it for exiting? I don't think the ram is overloading either because it only displays what it needs to tile-wise.
Is it also possible that my compiler, VisualC++, is screwing up?
How about changing the switch at end of your snippet to:
if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_ESCAPE) {
quit = true;
}
Because in your code you check keysym for all events, so usually event is of wrong type when you test if it is escape, and you get "garbage" value for keysym, and sometimes it matches with ESC.
Actually might be good idea to test the event.type with switch:
switch(event.type) {
case SDL_MOUSEMOTION:
//....
break;
case SDK_KEYDOWN:
switch(event.key.keysym.sym) {
case SDLK_ESCAPE:
quit = true;
break;
// cases for other keypresses
}
break;
// cases for other events
}
Take a look at this piece of code here:
void game::startLoop()
{
while(QUIT == false)
{
getRoomUpdate();
applySurface(-15, 280, zombie_lefthand, buffer);
applySurface(455, 280, zombie_righthand, buffer);
SDL_Flip(buffer);
while(SDL_PollEvent(&gameEvent))
{
if(gameEvent.type == SDL_QUIT)
{
QUIT = true;
}
}
while(SDL_WaitEvent(&keyEvent))
{
switch(keyEvent.type)
{
case SDL_KEYDOWN:
switch(keyEvent.key.keysym.sym)
{
//blahkeypress
}
}
}
}
}
I'm trying to figure out how to allow SDL_QUIT to work while we're waiting for a keypress. Is there a way to do this or do you guys have a better idea?
I'm a bit of a newbie so please be specific. :D
The name keyEvent is misleading. SDL_WaitEvent will wait for any sort of event, including QUIT.
SDL_Event event;
SDL_WaitEvent(&event);
switch (event.type) {
case SDL_QUIT:
quit = true;
break;
/* cases for keyboard events, etc. */
}
Minimal changes:
You could add if (QUIT) break; after the inner while loop that sets QUIT.
Or, you could move the outer while loop to a separate function and add a return; after QUIT = true;.
Better changes:
Refactor your code similar to many examples available on the web (at sourceforge, or at molly rocket, or just google it).