This is a new type of dungeon crawler...
apt-get install
the following
libsdl2-2.0-0 - Simple DirectMedia Layer
libsdl2-dev - Simple DirectMedia Layer development files
libsdl2-image-2.0-0 - Image loading library for Simple DirectMedia Layer 2, libraries
libsdl2-image-dev - Image loading library for Simple DirectMedia Layer 2, development files
cd
into top directory
make
./game
The clang format file is in the root directory. For vscode install and enable the C/C++ extension, search user settings for C_Cpp: Clang_format_style
and set it to file.
A game is defined by it's states, thus the best way to contribute would be to implement more states. Every state is represented by an array of strings and a corresponding enum and is defined as follows...
/* from Assets.c */
static char *asset_strings_f[] =
{
"map_directions",
"graphics/map.png",
"graphics/forest.png",
"graphics/pally_1_edit.png",
"graphics/pally_walk.png"
};
enum asset_enum
{
map_directions_e,
floor_forest_ground,
floor_forest_trees,
hero,
hero_walk
};
Each member of these lists represents an action that needs to be performed in order to achieve the goals of the states. Every action corresponds to a game class such as Floor.
#ifndef JRPG_FLOOR_H
#define JRPG_FLOOR_H
/**
* Holds an SDL Texture that resembles the ground in SDL2_Crawler,
* see map and forest in main.c
*/
typedef struct _Floor
{
void (*destroy)(struct _Floor *); /* Free Allocated Memory */
void (*render)(void *obj, SDL_Renderer *renderer); /* Render function */
void (*logic)(void *obj); /* Logic function */
SDL_Texture *texture; /* SDL Texture */
SDL_Rect rect; /* SDL Rectangle */
} Floor;
Floor *CREATE_FLOOR(int x, int y, int w, int h, SDL_Renderer *renderer, const char *path);
Every game class object contains two important functions render()
and logic()
. In main.c
we define two hash tables...
Hash_r *render_table; /* Hashtable of render functions */
Hash_l *logic_table; /* Hashtable of logic functions */
As well as corresponding game state lists...
char **state_logic; /* State list for logic functions */
char **state_render; /* State list for render functions */
The appearance that is generated and the logic that is performed varies from state to state. One thing that states have in common is that they all render graphics and they all perform game logic, thus We have two hash tables that contain all the possible rendering and logical actions. A state is executed when the string array of a state is passed into the draw or logic functions...
/* game loop in main.c */
while (!EXIT())
{
start_timer();
state_logic = create_state(get_dark_forest_logic(), 4, state_logic);
state_render = create_state(get_dark_forest_render(), 3, state_render);
mouse->get_state(mouse);
logic(logic_table, state_logic, 4);
draw(render_table, state_render, renderer, 3);
FRAMES_RENDERED = delay();
set_fullscreen(window);
reset_timer();
}
Hence the elements in state_logic
and state_render
are keys in the hash table. We execute logic and render functions as we iterate through the arrays...
/* draw defined in Assets.c */
void draw(Hash_r *table, char **state, SDL_Renderer *renderer, int num)
{
Render_Node *temp;
SDL_RenderClear(renderer); /* Clear Canvas */
for (int i = 0; i < num; i++)
{
temp = table->search(table, state[i]); /* Get render node */
(*temp->funct)(temp->obj, renderer); /* execute render function */
}
SDL_RenderPresent(renderer); /* draw to canvas */
}
Game Classes are added to a hash table as follows ...
/* Instantiate a floor object */
Floor *floor = CREATE_FLOOR(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, renderer, asset_strings[i]);
/* Insert a logic node */
t_l->insert(t_l, CREATE_LOGIC_NODE(asset_strings[i], floor, floor->logic));
/* Insert a render node */
t_r->insert(t_r, CREATE_RENDER_NODE(asset_strings[i], floor, floor->render));
A node is defined as follows
#ifndef RENDER_NODE_H
#define RENDER_NODE_H
typedef void render_function(void *obj, SDL_Renderer *renderer);
/**
* Encapsulate data for Render Table
*/
typedef struct _Render_Node
{
void (*destroy)(struct _Render_Node *this); /* Free allocated memory */
void (*print)(struct _Render_Node *this, int i); /* Print node data */
render_function(*funct); /* Pointer to render function */
void *obj; /* Pointer to object whose render function will be called */
int index; /* Index the node is stored at */
char *key; /* Key of node */
} Render_Node;
Render_Node *CREATE_RENDER_NODE(char *key, void *obj, render_function funct);``c