• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
iLoveGameProgramming

SDL Key/Mouse Simplified Intput Class

10 posts in this topic

Hello everybody 

 

Today I decided to create controls class for my engine (when I say engine, It is VERY loosely said).

Basically I am trying to make SDL code a little simpler to use, the idea would be you create controls class and then 

you just do 

if (controls->isKeyDown(SLDK_ESCAPE))
{
std::cout << "Escape was Pressed" << std::endl;
}

if (controls->isKeyHeld(SLDK_ESCAPE))
{
std::cout << "Escape is Held" << std::endl;
}

if (controls->isKeyUp(SLDK_ESCAPE))
{
std::cout << "Escape was Released" << std::endl;
}

if (controls->isMouseUp(SDL_LEFT_MOUSE)
{
std::cout << "Left Mouse was Released" << std::endl;
}

and you can guess the rest for the mouse tongue.png

 

If there is already free controls class like that please let me know, or if there is better way of doing controls in SDL smile.png

 

Unfortunately it does not work the way I intended it too. I managed to get Key Presses working until you start pressing multiple keys, then everything goes messy and it starts thinking keys are pressed when they are not... It will know when key is pressed, held and released as long only that key is being pressed at that every moment.

 

The Mouse does not work more on other hand. It recognizes that the key was pressed/released but for example when I do 

if (controls->isMouseDown(SDL_LEFT_MOUSE)
{
std::cout << "Left Mouse was Pressed" << std::endl;
}

and press any of the mouse buttons, it will read that line even when I use Mouse Wheel button. Also isMouseHeld doesn't work at all. It is never read.

 

Mouse controls also go messy when you start touching multiple mouse keys at once. Gets stuck on release, just like in controls. Thinks the mouse was released until 1 button is pressed and resets it.

 

 

 

If this class would work I think it could be not just useful to me but would save some time for anyone else smile.png Instead of reinventing the wheel each time...

 

I really hate posting large chunks of code, but I have no idea where the problem is in the code... so here is .h and .cpp file. I've commented .h file smile.png

 

Thank you for your time in advance smile.png

 

controls.h

#pragma once
#include "stdafx.h"

class DllExport controls
{
public:
	//event is passed down from the engine class
	controls(SDL_Event* theEvent);
	~controls(void);

	//different types of possible key states
	#define KEY_NONE -1
	#define KEY_PRESSED 0
	#define KEY_RELEASED 1
	#define KEY_HOLDING 2

	//returns true key was pressed
	bool isKeyDown(int SDLK_ID);
	//returns true key is being held
	bool isKeyHeld(int SDLK_ID);
	//returns true key was released
	bool isKeyUp(int SDLK_ID);

	//returns true if Mouse button was pressed
	bool isMouseDown(int MouseButton);
	//returns true if Mouse button is being held
	bool isMouseHeld(int MouseButton);
	//returns true if Mouse button was released
	bool isMouseUp(int MouseButton);

	//Gets SDL event
	SDL_Event* GetEvent();

	//this runs every frame
	void Update();
private:
	SDL_Event* events; //Pointer to an SDL events system

	//Holds Current Mouse states
	int LeftMouseState;
	int RightMouseState;
	int LeftMouseHeld;
	int RightMouseHeld;

	//Press and Release Key States
	int KEYS_STATE[322];  // 322 is the number of SDLK_DOWN events
	//Held Key States
	int KEYS_STATE2[322];
};

controls.cpp

#include "stdafx.h"
#include "controls.h"


controls::controls(SDL_Event* theEvents)
{
	events = theEvents;

	for(int i = 0; i < 322; i++) { // init them all to false
		KEYS_STATE[i] = KEY_NONE;
		KEYS_STATE2[i] = KEY_NONE;
	}

	LeftMouseState = KEY_NONE;
	RightMouseState = KEY_NONE;
	LeftMouseHeld = KEY_NONE;
	RightMouseHeld = KEY_NONE;
}


controls::~controls(void)
{
}

bool controls::isMouseDown(int MouseButton)
{

	if (MouseButton == SDL_BUTTON_LEFT)
	{
		if (LeftMouseState == KEY_PRESSED)
			return true;
	}
	else if (MouseButton == SDL_BUTTON_RIGHT)
	{
		if (RightMouseState == KEY_PRESSED)
			return true;
	}

	return false;
}

bool controls::isMouseHeld(int MouseButton)
{

	if (MouseButton == SDL_BUTTON_LEFT)
	{
		if (LeftMouseState == KEY_HOLDING) 
			return true;
	}
	else if (MouseButton == SDL_BUTTON_RIGHT)
	{
		if (RightMouseState == KEY_HOLDING)
			return true;
	}

	return false;
}

bool controls::isMouseUp(int MouseButton)
{

	if (MouseButton == SDL_BUTTON_LEFT)
	{
		if (LeftMouseState == KEY_RELEASED) 
			return true;
	}
	else if (MouseButton == SDL_BUTTON_RIGHT)
	{
		if (RightMouseState == KEY_RELEASED)
			return true;
	}

	return false;
}

void controls::Update()
{

	switch (events->type) {

	case SDL_MOUSEBUTTONDOWN:


		if (events->button.button == SDL_BUTTON_LEFT);
		{
			if (LeftMouseHeld == KEY_NONE)
				LeftMouseState = KEY_PRESSED;
			else
				LeftMouseState = KEY_NONE;

			LeftMouseHeld = KEY_HOLDING;

		}
		if (events->button.button == SDL_BUTTON_RIGHT);
		{
			if (RightMouseHeld == KEY_NONE)
				RightMouseState = KEY_PRESSED;
			else
				RightMouseState = KEY_NONE;

			RightMouseHeld = KEY_HOLDING;
		}
		break;
	case SDL_MOUSEBUTTONUP:

		if (events->button.button == SDL_BUTTON_LEFT);
		{

			if (LeftMouseHeld == KEY_HOLDING)
				LeftMouseState = KEY_RELEASED;
			else
				LeftMouseState = KEY_NONE;

			LeftMouseHeld = KEY_NONE;

		}
		if (events->button.button == SDL_BUTTON_RIGHT);
		{
			if (RightMouseHeld == KEY_HOLDING)
				RightMouseState = KEY_RELEASED;
			else
				RightMouseState = KEY_NONE;

			RightMouseHeld = KEY_NONE;
		}
		break;
	case SDL_KEYDOWN:

		if (KEYS_STATE2[events->key.keysym.sym] == KEY_NONE)
		{
			KEYS_STATE[events->key.keysym.sym] = KEY_PRESSED;
		}
		else
			KEYS_STATE[events->key.keysym.sym] = KEY_NONE;

		KEYS_STATE2[events->key.keysym.sym] = KEY_HOLDING;


		break; 
	case SDL_KEYUP:

		if (KEYS_STATE2[events->key.keysym.sym] == KEY_HOLDING)
		{
			KEYS_STATE[events->key.keysym.sym] = KEY_RELEASED;
		}
		else
			KEYS_STATE[events->key.keysym.sym] = KEY_NONE;

		KEYS_STATE2[events->key.keysym.sym] = KEY_NONE;

		break;
	default:
		break;

	}
}

bool controls::isKeyDown(int SDLK_ID)
{

	if (KEYS_STATE[SDLK_ID] == KEY_PRESSED)
	{
		return true;
	}
	else 
		return false;
}

bool controls::isKeyHeld(int SDLK_ID)
{

	if (KEYS_STATE2[SDLK_ID] == KEY_HOLDING)
	{
		return true;
	}
	else 
		return false;
}


bool controls::isKeyUp(int SDLK_ID)
{

	if (KEYS_STATE[SDLK_ID] == KEY_RELEASED)
	{
		return true;
	}
	else 
		return false;
}


SDL_Event* controls::GetEvent() { return events; }
Edited by iLoveGameProgramming
0

Share this post


Link to post
Share on other sites

Thank you for reply Pinebanana :)

Why are you using #define? #define is evil and should be avoided. Use an enum or const, e.g.:

good idea, no one ever told me they are bad, but I guess enum are easier to manage :)

 

 

