[SDL] Trouble with input events.

Started by
3 comments, last by Kylotan 15 years, 10 months ago
Ok, I've been going through SDL tutorials at www.lazyfoo.net and have run onto an issue with getting keyboard input to move a dot around on the screen. So here is the set up. I have an object class which is basically just some object you see on the screen that can move around. In my case it is a dot. It has x and y coords and velocity. It also have a handleInput and move method. Now for some reason when I call the dot's handleInput method is doesn't seem to register that a keydown event has happened when I push keys down. The only difference I really see from my code to the tutorials code is that I have a header file containing my globals for SDL one of which is the SDL_Event. These are all declared static to prevent multiply defined symbols. I'm not sure if the fact that it is static is causing any issue or not. So anyway, here is some code... Object.cpp

#include "Object.h"
#include "SDL_Globals.h"

const int DOT_WIDTH = 20;
const int DOT_HEIGHT = 20;

Object::Object() {
	x = 0;
	y = 0;
	xVel = 0;
	yVel = 0;
}

Object::~Object() {}

void Object::handleInput() {	
	if(event.type == SDL_KEYDOWN) {
		switch(event.key.keysym.sym) {
			case SDLK_UP : yVel -= DOT_HEIGHT / 2; break;
			case SDLK_DOWN : yVel += DOT_HEIGHT / 2; break;
			case SDLK_LEFT : xVel -= DOT_WIDTH / 2; break;
			case SDLK_RIGHT : xVel += DOT_WIDTH / 2; break;
		}
	}
	else if(event.type == SDL_KEYUP) {
        switch(event.key.keysym.sym) {
            case SDLK_UP : yVel += DOT_HEIGHT / 2; break;
            case SDLK_DOWN : yVel -= DOT_HEIGHT / 2; break;
            case SDLK_LEFT : xVel += DOT_WIDTH / 2; break;
            case SDLK_RIGHT : xVel -= DOT_WIDTH / 2; break;   
        }        
    }
}

void Object::move() {
	x += xVel;
	y += yVel;
}

int Object::getX() {return x;}

int Object::getY() {return y;}

int Object::getXVel() {return xVel;}

int Object::getYVel() {return yVel;}

SDL_Globals.h

#ifndef SDL_GLOBALS_H
#define SDL_GLOBALS_H

#include "SDL/SDL.h"
#include "SDL/SDL_ttf.h"

static SDL_Event event;
static SDL_Color textColor = {0, 0, 0};
static TTF_Font* font = NULL;

#endif

Chunk of my game loop

	while(quit == false) {
		fps.start();

		while(SDL_PollEvent(&event)) {
			dot.handleInput();
			if(event.type == SDL_QUIT) quit = true;
			else if(event.type == SDL_KEYDOWN) {
				if(event.key.keysym.sym == SDLK_c) {
					fpsCap = !fpsCap;
					if(fpsCap) capToggle = TTF_RenderText_Solid(font, "Framerate cap: on", textColor);
					else capToggle = TTF_RenderText_Solid(font, "Framerate cap: off", textColor);
				}
			}
		}
		// Update x and y coordinates for our dot object
        dot.move();

Any ideas about whats happening? The environment I'm using is VS 2008. Thanks!
Advertisement
I don't think the 'static' keyword is doing what you think it's doing here - as near as I can tell, you're creating a separate copy of your 'global' variables in each translation unit, which is why the object is not responding to keyboard input.

I think what you really want here is extern (if you search the forum archives for 'global variable extern', you'll probably find an example or two of how to set up your global variables correctly).

Also, once you get things working, I'd suggest that you try to eliminate the global variables entirely and take a more object-oriented approach. (There's nothing wrong with procedural code per se, but in this case there's really no reason for the 'event' object to be global, or for the 'object' class to have direct access to user input.)
Why not pass the SDL_Event to the handleInput function?

void Object::handleInput(const SDL_Event &event) {		if(event.type == SDL_KEYDOWN) {		switch(event.key.keysym.sym) {			case SDLK_UP : yVel -= DOT_HEIGHT / 2; break;			case SDLK_DOWN : yVel += DOT_HEIGHT / 2; break;			case SDLK_LEFT : xVel -= DOT_WIDTH / 2; break;			case SDLK_RIGHT : xVel += DOT_WIDTH / 2; break;		}	}	else if(event.type == SDL_KEYUP) {        switch(event.key.keysym.sym) {            case SDLK_UP : yVel += DOT_HEIGHT / 2; break;            case SDLK_DOWN : yVel -= DOT_HEIGHT / 2; break;            case SDLK_LEFT : xVel += DOT_WIDTH / 2; break;            case SDLK_RIGHT : xVel -= DOT_WIDTH / 2; break;           }            }}// later while(SDL_PollEvent(&event)) {	dot.handleInput(event);	// ...}
Hey, thanks for the reply. I've used extern variables a bit so no biggie setting it up. Didn't think of using it though.

Yeah, I'd like to make it more object oriented. That is my plan, I suppose passing the even is about the best way, eh?

"as near as I can tell, you're creating a separate copy of your 'global' variables in each translation unit, which is why the object is not responding to keyboard input."

Could you perhaps elaborate on this a little bit? I'm not entirely sure why seperate copies are being made.

Thanks for the input.
'static SDL_Event event;' This defines one separate 'event' object in every file that #includes that header.

This topic is closed to new replies.

Advertisement