Sign in to follow this  
BennettSteele

SDL Key press help- NEED BAD HELP

Recommended Posts

BennettSteele    493
So im making my game, right? and in my void KeyPress() function, it creates a local SDL Event, then changes up,down,left and right to true/false depending on the key state. but in my game, when you press a button, it quickly presses then releases the button. Does anyone know what is happening?!?

Share this post


Link to post
Share on other sites
jyk    2094
[quote name='bennettbugs' timestamp='1307145763' post='4819263']
Does anyone know what is happening?!?[/quote]
No, no one knows what is happening ;) But, if you could post the relevant code, I'm sure someone will be able to help out :)

Share this post


Link to post
Share on other sites
BennettSteele    493
Key presses:


while (SDL_PollEvent(&keyevent))
{
if (keyevent.type == SDL_KEYDOWN)
{
switch(keyevent.key.keysym.sym)
{
case SDLK_LEFT:
left = true;
Log.Write("LEFT_PRESSED\n");
break;
case SDLK_RIGHT:
right = true;
Log.Write("RIGHT_PRESSED\n");
break;
case SDLK_UP:
up = true;
Log.Write("UP_PRESSED\n");
break;
case SDLK_DOWN:
down = true;
Log.Write("DOWN_PRESSED\n");
break;
default:
break;
}
}
if (keyevent.type == SDL_KEYUP)
{
switch(keyevent.key.keysym.sym)
{
case SDLK_LEFT:
left = false;
Log.Write("LEFT_RELEASED\n");
break;
case SDLK_RIGHT:
right = false;
Log.Write("RIGHT_RELEASED\n");
break;
case SDLK_UP:
up = false;
Log.Write("UP_RELEASED\n");
break;
case SDLK_DOWN:
down = false;
Log.Write("DOWN_RELEASED\n");
break;
default:
break;
}
}
if(keyevent.type==SDL_QUIT)
{
isRunning=false;
Log.Write("UNKOWN_QUIT_COMMAND\n");
}
if (keyevent.key.keysym.sym==SDLK_ESCAPE)
{
isRunning=false;
Log.Write("ESC_PRESSED\n");
Log.Write("Saving Map...\n");
myMap.Save("stuff/save.txt");
Log.Write("Saved!\n");
}
if (keyevent.key.keysym.sym==SDLK_q)
{
myMap.Load("stuff/save.txt");
}
if (keyevent.key.keysym.sym==SDLK_p)
{
if(Playing && Paused.Done){Game.Pause();}
else if(Playing==false && Paused.Done){Game.Resume();}
Log.Write("P_PRESSED\n");
}
}

Share this post


Link to post
Share on other sites
jyk    2094
The code's a little hard to follow because of the formatting (you can use 'code' tags to fix that), but here's a couple of things I noticed:

1. For checking the event type, a switch statement or series of if-else's would be more appropriate (since an event can't be of multiple types).

2. It looks like you're checking for some key press events even when the event type may not be 'key down'. This may end up working anyway, but those checks should really be inside the 'key down' block.

3. Since the event can be any of several types (key press or release, 'quit', mouse, etc.), 'keyevent' is a misleading variable name; I'd just call it 'event'.

I'm not clear on what the problem behavior described in your original post is, but generally these sorts of problems can be solved be using the debugger and/or adding appropriate debug output (like the 'log' statements that you have already).

Share this post


Link to post
Share on other sites
BennettSteele    493
What happens is when you were to say press up, in the first loop you would have the up key pressed. but in the next loop, it automatically says in the keypress check that up has been released even though it is still being pushed. I have no idea what is happening.

Share this post


Link to post
Share on other sites
jyk    2094
What version of SDL are you using?

Can you post a complete, minimal example that demonstrates the behavior? For example, a single main.cpp file that does nothing more than create a window, run an event loop, and indicate somehow (e.g. console output, or perhaps setting the window title) when a specific key has been pressed and when it's been released.

(When posting the code, be sure to use 'code' tags. Also, I suggest converting all tabs to spaces before posting in order to have a better chance of preserving the formatting.)

Share this post


Link to post
Share on other sites
jyk    2094
[quote name='bennettbugs' timestamp='1307318799' post='4819914']
Log.txt :

PROGRAM_START
UP_PRESSED
UP_RELEASED
PROGRAM_END
[/quote]
We need to see the code.

Share this post


Link to post
Share on other sites
BennettSteele    493
What part? i have a lot of code. if its the main loop:
(and PS: if its good for learning c++ in 3 months, tell me)

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


#include "SDL.h"
#include "SDL_opengl.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include "include/ApplySurface.h"
#include "include/IntToChar.h"
#include "include/CharToInt.h"
#include "include/File.h"
#include "include/InitImages.h"
#include "include/Animation.h"
#include "include/Animations.h"
//DEFINE VARIABLES
bool left,right,up,down;//we save in which state the button is
int Timer;
const int ZOMBIES=3;
bool isRunning=true,Playing=true;
#include "include/TextToDraw.h"
Fire burn;
Pointer select;
//INCLUDE THINGS DEPENDANT ON VARIABLES

