Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon


10. November 2017


In the first tutorial we looked at creating our initial application, while in the second tutorial we looked at events and a cleaner game loop then in the third tutorial we looked at drawing bitmaps on screen.  Today we are going to look at handling keyboard and mouse input.  We covered this slightly in earlier tutorials when we looked at event queues and enabled the application to exit when the user pressed a key.  This tutorial will go into a great deal more depth.  Without further ado, let’s jump into the code sample:

#include "stdafx.h"
#include <allegro5\allegro.h>
#include <allegro5\allegro_image.h>

int main()
{
	ALLEGRO_DISPLAY * display;
	ALLEGRO_EVENT_QUEUE *queue;
	ALLEGRO_BITMAP * bitmap = NULL;

	al_init();
	display = al_create_display(640, 480);
	queue = al_create_event_queue();

	al_install_keyboard();
	al_install_mouse();

	al_register_event_source(queue, al_get_keyboard_event_source());
	al_register_event_source(queue, al_get_display_event_source(display));
	al_register_event_source(queue, al_get_mouse_event_source());

	al_init_image_addon();
	
	bitmap = al_load_bitmap("image64x64.jpg");
	assert(bitmap != NULL);

	bool running = true;
	float x = 0, y = 0;

	int width = al_get_display_width(display);
	while (running) {
		al_clear_to_color(al_map_rgba_f(0, 0, 0, 1));
		al_draw_bitmap(bitmap, x, y, 0);
		al_flip_display();

		ALLEGRO_EVENT event;

		if (!al_is_event_queue_empty(queue)) {
			al_wait_for_event(queue, &event);
			if (event.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
				running = false;


			if (event.type == ALLEGRO_EVENT_MOUSE_AXES) {
				x = event.mouse.x;
				y = event.mouse.y;
			}

			if (event.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
				x = y = 0;
				al_set_mouse_xy(display, 0, 0);
			}
		}

		// Actively poll the keyboard
		ALLEGRO_KEYBOARD_STATE keyState;

		al_get_keyboard_state(&keyState);
		if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT))
			if (al_key_down(&keyState, ALLEGRO_KEY_LCTRL))
				x += 0.1;
			else
				x += 0.01;
		if (al_key_down(&keyState, ALLEGRO_KEY_LEFT))
			if (al_key_down(&keyState, ALLEGRO_KEY_LCTRL))
				x -= 0.1;
			else
				x -= 0.01;
	}

	al_destroy_display(display);
	al_uninstall_keyboard();
	al_uninstall_mouse();
	al_destroy_bitmap(bitmap);

	return 0;
}


When you run this application, the sprite will be drawn in the position of the mouse cursor.  Clicking and mouse button will reset the sprite’s position back to (0,0).  You can also control the position of the sprite by using the left and right arrow keys.

GIF

As we can see mouse and keyboard functionality is optional, so we need to call the appropriate init() function for both devices, then later the appropriate uninstall() function to clean them up.  Just like earlier we create an event queue, and register additional event sources for both keyboard and mouse.  As you can see, multiple event types can exist in a single event queue.

Mouse handling is extremely straight forward, when the mouse is moved it will fire a ALLEGRO_MOUSE_AXES_EVENT with the mouse location stored in the events mouse.x and mouse.y properties.  You can also see that mouse button activity fire a ALLEGRO_MOUSE_BUTTON_UP_EVENT when a mouse button is released.  In this case we set the position of the mouse using al_set_mouse_xy().

We take a slightly different approach with keyboard handling.  We could use a similar approach, however it would only handle one key event at a time.  What we instead want to do is poll the current status of the keyboard every pass through our game loop.  We take this approach so we can detect multiple concurrent key presses.  This is done by populating a ALLEGRO_KEYBOARD_STATE structure with a call to al_get_keyboard_state().  We can then poll the status of individual keys by calling al_key_down().


Back to Table Of Contents

Programming , ,

blog comments powered by Disqus

Month List

Popular Comments