Giter Site home page Giter Site logo

jellysg / so_long Goto Github PK

View Code? Open in Web Editor NEW
3.0 1.0 0.0 1.24 MB

2D game developed using MiniLibX, 42's graphics library.

Home Page: https://42singapore.sg/

C 82.70% Makefile 3.47% Roff 12.44% Perl 0.38% Shell 1.01%
2d 2d-game 42 42projects c mlx so-long so-long42 42singapore

so_long's Introduction

Introduction to 42's so_long

and thanks for the fish(???)

Mandatory features

  • WASD to move the player
  • Should not be able to move into walls
  • View has to be 2D (top-down or profile)
  • Game doesn't have to be in real-time
  • There should be a valid path from Player to all collectibles and the exit
  • Collect all coins before escaping

Bonus features

  • Lose upon touching an enemy patrol
  • Sprites have animations
  • Movement count is shown directly on screen

Compiling

After cloning, make sure you are in ./core/02_so_long/ directory, then make:

make

To test the game, run the following:

./so_long ./maps/(map name).ber

Tutorial: Getting started on so_long

Disclaimer:

Due to unoptimized struct linking, I have to make extra frees before malloc. This is not only unnecessary line bloat, but also makes it harder to understand when reviewing the source code.
I apologize for the messy linking and extra frees here and there, they were mostly a band-aid to passing valgrind and speed up the submission overall. It could definitely be done better and I will revisit this when I have more time in the future.

Short introduction to MiniLibX:

MiniLibX (MLX) is a beginner-friendly API for C, used mainly for a window system called X11.

Installing MLX:

Install MLX by either downloading it directly from the project page or this command:

git clone https://github.com/42Paris/minilibx-linux.git mlx

Dependencies:

MLX (and X11 itself) depends on certain packages to carry out some functions. They can be installed with the following command:

sudo apt-get install gcc make xorg libxext-dev libbsd-dev

Makefile additions:

These are some of the additions to your Makefile to ensure the X11 and MLX files are accessible:

...
INCLUDES = -I/usr/include -Imlx
MLX_FLAGS = -Lmlx -lmlx -L/usr/lib/X11 -lXext -lX11
...

Core MLX functions for so_long:

  • mlx_init

Initializes the mlx library before anything else.

  • mlx_new_window

Creates a new window instance.

  • mlx_hook

"Hooks" or registers events onto the window or mlx pointer.

  • mlx_loop

Loops across the mlx pointer, registering the hooks in the same order they are called.

  • mlx_xpm_file_to_image

Converts XPM to a viewable image on an mlx pointer.

  • mlx_put_image_to_window

Puts... image.. to window.. I don't know how else to explain this.

The following have to be called in the same order or there will be memory leaks:

  • mlx_destroy_image

Frees image stored in 'mlx_xpm_file_to_image' pointers.

  • mlx_destroy_window

Frees the window instance.

  • mlx_destroy_display

Frees mlx.
(Note: This frees the mlx functions but you still have to free your own mlx pointer!)

Here is an example for creating a window using MLX:

#include <stdlib.h>
#include "mlx/mlx.h"
 
int main(void)
{
	void *mlx_ptr;
	void *win_ptr;
 
	mlx_ptr = mlx_init();
	win_ptr = mlx_new_window(mlx_ptr, 300, 300, "test");
	sleep(5); // 5 second sleep before closing the window
	mlx_destroy_window(mlx_ptr, win_ptr);
	mlx_destroy_display(mlx_ptr);
	free(mlx_ptr);
	return (0);
}

Hooks and Loops:

  • Hooks are important for MLX as it allows the window to receive and process certain user-inputs like keypress, mouse-click, etc.
  • Loops will essentially "hold on" to the window and listen for any previously defined hooks.

Here is a modified independant snippet of my source code:

#include <stdio.h>
#include <stdlib.h>
#include "mlx/mlx.h"
#include <X11/X.h>
#include <X11/keysym.h>
 
typedef struct s_data
{
	void *mlx_ptr;
	void *win_ptr;
} t_data;
 
int on_destroy(t_data *data)
{
	mlx_destroy_window(data->mlx_ptr, data->win_ptr);
	mlx_destroy_display(data->mlx_ptr);
	free(data->mlx_ptr);
	exit(0);
	return (0);
}
 
int on_keypress(int keysym, t_data *data)
{
	// Casted (void) as it is declared but intentionally not being used, yet ;D
	(void)data;
	printf("Pressed key: %d\\n", keysym);
	return (0);
}
 
int main(void)
{
	t_data data;
 
	data.mlx_ptr = mlx_init();
	data.win_ptr = mlx_new_window(data.mlx_ptr, 300, 300, "test");
 
	// Key Hook - when a key is pressed, it will call on_keypress
	mlx_hook(data.win_ptr, KeyPress, KeyPressMask, &on_keypress, &data);
 
	// Destroy Hook - when the window is closed, it will call on_destroy
	mlx_hook(data.win_ptr, DestroyNotify, StructureNotifyMask, &on_destroy, &data);
 
	// Loop the above hooks
	mlx_loop(data.mlx_ptr);
	return (0);
}

What happens is the window will wait for the user to input keypresses or close the window:

  • When a key is pressed, it will print the pressed key in the terminal.
  • When window is closed, it will carry out the function on_destroy.

Note: KeyPress and DestroyNotify are X11 events; accessible via importing the X11 headers.

Here are some pointers to take note of when tackling this project:

  1. XPM has to be converted to image first before putting into window
  2. The map has to have a valid path for the Player to navigate to all collectibles and the exit (if 1 collectible is walled off, it should be an error)
  3. This project has a heavy focus on memory manipulation at all stages. Segmentation fault will be very common.
  4. Linking structs without proper planning will often cause memory leaks. Plan your structs ahead of time, especially if they involve arrays!
  5. Approximately 70% of the time will be spent on just handling data from reading the map. Do not be discouraged if you spend most of your time just fixing map reading, it is expected!
  6. itch.io is a good platform for sourcing free assets

so_long's People

Contributors

jellysg avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.