File Log("stuff/log.txt");
#include "include/ScreenClass.h"
Screen Paused;
#include "include/GameStats.h"
GameStats Game;//NEEDS GAMESTATS
#include "include/Map.h"


Map myMap;
#include "include/Zombie.h"
newZombie Zombies[ZOMBIES];



#include "include/IntToImage.h"
#include "include/GameDraw.h"
#include "include/ScreenDraw.h"
#include "include/Movement.h"
#include "include/GameLogic.h"
#include "include/ScreenLogic.h"
//#include "include/KeyPresses.h"
#include "include/ReadFromSource.h"


char Version[7]="abc/";


int main( int argc, char* args[] )
{

Log.Write("PROGRAM_START\n");

myMap.Init();
SDL_Init(SDL_INIT_VIDEO);
SDL_WM_SetCaption("Survivor Pre-Alpha",NULL);
SDL_SetVideoMode(600,480,32, SDL_OPENGL );
InitImages();
SDL_WM_SetIcon(icon,NULL);




burn.Init(Game.myX,Game.myY);
select.Init(0,0);




for(int n=0;n<ZOMBIES;n++)
{
float x=(float)rand()/(float)RAND_MAX;
float y=(float)rand()/(float)RAND_MAX;
Zombies[n].Init(x*5+10,y*5+10);
}


std::string NewName=ReadFromScreen("name");
int newType=atoi(NewName.c_str());
myMap.Box(15,15,3,3,newType);
SDL_Event keyevent;
while(isRunning)
{
while (SDL_PollEvent(&keyevent))
{
if (keyevent.type == SDL_KEYDOWN)
{
switch(keyevent.key.keysym.sym)
{
case SDLK_LEFT:
left = true;
Log.Write("LEFT_PRESSED\n");
break;
case SDLK_RIGHT:
right = true;
Log.Write("RIGHT_PRESSED\n");
break;
case SDLK_UP:
up = true;
Log.Write("UP_PRESSED\n");
break;
case SDLK_DOWN:
down = true;
Log.Write("DOWN_PRESSED\n");
break;
default:
break;
}
}
if (keyevent.type == SDL_KEYUP)
{
switch(keyevent.key.keysym.sym)
{
case SDLK_LEFT:
left = false;
Log.Write("LEFT_RELEASED\n");
break;
case SDLK_RIGHT:
right = false;
Log.Write("RIGHT_RELEASED\n");
break;
case SDLK_UP:
up = false;
Log.Write("UP_RELEASED\n");
break;
case SDLK_DOWN:
down = false;
Log.Write("DOWN_RELEASED\n");
break;
default:
break;
}
}
if(keyevent.type==SDL_QUIT)
{
isRunning=false;
Log.Write("UNKOWN_QUIT_COMMAND\n");
}
if (keyevent.key.keysym.sym==SDLK_ESCAPE)
{
isRunning=false;
Log.Write("ESC_PRESSED\n");
Log.Write("Saving Map...\n");
myMap.Save("stuff/save.txt");
Log.Write("Saved!\n");
}
if (keyevent.key.keysym.sym==SDLK_q)
{
myMap.Load("stuff/save.txt");
}
if (keyevent.key.keysym.sym==SDLK_p)
{
if(Playing && Paused.Done){Game.Pause();}
else if(Playing==false && Paused.Done){Game.Resume();}
Log.Write("P_PRESSED\n");
}
}


if(Playing){GameLogic();GameDraw();lastscreen=screen;}//IN GAME LOGIC AND DRAWING
if(Playing==false){ScreenLogic();ScreenDraw();}//SCREEN LOGIC AND DRAWING

SDL_Delay(10);
}
Log.Write("PROGRAM_END");
SDL_Quit();
return 0;
}

Share this post


Link to post
Share on other sites
jyk    2094
[quote name='bennettbugs' timestamp='1307404218' post='4820302']
What part? i have a lot of code.[/quote]
It'd probably be easier if you could post a complete, minimal example that demonstrates the problem (as described earlier). Creating such an example can often be an effective way of finding the cause of problems such as this one.

You can also just try posting some relevant code from your project (as you did above), but be sure to use 'code' tags so that we can read it easily :)

Share this post


Link to post
Share on other sites
Roots    1625
Are you enabling joysticks anywhere? We've recently encountered an issue with our input system (which is about 4-5 years old and completely stable) where some players are unable to hold down a direction key to perform movement because the input engine is registering key releases unexpectedly. We haven't fixed the problem, but we think we found where the issue lies. On one user's system, disabling joystick input fixed the issue. Turns out, even though they do not have a joystick plugged into their system. SDL still registered some kind of virtual joystick and that was somehow causing joystick release events to occur. Its really odd and we've only had reports on it by two people so far. You can read more details in our thread:

http://www.allacrost.org/forum/viewtopic.php?f=3&t=5376

