CS 3 (Spring 2025) Project 03: Scenes (Demo)

In this project, you will write a version of the game pacman.

Code Correctness

Setup

Before we start, register for the project using the registration tool.

Engine Changes

Like last week, our engine library has been updated with even more functionality this week. Unlike last week, you will actually be using the library to implement a demo this week. Let’s go over the changes that were made to the engine; we encourage you to follow along by reading the relevant files as you read the guide. We also highly recommend you to read the engine changes in its entirety before writing any code for the demo.

body_t

body_t still retains most of the functions that it had last week, although some have been repurposed (for example, body_translate has been replaced by body_set_centroid). body_init also doesn’t take in an initial velocity nor rotation speed, but it does take in a mass. The mass won’t be useful for this project, but it will be once forces and collisions are implemented in the engine. We also wanted to highlight that body_rotate has been repurposed to body_set_rotation and is used slightly differently. Read its documentation carefully to understand how to use it.

We’ve also renamed the body_move function to body_tick. We’ve done so to introduce the idea of a game “tick” during which state gets updated. This is basically a wrapper around the dt idea we’ve been using.

list_t

list_init now contains a free_func_t parameter. The free_func_t type is defined at the top of list.h. Essentially, it’s defining the free_func_t type as any function that returns void and takes in a void * (generic pointer).

You can’t see the implementation of list_free, but suppose we didn’t take in a free_func_t parameter. Then a reasonable (and probably the only valid) implementation of list_free is to free() every element that it contains, and then to free the list_t itself. However, what if the objects inside the list_t allocate memory for their fields? In the case for an object like body_t, free() would only free the space allocated for the body_t struct, but not any of the fields that might’ve been allocated in body_init(), leading to memory leaks. Thus, we pass in a free_func_t so that the list_t knows which function to run on each element when list_free is called. In the case of our body_t example, we would initialize a list_t of bodies with list_init(capacity, body_free).

Importantly, list_t takes ownership of its elements depending on if freer is NULL or not. If freer is NULL, then the list_t doesn’t free its elements whatsoever when list_free is called. This might not be relevant to this project, but it will be if you ever want to keep ownership of an item while adding it to a list_t.

scene_t

This week, we’ve added a new scene_t abstraction to represent a collection of bodies. While its functionality seems pretty basic for now, it will be much more helpful in later weeks and prove to be much easier to manage than a list_t of bodies. We highly recommend you to start using it this week, for another reason that will be mentioned below.

sdl_wrapper

We’ve added an sdl_render_scene function that takes in a scene_t and renders all of its bodies onto the screen. This is yet another example of abstraction and helps us by calling many of the sdl functions for us.

Most importantly, we’ve also implemented key handling in our sdl_wrapper this week. We’ve updated sdl_wrapper.h with the new arrow_key_t and key_event_type_t enums, an sdl_on_key function, and and a new key_handler_t type (similarly to how we defined a free_func_t type in list.h). Futhermore, sdl_is_done has been updated to handle keypresses.

Rather than elaborating further on the changes, we want you to figure out how they all work together. Carefully read the contents of each new/modified function in sdl_wrapper.h/c along with their documentation. If you need more help, we encourage you to come talk to a TA at office hours.

Deliverable

This week’s demo is a pacman-like game in which pacman runs around the screen eating pellets. The novel SDL feature this week is keyboard events, so the user should be able to control pacman using the arrow keys. To implement this, we recommend thoroughly reading through sdl_wrapper.c/h.

We expect your demo to contain (at least) the following:

In pacman.c, we have given you some starter code to create the pacman shape and pellet bodies. However, the rest of the demo is left to you.

To compile pacman.c you will want to use the make demo command. Once you navigate to the link printed to the shell (the last line before “Serving HTTP on …”), click the compiled pacman.demo.html file.

Once you are done, push your code to GitLab to finish the project.