SDLK_F1 key case not working - sdl

I am trying to catch the event for F1 key in SDL in C++.
But,somehow i cannot see any changes after pressing the F1 key.But,when i wnat to toggle my animation objects on the screen i make use SDL_t case to do so,and it is executing fine.
Just not geting why is it not taking the F1 key.
Here is the switch case for handling key press events:
SDL_Event event;
bool done = false;
bool keyPress = false;
while ( not done ) {
draw();
SDL_Flip(screen);
SDL_PollEvent(&event);
if (event.type == SDL_QUIT) { break; }
if(event.type == SDL_KEYUP) { keyCatch = false; }
if(event.type == SDL_KEYDOWN) {
switch ( event.key.keysym.sym ) {
case SDLK_ESCAPE : done = true; break;
case SDLK_q : done = true; break;
case SDLK_F1 : {
if(!keyCatch){
keyPress=true;
//this method is from another class.
io.printMessageAt("F1 is selected:",50,10);
currentOrb = (currentOrb+1) % orbs.size();
}
break;
}
case SDLK_t : case SDLK_SPACE :
if ( !keyPress ) {
//something
}
break;
case SDLK_p : {
if (!keyPress) {
keyPress = true;
//something
}
break;
}
default : break;
}
}
}
NOTE: i cannot give the entire code here.The above is my part what i am trying to do.

Double-check that your window manager or a hotkey daemon isn't consuming your F1's before they hit your process.
This works fine (F1 closes the program) on my system:
#include <SDL.h>
int main( int, char** )
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Surface* screen = SDL_SetVideoMode(640, 480, 32, SDL_ANYFORMAT);
SDL_Event event;
bool done = false;
bool keyPress = false;
while ( !done )
{
SDL_Flip(screen);
SDL_PollEvent(&event);
if(event.type == SDL_QUIT)
{
break;
}
if(event.type == SDL_KEYUP)
{
keyPress = false;
}
if(event.type == SDL_KEYDOWN)
{
switch ( event.key.keysym.sym )
{
case SDLK_ESCAPE:
case SDLK_q:
done = true;
break;
case SDLK_F1:
if(!keyPress)
{
keyPress=true;
done = true;
}
break;
case SDLK_t:
case SDLK_SPACE:
if ( !keyPress )
{
//something
}
break;
case SDLK_p:
if (!keyPress)
{
keyPress = true;
//something
}
break;
default:
break;
}
}
}
SDL_Quit();
return 0;
}
I did notice that keyCatch was undefined. I replaced it with keyPress.

Related

Not recognizing keyboard input

