Question Details

[answered] Lab 9: Eventdriven interactive programs Write a simple game


I need this lab finished soon. I've included all the files required, so if anyone can help, that'd be great.


Lab 9: Event?driven interactive programs


Write a simple game using callback functions and switch statements to


handle events Mondrioids demo for CMPT127 Goals


After this lab you will be able to


1. Use switch/case statements in C.


2. Use callback functions implemented with C function pointers.


3. Use a simple event?handling framework to construct an interactive program. Setup


In the terminal:


1. Add the new directory '9' to the root directory of your repository. This


will be the working directory for all the instructions below.


2. Fetch the new material for Lab 9, stored in a compressed tarball: $ wget


3. Expand the archive into the working directory:


$ tar xzvf lab9.tgz Event?driven interactive programs


All the programs we have written so far have run, perhaps processed some input


data, and then stopped. If data were needed from standard input the program was


blocked from running, waiting for the user to type a line and press 'return'.


Now consider an interactive program like a realtime video game. The game does not


pause for input. If you do nothing the simulated world keeps updating and the


graphics are redrawn several times a second. When you press a key or click a


button, the program needs to respond very quickly, preferably without waiting for the


'return' key. The same is true for applications like a web browser or movie player: the


application often has work to do 'in the background' while it waits for user




In desktop and mobile applications there are many kinds of user input: e.g. key


presses, mouse clicks, the mouse moving into and out of a window, a finger?tap on a


touchscreen. There are also other things that can happen to a program: e.g. a


window gets created, the user quits, a network message is received. Most interactive


programs use a generalized abstraction to handle all the things that can happen to


them: the event?handling loop. Events


Everything that requires a response from your program is represented as an 'event'.


Each event has a type and usually has some related data that depends on the type.


For example, a mouse click is represented as an event with a type 'mouse?click' and


related data indicating where the mouse pointer was when the button was clicked


along with the state of the keyboard modifer keys (shift, control, etc).


The application's job is to respond appropriately to events. This is an event?driven


program. Event queue and event?handling loop


The architecture of most event?driven programs is very simple: a queue of events is


maintained by a combination of the underlying operating system and a library linked


into the program. The program has this characteristic loop structure: do all necessary initialization while( 1 ) { while( event queue is not empty ) { get next event from queue handle the event } do background work } For the program to feel responsive i.e. have very low delay before responding to


user?generated events, the event queue query, the event handler and the 'do background work' code should each run very quickly. Experience shows this is


often reasonable for real programs. Event handler dispatch


Consider the 'handle the event' section of the event?handling loop. This must


inspect the event type to figure out what to do with it, and then (typically) call a


function to handle the event. This is called event handler dispatch and is logically


something like this:


if( event.type == MOUSE_CLICK ) { handle_mouse_click( event ); } elseif( event.type == KEY_PRESS ) { handle_key_press( event ); } else if( event.type == KEY_RELEASE ) { handle_key_release( event ); } else if( event.type == MOUSE_ENTERS_WINDOW ) { handle_mouse_enters( event ); } // etc etc etc Switch/case statement


This logic is so common that C has a language feature that makes it easier to write:


the switch/case statement.


