Question Details

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


Hi,

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

Cheers.


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 http://www.cs.sfu.ca/~vaughan/lab9.tgz

 

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

 

commands.

 

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,

 

KEY_RELEASE or KEY_REPEAT.

 

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

 

expect.

 

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

 

structures).

 

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:
STATUS
Answered
QUALITY
Approved
ANSWER RATING

This question was answered on: Sep 18, 2020

PRICE: $15

Solution~0001013027.zip (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 www.aceyourhomework.com (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 .
SiteLock

About this Question

STATUS

Answered

QUALITY

Approved

DATE ANSWERED

Sep 18, 2020

EXPERT

Tutor

ANSWER RATING

GET INSTANT HELP/h4>

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.

NEW ASSIGNMENT HELP?

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.

WE GUARANTEE, THAT YOUR PAPER WILL BE WRITTEN FROM SCRATCH AND WITHIN YOUR SET DEADLINE.

Order Now