whenever I press a key nothing happens, there are no errors either, rather odd this is.
Here is the init function:
bool Game::init(int resx, int resy, bool fullscreen)
{
tm = new TextureManager();
int flags = 0;
if(fullscreen)
{
flags = SDL_WINDOW_FULLSCREEN;
}
if(SDL_Init(SDL_INIT_EVERYTHING) >= 0)
{
g_pWindow = SDL_CreateWindow("Pong", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, resx, resy, flags);
if(g_pWindow != 0)
{
g_pRenderer = SDL_CreateRenderer(g_pWindow, -1, 0);
if(g_pRenderer != 0)
{
running = true;
tm->load("/Users/WilsonKoder/C++P/projects/Pong/Pong/Images/bg.png", "bg", g_pRenderer);
tm->load("/Users/WilsonKoder/C++P/projects/Pong/Pong/Images/paddle.png", "player1", g_pRenderer);
tm->load("/Users/WilsonKoder/C++P/projects/Pong/Pong/Images/paddle.png", "player2", g_pRenderer);
tm->load("/Users/WilsonKoder/C++P/projects/Pong/Pong/Images/ball.png", "ball", g_pRenderer);
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
return false;
}
Here is my event handler:
void Game::handleEvents()
{
SDL_Event event;
switch (SDL_PollEvent(&event)) {
case SDL_KEYDOWN:
p1MoveUp = true;
break;
case SDL_KEYUP:
p1MoveUp = false;
break;
default:
break;
}
}
Here is my update function:
void Game::update()
{
if (p1MoveUp)
{
std::cout << "asfasfasf" << std::endl; //for debug purposes :)
p1YPos -= 5;
}
}
and last but not least, here is main.cpp (excluding includes...)
Game *g_game = 0;
int main(int argc, const char * argv[])
{
g_game = new Game();
g_game->init(800, 600, false);
while(g_game->isRunning())
{
g_game->handleEvents();
g_game->update();
g_game->render();
}
g_game->clean();
SDL_Quit();
return 0;
}
You are using the SDL_PollEvent incorrectly. The function does not return the type of event, but rather 1 if there are still items in the event queue, or 0 if the queue is empty.
So you'd want to poll events as long as there are things in the queue and THEN do a switch over the event.type as such:
void Game::handleEvents()
{
SDL_Event event;
// Poll events until the queue is empty...
while(SDL_PollEvent(&event)) {
// ...then check the event.
switch (event.type) {
case SDL_KEYDOWN:
p1MoveUp = true;
break;
case SDL_KEYUP:
p1MoveUp = false;
break;
default:
break;
}
}
}
EDIT: Note that currently ALL key down and up events of each key on the keyboard would cause the p1MoveUp flag to switch. Within your SDL_KEYDOWN and SDL_KEYUP you normally would also check which key has been pressed and act accordingly. You can do this like this:
if(event.key.keysym.sym == SDLK_UP) ...
This would check if the keycode for the "Up Cursor" has been pressed or not. There is a difference between a key scancode and a keycode, for which I would advise you to check the latter as shown above. You can find all these SDL defined keycodes here (look at the rightmost column): https://wiki.libsdl.org/SDL_Keycode
Please note that the event handler can grow quite rapidly if you are checking for different keys and different key events, so I'd suggest that you implement an extra class or other means of encapsulation once you are comfortable with the event mechanism of SDL.
SDL_PollEvent returns true or false. https://wiki.libsdl.org/SDL_PollEvent
If SDL_PollEvent returns true, then 'event' is set. Then do your switch on event.type instead.

Handling multiple keypressess at the same time in SDL

I'm making a simple top down 2D shooter, where you move with WASD and shoot in the direction you're looking at with space. I can move and shoot just fine, but I can't do them both at the same time. For example if I'm shooting and start moving, my character will stop shooting until I release and press space again, and if I then start moving in another direction I have to release and press space again.
Here's my main method:
int main(int argc, char* args[])
{
if (!init())
{
log("Failed to initialize!\n");
}
else
{
log("Initialized SDL and SDL subsystems. \nLoading assets:\n");
if (!loadAssets())
{
printf("Failed to load assets!\n");
}
else
{
log("All assets loaded successfully.\n");
bool running = true;
SDL_Event e;
std::vector<Shot> shots;
LTimer shotTimer;
float cooldown = 250.0f;
float previousCooldown = 0.0f;
Player player;
log("Game running.\n");
shotTimer.start();
while (running)
{
while (SDL_PollEvent(&e) != 0)
{
if (e.type == SDL_QUIT)
{
log("SDL_QUIT event triggered.\n");
running = false;
}
else if (e.type == SDL_KEYDOWN)
{
switch (e.key.keysym.sym)
{
case SDLK_ESCAPE:
{
running = false;
break;
}
}
}
player.handleEvent(e);
if (SDL_GetTicks() - previousCooldown > cooldown)
{
previousCooldown = SDL_GetTicks();
shots = shoot(e, player, shots);
}
}
player.move();
for (int i = 0; i < shots.size(); i++)
{
shots[i].move();
}
/*if (shotTimer.getTicks() >= cooldown)
shotTimer.restart();*/
SDL_SetRenderDrawColor(renderer, 0xff, 0xff, 0xff, 0xff);
SDL_RenderClear(renderer);
background.render(0, 0);
for (int i = 0; i < shots.size(); i++)
{
shots[i].render();
}
player.render();
SDL_RenderPresent(renderer);
}
}
}
close();
return 0;
}
Here's my shoot() function, which is probably what's causing this:
std::vector<Shot> shoot(SDL_Event& e, Player player, std::vector<Shot> shots)
{
bool shoot = false;
if (e.type = SDL_KEYDOWN && e.key.repeat == 1)
{
switch (e.key.keysym.sym)
{
case SDLK_SPACE:
{
shoot = true;
break;
}
}
}
else if (e.type = SDL_KEYUP && e.key.repeat == 1)
{
switch (e.key.keysym.sym)
{
case SDLK_SPACE:
{
shoot = false;
break;
}
}
}
if (shoot)
{
Shot newShot(player.getDir(), player);
shots.push_back(newShot);
}
return shots;
}
And this is how I move the player
void Player::handleEvent(SDL_Event& e)
{
if (e.type == SDL_KEYDOWN && e.key.repeat == 0)
{
switch (e.key.keysym.sym)
{
case SDLK_w: mVelY -= PLAYER_VEL; mDir = 0; break;
case SDLK_s: mVelY += PLAYER_VEL; mDir = 1; break;
case SDLK_d: mVelX += PLAYER_VEL; mDir = 2; break;
case SDLK_a: mVelX -= PLAYER_VEL; mDir = 3; break;
}
}
else if (e.type == SDL_KEYUP && e.key.repeat == 0)
{
switch (e.key.keysym.sym)
{
case SDLK_w: mVelY += PLAYER_VEL; break;
case SDLK_s: mVelY -= PLAYER_VEL; break;
case SDLK_d: mVelX -= PLAYER_VEL; break;
case SDLK_a: mVelX += PLAYER_VEL; break;
}
}
}
Separate your event polling from the rest of the game logic.
Poll all events once per frame in a separate function and store the state of the keystates into an array. Then, when you need the state, simply check the array.
You can also use SDL_GetKeyboardState to sample the surrent state of the keys, without having to handle the key events yourself.

allegro 5 no events work

no events work in my "game" if I test the actions themselves that should happen (like if I put the moving function into the loop itself or the firing function, it works perfectly), but no event works, closing the display, with esc or pressing X, any pressed key, nothing is seen.
I cannot find the mistake in my code, could anyone please help? The game loop is bellow and all of the main function is here : http://pastebin.ca/2468619
while(!done)
{
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
{
std::cout << "EXITING MOFO";
done= true;
}
else if(ev.type == ALLEGRO_KEY_DOWN)
{
switch(ev.keyboard.keycode)
{
case ALLEGRO_KEY_ESCAPE:
done = true;
break;
case ALLEGRO_KEY_A:
keys[A] = true;
break;
case ALLEGRO_KEY_S:
keys[S] = true;
break;
case ALLEGRO_KEY_D:
keys[D] = true;
break;
case ALLEGRO_KEY_W:
keys[W] = true;
break;
case ALLEGRO_KEY_SPACE:
fireWeapon(0);
break;
case ALLEGRO_KEY_LEFT:
keys[LEFT] = true;
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = true;
break;
case ALLEGRO_KEY_UP:
keys[UP] = true;
break;
case ALLEGRO_KEY_DOWN:
keys[DOWN] = true;
break;
case ALLEGRO_KEY_ENTER:
std::cout << "FUCK";
fireWeapon(1);
break;
}
}
else if(ev.type == ALLEGRO_KEY_UP)
{
switch(ev.keyboard.keycode)
{
case ALLEGRO_KEY_A:
keys[A] = false;
break;
case ALLEGRO_KEY_S:
keys[S] = false;
break;
case ALLEGRO_KEY_D:
keys[D] = false;
break;
case ALLEGRO_KEY_W:
keys[W] = false;
break;
case ALLEGRO_KEY_LEFT:
keys[LEFT] = false;
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = false;
break;
case ALLEGRO_KEY_UP:
keys[UP] = false;
break;
case ALLEGRO_KEY_DOWN:
keys[DOWN] = false;
break;
}
}
else if(ev.type == ALLEGRO_EVENT_TIMER)
{
render = true;
moveTank();
updateBullet(0);
updateBullet(1);
}
if(render && al_is_event_queue_empty(event_queue))
{
render = false;
//al_set_target_bitmap(back);
//al_clear_to_color(al_map_rgb(0,0,0));
drawTank(0);
drawTank(1);
drawBullet(0);
drawBullet(1);
//setupDebris();
al_flip_display();
al_clear_to_color(al_map_rgb(0,0,0));
}
I watched the same tutorial.
You have to add
al_register_event_source(event_queue, al_get_display_event_source(display))
to main.

C++ SDL program terminates immediately

I've been following LazyFoo's tutorial for a while. But I haven't been able to get this to initialize a week a go. I went back to it recently, after error checking, I found it that the window initializes properly, but the images won't load. What is the reason for it?
#include "SDL/SDL.h"
#include <string>
//setting screen info
const int SCH=640;
const int SCW=480;
const int BBP=32;
const char* name = "TEHGAEM";
// sprite height and width
const int SPH=45;
const int SPW=45;
//initilize event
SDL_Event event;
//loading surfaces for screen, sprite, and temp sprite
SDL_Surface *screen=NULL;
SDL_Surface *sprite=NULL;
SDL_Surface *temp = NULL;
//making class for movable objects
class Player
{
private:
int x,y;
int xVel,yVel;
public:
Player();
void show();
void move();
void handle_input();
};
//initializing variables
Player::Player()
{
x=0;
y=0;
xVel=0;
yVel=0;
}
//intended to show player picture
void Player::show()
{
SDL_Rect pos;
pos.x=x;
pos.y=y;
SDL_BlitSurface(sprite, NULL, screen, &pos);
SDL_UpdateRects(screen, 1, &pos);
}
//setting input
void Player::handle_input()
{
if (event.type ==SDL_KEYDOWN)
{
switch (event.key.keysym.sym)
{
case SDLK_UP: yVel -= SPH /2; break;
case SDLK_DOWN: yVel += SPH /2; break;
case SDLK_LEFT: xVel -=SPW /2; break;
case SDLK_RIGHT: xVel +=SPW /2; break;
}
}
if (event.type == SDL_KEYUP)
{
switch(event.key.keysym.sym)
{
case SDLK_UP: yVel += SPH /2; break;
case SDLK_DOWN: yVel -= SPH /2; break;
case SDLK_LEFT: xVel +=SPW /2; break;
case SDLK_RIGHT: xVel -=SPW /2; break;
}
}
}
void Player::move()
{
x=+xVel;
y=+yVel;
if (x >= SCW)
{
x-10;
}
if (y >= SCH)
{
y-10;
}
}
//initializing program
bool init()
{
if (SDL_Init(SDL_INIT_EVERYTHING)==-1)
{
return false;
}
screen = SDL_SetVideoMode(SCH,SCW,BBP, SDL_SWSURFACE);
if (screen == NULL)
{
return false;
}
SDL_WM_SetCaption(name, NULL);
return true;
}
//loading images
bool somethings()
{
temp = SDL_LoadBMP("sprite.bmp");
if (temp == NULL)
{
return false;
}
sprite = SDL_DisplayFormat (temp);
if (sprite ==NULL)
{
return false;
}
SDL_FreeSurface(temp);
return true;
}
//clean up function
void clean()
{
SDL_FreeSurface(sprite);
SDL_Quit();
}
int main(int argc, char* args[])
{
Player P1;
bool quit;
if (init() == false)
{
return 1;
}
if (somethings() ==false)
{
return 1;
}
while (quit ==false)
{
while (SDL_PollEvent(&event))
{
P1.handle_input();
if (event.type == SDL_QUIT)
{
quit == true;
}
}
if (SDL_Flip(screen) ==-1)
{
return 1;
}
P1.move();
P1.show();
}
clean();
return 0;
}
This isn't completely related to your problem but the varible bool quit; isn't defined as true or false before the main while( quit == false ) { ... }loop. This could produce undefined while loop behavior.
int main(int argc, char* args[])
{
Player P1;
bool quit = false; // CHANGE THIS AND SEE WHAT HAPPENS
if (init() == false)
{
return 1;
}
if (somethings() ==false)
{
return 1;
}
while (quit ==false)
{
while (SDL_PollEvent(&event))
{
P1.handle_input();
if (event.type == SDL_QUIT)
{
quit == true;
}
}
if (SDL_Flip(screen) ==-1)
{
return 1;
}
P1.move();
P1.show();
}
clean();
return 0;
}
About the images not loading, step through your program with a debugger and watch your somethings()function and follow the variables temp and sprite.
Make sure your "sprite.bmp" file is located in the running directory of this program. I tested it and it works for me.
Also this has no effect:
if (x >= SCW)
{
x-10;
}
if (y >= SCH)
{
y-10;
}
You probably wanted to say x -= 10; and y -= 10;.
This makes your 'player' jump back to the original position immediately:
if (event.type == SDL_KEYUP)
{
switch(event.key.keysym.sym)
{
case SDLK_UP: yVel += SPH /2; break;
case SDLK_DOWN: yVel -= SPH /2; break;
case SDLK_LEFT: xVel +=SPW /2; break;
case SDLK_RIGHT: xVel -=SPW /2; break;
}
}
You probably only need to handle SDL_KEYDOWN event.
Hope that helps.
There are big chances that you aren't loading the bitmap. But anything that you are trying to print on the screen and wasn't loaded can terminate the app.

No SDL Keypress events being detected

I am completely stumped as to why this code does not get any SDL keypress events. The other SDL events (removed for clarity) work fine. It does not work on my XP or Vista machines. No compile/link errors, just never recieve a keydown event.
#include "SDL/SDL.h"
// Yes SDL.lib and SDLmain.lib are linked
Uint32 TimeLeft(void)
{
static Uint32 next_time = 0;
Uint32 now;
now = SDL_GetTicks();
if ( next_time <= now ) {
next_time = now + tickInterval;
return 0;
}
return(next_time-now);
}
int main( int argc, char **argv )
{
if( -1 == SDL_Init( SDL_INIT_EVERYTHING ) )
{
cerr << "Error: SDL_Init failed" << endl;
return -1;
}
SDL_Event event;
bool quit = false;
while( !quit )
{
while( SDL_PollEvent( &event ) )
{
switch( event.type )
{
case SDL_KEYDOWN:
switch( event.key.keysym.sym )
{
case SDLK_ESCAPE:
case SDLK_q:
quit = true;
break;
default:
break;
}
break;
case SDL_JOYAXISMOTION:
// stuff removed
break;
case SDL_QUIT:
quit = true;
break;
default:
break;
}
}
SDL_Delay( TimeLeft() );
}
SDL_Quit();
return 0;
}
You'll need to create a window with SDL_SetVideoMode to get mouse and keyboard events.
I don't think you'll have luck trying to SDL_WM_GrabInput the mouse and keyboard without a window. It may also raise security alerts the first time on moderm Windows machines.