is there anything wrong with the way i'm handling keys (SDL)

Started by
6 comments, last by SpacedOut 18 years, 7 months ago

while (!g_bGameOver)
	{		
		SDL_Event event;
		while (SDL_PollEvent(&event))
		{
			if (event.type == SDL_QUIT)
				g_bGameOver = true;
			if (event.type == SDL_KEYDOWN)
			{
				if (event.key.keysym.sym == SDLK_ESCAPE)
					g_bGameOver = true;
				if (event.key.keysym.sym == SDLK_SPACE)
					g_pGame->AddSprite(g_pShip->Fire());
			}
		}
		iTickCount = SDL_GetTicks();

		if (iTickCount > iTickTrigger)
		{
			iTickTrigger = iTickCount + g_pGame->GetFrameDelay();
			keys = SDL_GetKeyState(NULL);
			if (keys[SDLK_LEFT])
				g_pShip->xadd(-5);
			else if (keys[SDLK_RIGHT])
				g_pShip->xadd(5);

			GameCycle();
			SDL_Flip(screen);
		}
	}
the spacebar is supposed to call the Sprite::Fire() method. the firing part works ok, but when i press the spacebar rapidly, sometimes it doesn't work. it fires nice and evenly but then it skips a few spacebar presses.
Advertisement
I see nothing wrong. I bet the problem is in the fire function.
Post the source to that.

Learn to make games with my SDL 2 Tutorials

Bullet* PlayerShip::Fire(){	m_pBullet = new Bullet(m_screen, "shot.bmp", 1, 1);	m_pBullet->SetPosition(m_position.x+20, m_position.y-30);	m_pBullet->SetVelocity(0, -7);	m_pBullet->SetWH(10, 20);	return m_pBullet;}
Although from your description it doesn't sound like you're using keyboard repeat, the only thing I can think of in the API that deals with the keyboard buffer is SDL_EnableKeyRepeat. You might want to mess around with that. Try different values, and maybe even disabling the repeat altogether (SDL_EnableKeyRepeat(0,0);).

Hope this helps.
Jooleem. Get addicted.
I'm using a totally different input-manager(partially grabbed from enginuity)
so far it hasn't given me any problem ;)

///////////////////// Key Manager.hpp#ifndef __KEY_MANAGER_HPP#define __KEY_MANAGER_HPP#include "Classes.hpp"#include "Global.hpp"#define NUMBER_OF_KEYS 323class KeyManager {public:	KeyManager();	~KeyManager();	void init();	bool keyDown(int index) const;	bool keyStillDown(int index) const;	bool keyUp(int index) const;	bool keyStillUp(int index) const;	void updateKeys();private:	bool curKey(int index) const;	bool oldKey(int index) const;	unsigned char keys[NUMBER_OF_KEYS];	unsigned char oldKeys[NUMBER_OF_KEYS];	int keyCount;};#endif/////////////////////////////// KeyManager.cpp#include "Global.hpp"#include "KeyManager.hpp"#include <sdl.h>#include <memory.h>KeyManager::KeyManager() {	int i = 0;	for(i=0; i<keyCount; i++) {		keys=0;	}	for(i=0; i<keyCount; i++) {		oldKeys=0;	}}KeyManager::~KeyManager() {}void KeyManager::init() {	unsigned char *tempKeys;	tempKeys =SDL_GetKeyState(&keyCount);	assert( keyCount == NUMBER_OF_KEYS );	memcpy((unsigned char*)(keys),tempKeys,sizeof(unsigned char)*keyCount);}void KeyManager::updateKeys() {	unsigned char *tempKeys;	SDL_PumpEvents();	memcpy((unsigned char*)(oldKeys),(unsigned char*)(keys),sizeof(unsigned char)*keyCount);	tempKeys=SDL_GetKeyState(&keyCount);	assert( keyCount == NUMBER_OF_KEYS );	memcpy((unsigned char*)(keys),tempKeys,sizeof(unsigned char)*keyCount);}bool KeyManager::keyDown(int index) const {	return ( curKey(index))&&(!oldKey(index));}bool KeyManager::keyStillDown(int index) const {	return ( curKey(index))&&( oldKey(index));}bool KeyManager::keyUp(int index) const {	return (!curKey(index))&&( oldKey(index));}bool KeyManager::keyStillUp(int index) const {	return (!curKey(index))&&(!oldKey(index));}bool KeyManager::curKey(int index) const {	return (keys[index]!=0);}bool KeyManager::oldKey(int index) const {	return (oldKeys[index]!=0);}////////////////////////////////// useKeyManager manager;init();//open gl and sdlkeyManager.init();while(run) {  keyManager.updateKeys();  if( keyManager.keyDown(SDL_SDLK_ESCAPE) ) run = false;}
Well, you could still try SDL_EnableKeyRepeat. Just stick it in KeyManager::Init or the class' constructor.
Jooleem. Get addicted.
I'm not sure if you should use keydown events and SDL_GetKeyState in the same program as it's implied that SDL_GetKeyState empties the message pump in order to collect the key state. I may be wrong, but you could perhaps try taking out the SDL_GetKeyState, and tracking SDLK_LEFT/SDLK_RIGHT with your own variables, setting them to True in a keydown event and False in a keyup event, and see if you have more luck.
i think you're right about that SDL_GetKeyState() emptying the message pump because the it seems the spacebar press is ignored when i'm holding down an arrow key. i probably don't know what i'm talking about, i'll try your suggestions but more help would be appreciated. i'd post the entire syntax but it's almost 1000 lines long and embarasingly disorganized.

This topic is closed to new replies.

Advertisement