A small 2D game to learn how to work with windows, colors, events and textures. Inspired by the "42 Coding School" exercise "so_long" (October 2021).
open, close, read, write, printf, malloc, free, perror, strerror, exit
Aditionally all functions of the MinilibX can be used.
The aim of the exercise is to create a small 2D game in which the player has to collect some loot on a map, before leaving it.
- The player’s goal is to collect all collectibles present on the map and then escape.
- The current number of movements must be displayed.
- The player must be able to move: up, down, left, right.
- The player cannot move into walls.
- The program is dosplayed in a window.
- The arrow-keys and/or the W, A, S, and D keys will be used to move around the map.
- Pressing ESC or clicking on the close button on the window’s frame must close the window and quit the program cleanly.
- As argument the program takes a map-file.
- If a misconfiguration of any kind is encountered in the map-file, the program must exit properly and return "Error\n" followed by an explicit error message.
- The map-file has to be of type ".ber".
- It can only consist of 5 possible characters:
- '0' for an empty space
- '1' for a wall
- 'C' for a collectible
- 'E' for a map exit
- 'P' for the player’s starting position
- The map must be closed/surrounded by walls.
- The map must have:
- at least one exit
- at least one collectible
- only one starting position
- The map has to be rectangular.
Next: Prerequisites Previous: Introduction [Contents]
I started with reading, storing and errorchecking the map-file. To make sure everything worked as it is supposed to, I printed the stored data into the terminal and checked weather I get back the map-file's original content.
The main difficulty with this project for me was to get to know the mlx-functions and to learn how they work or at least how to use them. First I learned how to initialize mlx and open a window. The result is a black window. Then I tried to display pixels in different colors using mlx_pixel_put. Once I managed this, I arranged the colored pixels to display lines, then rectangels and so on.
After that I learned how to write pixels to an image and how to put images to the window. This was the perfect function for my project, as you can also load images into your program instead of drawing them pixel by pixel. The grid-like layout of the map is particularly suited to work with tiles. This means that each field of the map will be represented by a certain image in accordance to the map-file's definition.
My next step was to display the map within the window using different images. I use one image per map-file character. For diversion it would also be possible to user various images for the same map-file character and vary them. The only exception is the player where I use different images depending on the direction it is heading, but this is something I implemented later.
Now I had to find a way to change what I see when pressing certain keys. Therefore I learned about events and how to hook into them. To see if I got it right, I startet printing the keycodes into the terminal. Then instead of printing the keycodes on key-press, I checked for the keycode instead and executed different functions, depending on the pressed key.
To get the impression of movement you can think of a flicker book, where you have an image that changes slightly page by page. Instead of pages you have a window and key-press by key-press you can put new images on top of the old ones. In my opinion it is enough to only put new images on the map-fields that change, but I guess you could also refresh the whole map each time, but I don't think that it is necessary.
Next: How to launch Previous: Approach [Contents]
Tested on macOS Catalina 10.15.7 (link to Linux version)
- gcc (
sudo apt-get install gcc
) - make (
sudo apt-get install make
)
Next: How to play Previous: Prerequisites [Contents]
Compile the program via the Makefile by using make
in the root directory of the repository.
Run it by giving it the path to the map-file as argument (in this case the file "example.ber" within the directory "maps"):
./so_long maps/example.ber
For the required map-file format see: Map-file
Next: Example Previous: How to launch [Contents]
You are a fly and have to collect all the poo on the map and escape into the bright light. But be careful, there is a hungry frog who wants to eat you. If you get caught, you lose. You can create your own map, by creating a map-file.
W
/ ARROW-UP
- Move upwards
A
/ ARROW-LEFT
- Move left
S
/ ARROW-DOWN
- Move downwards
D
/ ARROW-RIGHT
- Move right
ESC
- Exit game
Next: Resources Previous: How to play [Contents]
Sample of a game on the map "example_small.ber"
MiniLibX documentation made by hsmits and @jvan-sni.
Images used from https://opengameart.org/ and https://www.seekpng.com/.
As there was no wait or sleep function allowed, I did something called "busywaiting" or "spinning" to create time-delays. In general this should not be done because it creates unneeded load on the CPU and the delay is unpredictable (depends on the computer and its workload).