From 908b97131760d7dd5ddaabe246a99a2e30e5fc9f Mon Sep 17 00:00:00 2001 From: mibi88 <76903855+mibi88@users.noreply.github.com> Date: Sat, 8 Jul 2023 15:55:06 +0200 Subject: [PATCH] Restructured a lot of things. Collisions are not working properly but I'll fix that --- CMakeLists.txt | 2 ++ src/game.c | 13 +++++++++ src/game.h | 22 +++++++++++++++ src/main.c | 32 +++++++++------------- src/map.c | 16 ++++++++++- src/map.h | 23 ++++++---------- src/mapstruct.h | 18 ++++++++++++ src/memory.c | 12 ++++++++ src/memory.h | 9 ++++++ src/player.c | 73 +++++++++++++++++++++++++++++++------------------ src/player.h | 35 ++++++++++++++++++------ 11 files changed, 185 insertions(+), 70 deletions(-) create mode 100644 src/game.c create mode 100644 src/game.h create mode 100644 src/mapstruct.h create mode 100644 src/memory.c create mode 100644 src/memory.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ceb767e..98b9ef1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,8 @@ set(SOURCES src/main.c src/map.c src/player.c + src/memory.c + src/game.c # ... ) # Shared assets, fx-9860G-only assets and fx-CG-50-only assets diff --git a/src/game.c b/src/game.c new file mode 100644 index 0000000..f424503 --- /dev/null +++ b/src/game.c @@ -0,0 +1,13 @@ +#include "game.h" + +#include "map.h" + +void game_logic(Game *game) { + // to be done +} + +void draw(Game *game) { + render_map(&game->player, game->map_level); + player_draw(&game->player); +} + diff --git a/src/game.h b/src/game.h new file mode 100644 index 0000000..e01632e --- /dev/null +++ b/src/game.h @@ -0,0 +1,22 @@ +#ifndef GAME_H +#define GAME_H + +#include "mapstruct.h" +#include "player.h" + +/* This struct will contain all the data of the game. It will make it possible + * to pass it to the NPCs to let them interact with the player and the rest of + * the world. */ +typedef struct { + Map *map_level; /* The level that the player is currently playing */ + Player player; /* The player data (see player.h). */ +} Game; + +/* (Mibi88) TODO: Describe what this function is doing. */ +void game_logic(Game *game); + +/* Draws everything on screen. */ +void draw(Game *game); + +#endif + diff --git a/src/main.c b/src/main.c index d803bff..21ff533 100644 --- a/src/main.c +++ b/src/main.c @@ -21,13 +21,14 @@ #include #include -#include "map.h" -#include "player.h" +#include "game.h" #include "mapdata.h" -/* Player data (defined in "player.h")*/ -Player MyPlayer = { 10, 5, 0, 0, 100 }; -Map *map_level = &map_level0; +/* Game data (defined in "game.h")*/ +Game game = { + &map_level0, + {10, 5, 0, 0, 100} +}; /* some global variables */ bool exittoOS = false; // set to true when asked for exit @@ -51,11 +52,11 @@ static void get_inputs( void ) if(keydown(KEY_EXIT)) exittoOS = true; /* Player actions - Prototypes in player.h and implementation in player.c */ - if(keydown(KEY_LEFT)) PlayerLeft(); - if(keydown(KEY_RIGHT)) PlayerRight(); - if(keydown(KEY_UP)) PlayerUp(); - if(keydown(KEY_DOWN)) PlayerDown(); - if(keydown(KEY_SHIFT)) PlayerAction(); + if(keydown(KEY_LEFT)) player_move(game.map_level, &game.player, D_LEFT); + if(keydown(KEY_RIGHT)) player_move(game.map_level, &game.player, D_RIGHT); + if(keydown(KEY_UP)) player_move(game.map_level, &game.player, D_UP); + if(keydown(KEY_DOWN)) player_move(game.map_level, &game.player, D_DOWN); + if(keydown(KEY_SHIFT)) player_action(&game.player); /* if USB is enabled - keybinding for screencapture */ @@ -105,12 +106,6 @@ static void get_inputs( void ) #endif - -void GameLogic(void) { - // to be done -} - - int main(void) { #if USB_FEATURE==1 @@ -132,11 +127,10 @@ int main(void) { dclear(C_WHITE); /* render the map */ - RenderMap(&MyPlayer, map_level); - PlayerDraw(); + draw(&game); /* start the logic of the game */ - GameLogic(); + game_logic(&game); /* Screen blit */ dupdate(); diff --git a/src/map.c b/src/map.c index 749b6e7..c52c70a 100644 --- a/src/map.c +++ b/src/map.c @@ -2,7 +2,7 @@ #include -void RenderMap(Player *player, Map *map_level) { +void render_map(Player *player, Map *map_level) { /* for all Layer (2 in the current configuration: Background is layer 0 and * foreground is layer 1 ) */ /* x and y will contain the position in the loop. */ @@ -87,3 +87,17 @@ void RenderMap(Player *player, Map *map_level) { } } +/* short int get_tile_at_pos(Map *map_level, int x, int y, int l) { + unsigned short int xtile = x/T_WIDTH; + unsigned short int xtile = x/T_HEIGHT; + unsigned short int map_w = map_level->w*T_WIDTH; + unsigned short int map_h = map_level->h*T_HEIGHT; + return x>=0 && x < map_w && y>=0 && y < map_h ? + map_level->layers[l][ytile * map_level->w + xtile] : MAP_OUTSIDE; +} */ + +short int get_tile(Map *map_level, int x, int y, int l) { + return x>=0 && x < map_level->w && y>=0 && y < map_level->h ? + map_level->layers[l][y * map_level->w + x] : MAP_OUTSIDE; +} + diff --git a/src/map.h b/src/map.h index 0d7fe0f..42293f1 100644 --- a/src/map.h +++ b/src/map.h @@ -10,25 +10,18 @@ #define T_WIDTH 8 #endif +#define MAP_OUTSIDE -2 /* Returned by get_tile_at_pos if the point is outside of + * the map. */ -#include - +#include "mapstruct.h" #include "player.h" -typedef struct { +/* Draws the map map on the entire screen to be viewed by the player player. */ +void render_map(Player *player, Map *map_level); - /*width, height and the number of layer of the map*/ - int w, h, nblayers; - - /*the tileset to use*/ - bopti_image_t *tileset; - int tileset_size; - - /*list of all the tiles*/ - short *layers[]; -} Map; - -void RenderMap(Player *player, Map *map_level); +/* Get the tile at (x, y) of the map map. If the tile is located outside of the + * screen, MAP_OUTSIDE is returned. */ +short int get_tile(Map *map_level, int x, int y, int l); #endif diff --git a/src/mapstruct.h b/src/mapstruct.h new file mode 100644 index 0000000..bcf1c77 --- /dev/null +++ b/src/mapstruct.h @@ -0,0 +1,18 @@ +#ifndef MAPSTRUCT_H +#define MAPSTRUCT_H + +#include + +typedef struct { + /* width, height and the number of layer of the map */ + int w, h, nblayers; + + /* the tileset to use */ + bopti_image_t *tileset; + int tileset_size; + + /* list of all the tiles */ + short *layers[]; +} Map; + +#endif diff --git a/src/memory.c b/src/memory.c new file mode 100644 index 0000000..9e3e58a --- /dev/null +++ b/src/memory.c @@ -0,0 +1,12 @@ +#include "memory.h" + +bool is_in(short int *array, short int array_length, short int item) { + short int i; + for(i=0;i + +bool is_in(short int *array, short int array_length, short int item); + +#endif + diff --git a/src/player.c b/src/player.c index 5d7c582..1932a00 100644 --- a/src/player.c +++ b/src/player.c @@ -2,51 +2,72 @@ #include "map.h" #include - +/* (Mibi88) TODO: Upscale the player for the CG50. */ #define P_WIDTH 8 #define P_HEIGHT 8 - +/* SPEED should NOT be 8 or bigger: it this may cause bugs when handling + * collisions! */ #ifdef FXCG50 #define SPEED 3 #else #define SPEED 1 #endif +const char one_px_mov[8] = { + 0, -1, /* Up */ + 0, 1, /* Down */ + -1, 0, /* Left */ + 1, 0 /* Right */ +}; + +/* TODO: Search for all hard tiles in the tileset. hard_tiles is a list of their + * IDs */ +#define HARD_TILES_AMOUNT 5 +const short int hard_tiles[HARD_TILES_AMOUNT] = { + MAP_OUTSIDE, 124, 148, 125, 149 +}; -extern Player MyPlayer; -extern Map *map_level; extern bopti_image_t demo_player_img; - -void PlayerDraw(void) { - dimage(MyPlayer.px-P_WIDTH/2, MyPlayer.py-P_HEIGHT/2, &demo_player_img); +void player_draw(Player *player) { + dimage(player->px-P_WIDTH/2, player->py-P_HEIGHT/2, &demo_player_img); } -void PlayerLeft(void) { - if(MyPlayer.x >= SPEED){ - MyPlayer.x-=SPEED; +void player_move(Map *map_level, Player *player, Direction direction) { + /* How this player movement will modify the player x and y. */ + const char dx = one_px_mov[direction*2]*SPEED; + const char dy = one_px_mov[direction*2+1]*SPEED; + if(player_collision(map_level, player, direction)){ + player_fix_position(player, dx, dy); + }else{ + player->x += dx; + player->y += dy; } } -void PlayerRight(void) { - if(MyPlayer.x <= map_level->w * T_WIDTH - SPEED){ - MyPlayer.x+=SPEED; +void player_action(Player *player) { + /**/ +} + +bool player_collision(Map *map_level, Player *player, Direction direction) { + /* What's the tile the player is going to. */ + short int i; + const char dx = one_px_mov[direction*2]; + const char dy = one_px_mov[direction*2+1]; + int player_tile_x = player->x/T_WIDTH; + int player_tile_y = player->x/T_WIDTH; + for(i=0;inblayers;i++){ + if(is_in(hard_tiles, HARD_TILES_AMOUNT, + get_tile(map_level, player_tile_x+dx, player_tile_y+dy, i))){ + return true; + } } + return false; } -void PlayerUp(void) { - if(MyPlayer.y >= SPEED){ - MyPlayer.y-=SPEED; - } +void player_fix_position(Player *player, bool fix_x, bool fix_y) { + if(fix_x) player->x = player->x/T_WIDTH*T_WIDTH; + if(fix_y) player->y = player->y/T_HEIGHT*T_HEIGHT; } -void PlayerDown(void) { - if(MyPlayer.y <= map_level->h * T_HEIGHT - SPEED){ - MyPlayer.y+=SPEED; - } -} - -void PlayerAction(void) { - -} diff --git a/src/player.h b/src/player.h index 6277655..e4771a2 100644 --- a/src/player.h +++ b/src/player.h @@ -1,6 +1,19 @@ #ifndef PLAYER_H #define PLAYER_H +#include + +#include "mapstruct.h" +#include "memory.h" + +/* The direction where the player is going to. */ +typedef enum { + D_UP, + D_DOWN, + D_LEFT, + D_RIGHT +} Direction; + /* Struct that define player parameters */ typedef struct { unsigned short int x, y; /* The position of the player */ @@ -9,18 +22,22 @@ typedef struct { * and 100. */ } Player; -/* This function should be called after drawing the map ! */ -void PlayerDraw(void); +/* Draws the player player. This function should be called after drawing the + * map! */ +void player_draw(Player *player); -void PlayerLeft(void); +/* Move the player player in the direction direction. */ +void player_move(Map *map_level, Player *player, Direction direction); -void PlayerRight(void); +/* (Mibi88) TODO: Describe this function please, I've no idea what she's for! */ +void player_action(Player *player); -void PlayerUp(void); - -void PlayerDown(void); - -void PlayerAction(void); +/* Check if the player is in collision with the map or a NPC. */ +bool player_collision(Map *map_level, Player *player, Direction direction); +/* Fix the position of the player so that he's not a bit inside of a hard block + * after a collision. */ +void player_fix_position(Player *player, bool fix_x, bool fix_y); #endif +