I am using that include because it needs to include SDL. I guess I could move it to include just SDL. It would make it more portable.

 

 

return KEYS_STATE[SDLK_ID] == KEY_PRESSED;

 

I had no idea you can do something like that! So this returns false if its anything else besides KEY_PRESSED, and true if it is? 

 

I am aware that there is some duplicated code, trying to get it working properly first. Still didn't figure out how to get multiple key presses at once :(

 

Thanks it was very good feedback :)

0

Share this post


Link to post
Share on other sites

 

 

As for why #defines are generally considered bad practice, consider this:

#define FIVE 3 + 2
#define FOUR 4

std::cout << "The wrong result: " << FIVE * FOUR << std::endl;

 

Which is why it's recommended to do this:

#define FIVE (3 + 2)
#define FOUR (4)
std::cout << "The correct result: " << FIVE * FOUR << std::endl;

I do agree that constants or an enum is a better choice though.

 

Just thought I'd defend #define a bit. rolleyes.gif

It's very useful at times. Just needs to be used when it should be used.

Edited by diventurer
1

Share this post


Link to post
Share on other sites

Which is why it's recommended to do this:

#define FIVE (3 + 2)
#define FOUR (4)
std::cout << "The correct result: " << FIVE * FOUR << std::endl;

Yep, but it's the simplest illustration of why it can cause problems - it just does a copy+paste of the define with what it was defined to.

