Advertisement

while key pressed

Started by October 29, 2004 02:57 PM
11 comments, last by raptorstrike 19 years, 10 months ago
while boku san's method is the one your "supposed" to use, i find it difficult to use and not as flexible. this is because ALL input in your game would have to go through the polling system. this means you have to set up some sort of distributed messaging system, where you receive a keypress and then send it along to whoever needs it. while you might want to do that, i find it a hassle.

i prefer to just directly grab input from the keyboard. that is, getting input using the if(keys[SDLK_XX]) way. this way i can get input from any point in my game without using the message pump. there are 2 downsides to this:

1) you aren't guarenteed to receive all input.

2) you take input too fast.

you aren't guarenteed to receive all input. that is, on a very slow machine, you might miss some input. however, i find this to be a non serious issue. even when getting only 30 FPS, SDL still takes input WAY to fast. that is, using the "direct" method (technically its not direct, but its the best way to describe it), you would receive a button down even 10-15 times when the button was only pressed one. test it out, do something like this:

if(keys[SDLK_t])
cout << " T IS PRESSED !!! "<<endl;

when you press T, the console will print that out more then once, depending on FPS. like i said, at 30 FPS, you will probably see the print out 10-20 times. so, IMO , its nearly impossible to miss input unless your getting like 5 FPS. in which case the game isnt really worth playing anyway.

now, about the second issue. this is more serious. you take input too fast so when the key is pressed once, you might register that input 15 times. this isn't cool if you truly only wanted to do that thing 1 time and not 15 times. but, there is a pretty simple way to do it. if you look at the enginuity article here on gamedev, he talks about how to do it and shows example code, its around the 4th article in the series i believe. im not at home right now, so i cant post the code to show you, but i will whenever i get back if you want.

PS- whatcha talkin about with the windows message thing?

[Edited by - graveyard filla on October 31, 2004 12:20:07 AM]
FTA, my 2D futuristic action MMORPG
heres my input class. it was really easy to implement and its very very nice to have... you dont know how many timers i had set up, basically one for each keypress, well, either that or a different trick to slow down input taking. anyway, heres the header:

class Input{	public:		Input();		~Input();		void Update();		void Process_Input_Message(const SDL_Event &event);		//getting key functions		bool Cur_Key(int index) { return keys[index] != 0; }		bool Old_Key(int index) { return old_keys[index] != 0; }				bool Key_Down(int index)	{ return ( Cur_Key(index))&&(!Old_Key(index)); }		bool Key_Still_Down(int index) { return ( Cur_Key(index))&&( Old_Key(index)); }		bool Key_Up(int index) { return (!Cur_Key(index))&&( Old_Key(index)); }		bool Key_Still_Up(int index)	{ return (!Cur_Key(index))&&(!Old_Key(index)); }		//now the mouse functions		bool Cur_Mouse(int button) { return (buttons&SDL_BUTTON(button))!=0; }		bool Old_Mouse(int button) { return (old_buttons&SDL_BUTTON(button))!=0; }		bool Mouse_Down(int button) { int x,y; SDL_GetMouseState(&x,&y); if(y >= 0) return ( Cur_Mouse(button))&&(!Old_Mouse(button)); }		bool Mouse_Still_Down(int button){ return ( Cur_Mouse(button))&&( Old_Mouse(button)); }		bool Mouse_Up(int button){ return (!Cur_Mouse(button))&&( Old_Mouse(button)); }		bool Mouse_Still_Up(int button){ return (!Cur_Mouse(button))&&(!Old_Mouse(button)); }	private:		//keyboard		int key_count;		unsigned char *keys, *old_keys;		//mouse		unsigned int buttons;	    unsigned int old_buttons;};


heres the cpp:
Input::Input(){	unsigned char *temp_keys = SDL_GetKeyState(&key_count);	keys = new unsigned char [key_count];//(unsigned char*)malloc(sizeof(unsigned char) * key_count);	memcpy(keys,temp_keys,key_count);	old_keys = new unsigned char [key_count];// (unsigned char*)malloc(sizeof(unsigned char) * key_count);}void Input::Process_Input_Message(const SDL_Event &event){	switch(event.type)	{		case SDL_QUIT: 		{		}		break;		case SDL_KEYDOWN:		{		}		break;		}//end of switch event.type}void Input::Update(){	SDL_Event event;		while(SDL_PollEvent(&event))	{		Process_Input_Message(event);	}		//for keyboard	memcpy(old_keys,keys,key_count);	unsigned char *temp_keys = SDL_GetKeyState(&key_count);	memcpy(keys,temp_keys,key_count);	//for mouse  	old_buttons = buttons;	buttons = SDL_GetMouseState(NULL,NULL);}Input::~Input(){	delete [] keys;	delete [] old_keys;}


just create an Input object and call Update() each frame with it, wherever you take input normally. then you can use the functions to get mouse and keyboard input. Key_Down() means the key was _just_ pushed down. this means it will only return true the exact frame that the key was pushed, and only it will only return true one time for each key press. Key_Still_Down() will return true if a key is being held down. so, if you call this function and a key was _just_ pressed, it will return false, but if the key is still held down N number of frames (where N > 1), it will return true. the same goes for the Key_Up() functions.

the mouse functions are the same way. return true if a mouse was just clicked, or if the mouse is held down. for the mouse just send it 1,2, or 3. where 1 is left mouse click, 2 is mouse wheel pressed, and 3 is right mouse click. again, the Up() functions work the same.

also, if for some reason you pass around your Input instance by value (i dont recommend it, you should send this around by reference), you should probably make a copy constructor and = operator for the class. this is because the constructor / destructor allocates / deletes memory. if this was passed by value, the default copy constructor would be called, so the memory would never be allocated, but when it falls out of scope, the destructor would delete the memory that was never allocated, and thats when your game crash's [smile]. so, just know to always send this class by reference if you send it anywhere (like in a Get() function)
FTA, my 2D futuristic action MMORPG
Advertisement
this works great thanks alot but i noticed that with all the input stratagys ive tried SDL seems to lag is there any way to optimize this so that it lags less (THANKS AGAIN EVERY ONE [smile])

[EDIT]
actually when i call it twice a loop it dosnt lag so nvr mind thanks again

wow heres another edit your system also has no problems with multiple key presses and do you mind if i suggest this mehtod to other people (that is if you wrote it)?
____________________________"This just in, 9 out of 10 americans agree that 1 out of 10 americans will disagree with the other 9"- Colin Mochrie

This topic is closed to new replies.

Advertisement