switch( event.type ) { case MOUSE_CLICK: handle_mouse_click( event ); break; case KEY_PRESS: handle_key_press( event ); break; case KEY_RELEASE: handle_key_release( event ); break; case MOUSE_ENTERS_WINDOW: handle_mouse_enters( event ); break; // etc etc etc } The general form of a switch/case statement is:


switch( value ) { case constant_1: // code to run if value == constant_1 break; case constant_2: // code to run if value == constant_2 break; // ... case constant_n: // code to run if value == constant_n break; default: // runs if value did not equal any cases above. } The break statements can be ommitted in order to match multiple cases. This is


useful when the same function can handle multiple event types, for example:


switch( event.type ) { case MOUSE_CLICK: handle_mouse_click( event ); break; case KEY_PRESS: case KEY_RELEASE: case KEY_REPREAT: handle_key( event ); break; } Which will call handle_key() when event.type is either KEY_PRESS,




The switch statement is ideal for event dispatch and anywhere that a large if/else?


if/else?if statement is used and all conditions are constant values.


More examples can be seen here. Event filters


Real?world systems like Windows and Android have tens or hundreds of event


types, and handling them all this way leads to a large chunk of tedious code. Most


applications are very similar, so many events can have built?in default behaviour. For


example, clicking and dragging on a title bar of a window will almost always move


the window and the application does not need to do anything specific. So most real


systems have a mechanism for specifing that you only wish to receive events of


certain types, and the rest can be handled automatically with the default behaviour.


There are two main designs for event frameworks to do this. The first is to provide a


function that allows you to specify a filter which contains only those events in which


you are interested:


SetEventMask( MOUSE_CLICK | KEY_PRESS | KEY_RELEASE ); After calling this function only the listed event types will appear in the event queue,


where they must be dispatched as before.


The second method is more interesting and handles the event queue and dispatch


code automatically. Event Callbacks


In the second method, we simultaneously tell the event framework what events we


are interested in and what to do when they occur, for example:


AddEventHandler( MOUSE_CLICK, handle_mouse_click ); AddEventHandler( KEY_PRESS, handle_key_press ); AddEventHandler( KEY_RELEASE, handle_key_release ); In each call, the event type argument is followed by the name of a function that must


be called to handle events of that type. Now, instead of getting events from the


queue and dispatching them in a switch, we simply ask for all the events on the


event queue to be handled by the registered function:


DispatchEvents(); // call one function for each outstanding event This is the method of callback functions and most real?world event frameworks


use them. We have not seen functions passed as arguments before. You may be


surprised to see that function names can be used as if they were values. What does


the name of a function mean anyway? As usual in C, the answer is 'pointer'. Function pointers


The name of a function in C is a pointer to that function. The value of the pointer is


the base address of the function's executable code in memory. The type of such a


pointer is quite complex: it is type pointer?to?function?with?this?return?type?and?these?


argument?types. It is easiest to see with an example. The function strlen() is


declared in string.h like this:


size_t strlen(const char *s); the type of strlen is "pointer to a function that returns a size_t and takes a


const char pointer as an argument". This is a mouthful, and unfortunately the C


syntax to declare these pointers without a normal function declaration is famously


ugly. Here is a program that declares a function pointer of the correct type to copy


the value of strlen:


#include <stdio.h> #include <string.h> int main( int argc, char** argv ) { const char* str = "Hello World"; // call strlen as normal size_t a = strlen( str ); // declare a function ptr that has the same type and value as strlen size_t (*fptr)(const char*) = strlen; // show that strlen and fptr have the same value printf( "strlen %p fptr %p\n", strlen, fptr ); // use the function pointer to call the function size_t b = fptr( str ); // results of calls are the same printf( "a %lu b %lu\n", a, b ); return 0; } If you're not convinced, you can compile and run this program. The output on my


machine is:


strlen 0x7fff9a9ecd20 fptr 0x7fff9a9ecd20 a 11 b 11 (the large values for the function pointer will be different for you).


Note the awkward syntax for declaring the variable fptr. As usual for a pointer we


could have initialized it to NULL: size_t (*fptr)(const char*) = NULL; But calling a function via a NULL pointer causes a segmentation fault, as you might




While this syntax is hard to love, there is no concensus on how to improve upon it.


Most programmers use a typedef for function pointer types to make code easier to


read. We show this in the example below. Pointers to functions as arguments


Now we know how to declare variables that are pointers to functions, we can use


them as arguments passed into functions:


void printnumber( int num ) { printf( "number is %d\n", num ); } void CallFunctionRepeat( void (*callback)(int), int numtimes ) { for( int i=0; i<numtimes; i++ ) callback( numtimes ); } int main( int argc, char** argv ) { CallFunctionRepeat( printnumber, 5 ); return 0; } The output is:


number is 5 number is 5 number is 5 number is 5 number is 5 Implementing event dispatch using callback functions


This is an advanced topic for interested students only. You can safely skip to the


Tasks: finish the Mondrioids game section below


To complete the event?handing dispatch callback mechanism, we need to record


which function function pointer goes with which event. Then when events occur, we


call the appropriate function: /* sketch of event?handling code */ #include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct { unsigned int type; // more information about events here // .... } event_t; // use a typedef to avoid the awkward syntax of function pointers typedef void (*)(event_t) callback_t; const size_t NUMBER_OF_EVENT_TYPES = 10; /* array contains one callback function pointer for each event type. These will be initialized to NULL then modified by calls to EventsAddCallback(); */ callback_t callback_array[ NUMBER_OF_EVENT_TYPES ]; void EventsInitialize( void ) { // fill event handling array with NULL pointers for( size_t i=0; i<NUMBER_OF_EVENT_TYPES; i++ ) callback_array[i] = NULL; } void EventsAddCallback( unsigned int eventtype, callback_t callback ) { // store the callback function pointer in an array of all possible event types callback_array[ eventtype ] = callback; } void EventsDispatch( void ) { while( event_queue_length() > 0 ) { // get the next event from the queue event_t event = event_queue_pop(); // find the function pointer in the database for this event type callback_t callback = callback_array[ event.type ]; // if a callback was installed, call it to handle the event if( callback != NULL ) callback( event ); } } void handle_mouse_clicks( event_t event ) { // deal with clicks } int main( int argc, char** argv ) { EventsInitialize(); EventsAddCallback( MOUSE_CLICK, handle_mouse_clicks ); while( 1 ) { // call callbacks for any events that happen EventsDispatch(); // do any other work that needs done... } return 0; } Note how this realistic code has exactly the form of the abstract event loop


introduced above.


Most programmers don't implement the underlying framework code like this very


often, but we use event?based frameworks all the time, so it's good to know how


they work.


(End of advanced topic) Tasks: finish the Mondrioids game


In this week's assignment you must complete two callbacks to handle user input for a


video game, and tighten up the graphics.


The code download for this lab contains the skeleton of a simple Asteroids?like


game. It contains:


1. roids.c ? main game code


2. gui.c ? simple GUI with callback event?loop


3. brightcolor.c ? utility for generating nice bright colors


4. Makefile ? for building the program


Search for the word "TASK" in roids.c to find the five functions to finish. Tasks 1..5


1. Complete the functions in roid.c.


2. Commit roid.c to your repo in directory 9. Extra work


If you want to stretch yourself, you can add additional features to roids. There's no


credit for this work, apart from feeling good about yourself. Suggested additional features


Ship collisions with roids (easy)


Multiple lives (less easy, since you need to choose a safe moment to respawn) Multiple players sharing a keyboard (harder: need to update key data




Network coop multiplayer (shoot roids together) (harder: need to learn basic


IP networking, but sendto(), recvfrom() UDP messaging should be enough)


Network combat multiplayer (shoot each other) (same as previous but maybe


more fun)


Lab complete. Back to the list of labs.


Solution details:

This question was answered on: Sep 18, 2020

PRICE: $15 (25.37 KB)

Buy this answer for only: $15

This attachment is locked

We have a ready expert answer for this paper which you can use for in-depth understanding, research editing or paraphrasing. You can buy it or order for a fresh, original and plagiarism-free copy from our tutoring website (Deadline assured. Flexible pricing. TurnItIn Report provided)

Pay using PayPal (No PayPal account Required) or your credit card . All your purchases are securely protected by .

About this Question






Sep 18, 2020





We have top-notch tutors who can do your essay/homework for you at a reasonable cost and then you can simply use that essay as a template to build your own arguments.

You can also use these solutions:

  • As a reference for in-depth understanding of the subject.
  • As a source of ideas / reasoning for your own research (if properly referenced)
  • For editing and paraphrasing (check your institution's definition of plagiarism and recommended paraphrase).
This we believe is a better way of understanding a problem and makes use of the efficiency of time of the student.


Order New Solution. Quick Turnaround

Click on the button below in order to Order for a New, Original and High-Quality Essay Solutions. New orders are original solutions and precise to your writing instruction requirements. Place a New Order using the button below.


Order Now