Sign in to follow this  
SpacedOut

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

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 323

class 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[i]=0;
}
for(i=0; i<keyCount; i++) {
oldKeys[i]=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);
}





////////////////////////////////
// use

KeyManager manager;
init();//open gl and sdl
keyManager.init();

while(run) {
keyManager.updateKeys();
if( keyManager.keyDown(SDL_SDLK_ESCAPE) ) run = false;
}


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

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