Share this post


Link to post
Share on other sites
rip-off    10979
Here is a minimal program:
[code]
#include <iostream>
#include <cstdlib>

#include "SDL.h"

int main(int argc, char **argv)
{
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
std::cerr << SDL_GetError() << '\n';
return 1;
}
std::atexit(&SDL_Quit);

SDL_Surface *screen = SDL_SetVideoMode(800, 600, 0, 0);
if(!screen)
{
std::cerr << SDL_GetError() << '\n';
return 2;
}

int vertical = 0;
int horizontal = 0;

bool running = true;
while(running)
{

SDL_Event event;
while(SDL_PollEvent(&event))
{
if(event.type == SDL_KEYDOWN)
{
switch(event.key.keysym.sym)
{
case SDLK_UP: vertical -= 1; break;
case SDLK_DOWN: vertical += 1; break;
case SDLK_LEFT: horizontal -= 1; break;
case SDLK_RIGHT: horizontal += 1; break;
}
}
else if(event.type == SDL_KEYUP)
{
switch(event.key.keysym.sym)
{
case SDLK_UP: vertical -= -1; break;
case SDLK_DOWN: vertical += -1; break;
case SDLK_LEFT: horizontal -= -1; break;
case SDLK_RIGHT: horizontal += -1; break;
}
}
else if(event.type == SDL_QUIT)
{
running = false;
}
}

// Clear screen
SDL_FillRect(screen, 0, 0);

// Draw center
SDL_Rect rect;
rect.w = 10;
rect.h = 10;
rect.x = screen->w / 2;
rect.y = screen->h / 2;
SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0x00, 0xff, 0x00));

// Draw offset
rect.x += rect.w * horizontal;
rect.y += rect.h * vertical;
SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, 0xff, 0x00, 0x00));
SDL_Flip(screen);
}
}
[/code]
Does the behaviour occur in this?

Share this post


Link to post
Share on other sites
rip-off    10979
That was what I wrote it to do. It is designed to see if the SDK_KEYUP is being spuriously sent. It seems you're getting the expected behaviour, which indicates that there is something else in your program that is causing this issue.

I think you should take a copy of your program, and start commenting stuff out until the problem disappears. Do it bit by bit, comment out the Zombies and run it, comment out the Fire and see what happens, and so on. The point at which the problem disappears should then be uncommented, and you should dive into its internals and start commenting out smaller chunks. This process can be repeated until you isolate a line or number of lines which cause the issue.

Alternatively, you could take my working program and add your code to it piece by piece until it breaks.

Share this post


Link to post
Share on other sites
jyk    2094
[quote name='bennettbugs' timestamp='1307749235' post='4821916']
Ok, so adding your code still does not fix it. I do know that it is something with the key presses. :(
[/quote]
I'm not sure if the suggestion was to add additional code to your project, per se.

There are a few different diagnostic approaches you can take here. You can find them described elsewhere in the thread (see rip-off's post above, for example), but I'll summarize here for convenience:

1. Start with a brand new clean project, and create a minimal, single-source-file program that demonstrates the problem behavior. (In your case, the program would likely just create a window, poll for input, and produce some output indicating when keys have been pressed or released.) Generally, creating such an example will have one of two possible results: a) the minimal example works correctly, which indicates there's a problem elsewhere in your code, or b) you end up with a concise example that you can post here for us to look at, and/or submit along with a bug report.

2. Back up your project and then start commenting stuff out, as rip-off suggested. With this approach, you're essentially working backwards towards the aforementioned 'minimal example'. A possible outcome of this approach is that at some point the program will start to work correctly, in which case you can look to whatever you commented out last for clues as to why things aren't working.

3. Start with an example that's known to work correctly (like the example rip-off posted) and then progressively add things until it stops working correctly (in which case the last feature added will provide a clue as to why things aren't working).

4. Use the debugger and/or debug output to try and deduce exactly what's going on inside your program. Input-related errors can be tricky to debug sometimes, but by placing breakpoints or adding debug output strategically, you should be able to narrow things down.

Unfortunately debugging can be hard, but sometimes you just have to dig in and take things apart (or put things together) a piece at a time until you find the problem.

Share this post


Link to post
Share on other sites
ote    100
Maybe it's not that but have you try to enable SDL_EnableKeyRepeat(int delay, int interval) ? [url="http://pwet.fr/man/linux/fonctions_bibliotheques/sdl_enablekeyrepeat"]http://pwet.fr/man/linux/fonctions_bibliotheques/sdl_enablekeyrepeat[/url]

Share this post


Link to post
Share on other sites
BennettSteele    493
The [color=#404040][b] [/b][b]SDL_EnableKeyRepeat[/b]([b]int delay, int interval[/b]); did not work. if i gave you the project(its in code::blocks), maybe one of you could look and fix it?[/color]

Share this post


Link to post
Share on other sites
capricorn    139
Would you mind posting the actual cause of the problem and exactly how did you fix it? This may help other people who might come here with similar issue.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this