I also use defines in my project; not frequently, but they are useful in a good number of circumstances. They just should be avoided for things that there are superior options for, like when using them for constant values. Edited by Servant of the Lord
0

Share this post


Link to post
Share on other sites

 

if(x) triggers a branch of code if 'x' is true. It takes a bool.

 

A == B is a function that returns a bool.

&&, ||, !, >, <, <=, >=, also return bools.

 

This means you can go:

bool result = (a > 4) && (a < 6);
if(result)
{
    //Do something.
}

 

Oh wow, thank you for this information. I always thought that the if statements are doing the job of returning the value. Not that I can use this, this way. I can see how it could be useful! Everyday learning something new :D

 

I've replaced #define with enum :)

 

I am using the SDL-1.2.15 unfortunately, I guess it's time to upgrade to SDL2 :)

 

Maybe upgrading will fix my problem with toggling full screen and losing  loaded textures in OpenGL. But that fix is for another day :)

 

Once I get controls class working I'll post it here, so anyone else can use it. If not I'll keep asking questions :)

0

Share this post


Link to post
Share on other sites

The two functions I linked to are for SDL 1.2, and do exactly what I think you are asking for. smile.png

1

Share this post


Link to post
Share on other sites

Hehe yeah I've miss read it my bad. I still managed to upgrade my engine with SDL2.0 and everything seems to work besides the controls :P. Just want to let you guys know I haven't forgotten about this post and I will post this class here once its absolutely glitches :) So maybe it could help someone in the future. Hopefully I will find some time tomorrow to finish it up.

0

Share this post


Link to post
Share on other sites

One other thing to consider (although this could be done at a higher layer).  Typically, users want to map their keys/buttons to do different things.  So, in my Input manager, I give it enumerations like KEY_MOVE_LEFT, KEY_MAIN_FIRE, KEY_SPECIAL_FIRE, KEY_JUMP, etc to test for key presses.  And the InputManager reads some configuration file to determine which actual keys (or buttons) map to what ability.  So, shooting a gun might be Left Mouse Button for one user, but Right Ctrl for another.

 

Good luck!

0

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  
Followers 0