mirror of
https://git.planet-casio.com/Slyvtt/Collab_RPG.git
synced 2024-12-28 04:23:42 +01:00
Refactoring
This commit is contained in:
parent
f6d142c920
commit
25ea360713
15 changed files with 234 additions and 144 deletions
|
@ -1,3 +1,26 @@
|
||||||
# Project structure
|
# Project structure
|
||||||
|
|
||||||
TODO: Describe the project structure.
|
* `assets` contains the tiled maps, and the tiled map converters.
|
||||||
|
* `assets-cg` contains the assets for cg calculators like the cg-50.
|
||||||
|
* `assets-fx` contains the assets for monochrome calculators.
|
||||||
|
* `captures` contains screenshots.
|
||||||
|
* `src` This folder contains the source code.
|
||||||
|
* `config.h` This header file contains defines for the size of various
|
||||||
|
things on screen, like the size of a tile in the tilemap, the size of the
|
||||||
|
dialog box, etc.
|
||||||
|
* `dialogs.c` and `dialogs.h` contain various functions to display dialogs
|
||||||
|
and also let the user respond.
|
||||||
|
* `events.c` and `events.h` parse tags in the messages that are displayed
|
||||||
|
using the dialogs procedures to modify variables (and soon, call
|
||||||
|
procedures).
|
||||||
|
* `game.c` and `game.h` handles the rendering, the input, etc.
|
||||||
|
* `main.c` handles the USB connection and the gint gray rendering, for 2bpp
|
||||||
|
rendering on monochrome calculators. Contains the mainloop. Also contains
|
||||||
|
code to display debug informations.
|
||||||
|
* `map.c` and `map.h` contain code to render, get a tile in the map, see if
|
||||||
|
the tile is walkable, etc.
|
||||||
|
* `mapdata.h` contains the available maps.
|
||||||
|
* `memory.c` and `memory.h` procedures to handle arrays (currently: search
|
||||||
|
in an array of short ints).
|
||||||
|
* `npc.c` and `npc.h` npc rendering and movement (and soon pathfinding).
|
||||||
|
* `player.c` and `player.h` handle the player movement, collision, etc.
|
||||||
|
|
|
@ -4,9 +4,10 @@ Plus d'infos sur ce projet ici : [Le projet Collaboratif de PC](https://www.plan
|
||||||
|
|
||||||
## Contribuer!
|
## Contribuer!
|
||||||
Style du code [STYLE.md](STYLE.md).
|
Style du code [STYLE.md](STYLE.md).
|
||||||
|
|
||||||
Structure du projet [PROJECT_STRUCTURE.md](PROJECT_STRUCTURE.md).
|
Structure du projet [PROJECT_STRUCTURE.md](PROJECT_STRUCTURE.md).
|
||||||
|
|
||||||
## Avencement du projet
|
## Avancement du projet
|
||||||
|
|
||||||
A ce stade, on a déjà implémenté :
|
A ce stade, on a déjà implémenté :
|
||||||
|
|
||||||
|
@ -17,12 +18,13 @@ A ce stade, on a déjà implémenté :
|
||||||
- [x] Multiple cartes avec importation automatique des fichiers `world` issus de Tiled
|
- [x] Multiple cartes avec importation automatique des fichiers `world` issus de Tiled
|
||||||
- [x] Carte Multilayer (Background, Foreground + accessibilité / Dommages) avec transparence du calque Foreground
|
- [x] Carte Multilayer (Background, Foreground + accessibilité / Dommages) avec transparence du calque Foreground
|
||||||
- [x] Personnage
|
- [x] Personnage
|
||||||
- [x] Dialogues avec fichiers externes `json` et séquenceage possible de ceux-ci via un arbre d'histoire (sauts de lignes et mots plus grands que l'écran pas supportés)
|
- [x] Dialogues avec fichiers externes `json` et séquenceage possible de ceux-ci via un arbre d'histoire (sauts de lignes et mots plus grands que l'écran pas supportés + limite d'un kibibyte)
|
||||||
- [x] Fontes de caractères
|
- [x] Fontes de caractères
|
||||||
- [x] Interaction
|
- [x] Interaction
|
||||||
- [ ] NPC
|
- [ ] NPC
|
||||||
- [x] Changement de map durant le jeu
|
- [x] Changement de map durant le jeu
|
||||||
- [ ] Système d'événements
|
- [ ] Système d'événements
|
||||||
|
- [ ] Pathfinding
|
||||||
|
|
||||||
|
|
||||||
## Crédits
|
## Crédits
|
||||||
|
|
44
README_en.md
Normal file
44
README_en.md
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Planet Casio Collaborative Project
|
||||||
|
|
||||||
|
(maybe I should've used google translate)
|
||||||
|
|
||||||
|
More informations can be found here (in french):
|
||||||
|
[Le projet Collaboratif de PC](https://www.planet-casio.com/Fr/forums/topic17343-last-projet-collaboratif-avec-toute-la-commu.html)
|
||||||
|
|
||||||
|
## Contribute!
|
||||||
|
Style guidelines [STYLE.md](STYLE.md).
|
||||||
|
|
||||||
|
Project structure [PROJECT_STRUCTURE.md](PROJECT_STRUCTURE.md).
|
||||||
|
|
||||||
|
## Current state
|
||||||
|
|
||||||
|
What we've implemented so far:
|
||||||
|
|
||||||
|
- [x] Screenshots via USB
|
||||||
|
- [x] Displaying the current map at the players position
|
||||||
|
- [x] Handling keyboard inputs
|
||||||
|
- [x] Handling collisions.
|
||||||
|
- [x] Multiple maps with automatic `world` files import (made with Tiled)
|
||||||
|
- [x] Multilayer map (Background, Foreground + accessibility / damage) with
|
||||||
|
foreground layer transparency.
|
||||||
|
- [x] Player character.
|
||||||
|
- [x] Dialogs from external `json` files (line jumps and words bigger than the
|
||||||
|
screen are unsupported + 1 kibibyte per message limit)
|
||||||
|
- [x] Font
|
||||||
|
- [x] Interaction
|
||||||
|
- [ ] NPC
|
||||||
|
- [x] Changing map in game.
|
||||||
|
- [ ] Event system
|
||||||
|
- [ ] Pathfinding
|
||||||
|
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
The tiles are from Game Boy Top-down RPG Fantasy Tileset (FREE)
|
||||||
|
"Background Assets by Gumpy Function (gumpyfunction.itch.io)"
|
||||||
|
[Tiles Background Assets by Gumpy Function](https://gumpyfunction.itch.io/game-boy-rpg-fantasy-tileset-free)
|
||||||
|
|
||||||
|
Converted to greyscale with gimp.
|
||||||
|
|
||||||
|
1-bit (black and white) version by Shadow15510
|
||||||
|
CG (palette EGA64) color version by Fcalva
|
10
STYLE.md
10
STYLE.md
|
@ -11,6 +11,10 @@ single line.
|
||||||
Put the curly braces after if, else, while or for statements and declarations of
|
Put the curly braces after if, else, while or for statements and declarations of
|
||||||
procedures on the same line.
|
procedures on the same line.
|
||||||
|
|
||||||
|
No spaces around parantheses, one space after a comma.
|
||||||
|
|
||||||
|
Variables names in sneak_case.
|
||||||
|
|
||||||
(Mibi88) SlyVTT, Fcalva, should be use a doc generation thing or do we describe
|
(Mibi88) SlyVTT, Fcalva, should be use a doc generation thing or do we describe
|
||||||
the procedures as I did so far?
|
the procedures as I did so far?
|
||||||
|
|
||||||
|
@ -20,9 +24,9 @@ Document your procedures as following:
|
||||||
/* procedure_name()
|
/* procedure_name()
|
||||||
*
|
*
|
||||||
* Describe what this procedure does.
|
* Describe what this procedure does.
|
||||||
* arg1: Describe this argument. If the text is too long, wrap it to the next
|
* arg1: Describe this argument. If the text is too long, wrap it to the
|
||||||
* line like this.
|
* next line like this.
|
||||||
* arg2: Describe this argument, and so on.
|
* long_name: Describe this argument, and so on.
|
||||||
*/
|
*/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ void blit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int showtext_opt(Game *game, bopti_image_t *face, char *text,
|
int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
int call_before_end(Game *game, unsigned int i),
|
int call_before_end(Game *game, unsigned int i),
|
||||||
bool start_anim,
|
bool start_anim,
|
||||||
bool end_anim,
|
bool end_anim,
|
||||||
|
@ -68,7 +68,7 @@ int showtext_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
/* Redrawing the entire screen, because maybe there was no dialog
|
/* Redrawing the entire screen, because maybe there was no dialog
|
||||||
displayed before. */
|
displayed before. */
|
||||||
update_npc(game);
|
update_npc(game);
|
||||||
draw(game);
|
game_draw(game);
|
||||||
|
|
||||||
/* Fill the dialog box with white */
|
/* Fill the dialog box with white */
|
||||||
drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE);
|
drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE);
|
||||||
|
@ -88,7 +88,7 @@ int showtext_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
}else{
|
}else{
|
||||||
/* Here I'm drawing the same as if start_anim is true, but whitout
|
/* Here I'm drawing the same as if start_anim is true, but whitout
|
||||||
* making an animation. */
|
* making an animation. */
|
||||||
draw(game);
|
game_draw(game);
|
||||||
drect(0, 0, DWIDTH, BOX_HEIGHT*PXSIZE, C_WHITE);
|
drect(0, 0, DWIDTH, BOX_HEIGHT*PXSIZE, C_WHITE);
|
||||||
drect(0, BOX_HEIGHT*PXSIZE, DWIDTH, (BOX_HEIGHT+1)*PXSIZE, C_BLACK);
|
drect(0, BOX_HEIGHT*PXSIZE, DWIDTH, (BOX_HEIGHT+1)*PXSIZE, C_BLACK);
|
||||||
dimage(4*PXSIZE, 2*PXSIZE, face);
|
dimage(4*PXSIZE, 2*PXSIZE, face);
|
||||||
|
@ -191,7 +191,7 @@ int showtext_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
for(i=BOX_HEIGHT;i>0;i--){
|
for(i=BOX_HEIGHT;i>0;i--){
|
||||||
/* It is the same as the start animation. */
|
/* It is the same as the start animation. */
|
||||||
update_npc(game);
|
update_npc(game);
|
||||||
draw(game);
|
game_draw(game);
|
||||||
drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE);
|
drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE);
|
||||||
drect(0, i*PXSIZE, DWIDTH, (i+1)*PXSIZE, C_BLACK);
|
drect(0, i*PXSIZE, DWIDTH, (i+1)*PXSIZE, C_BLACK);
|
||||||
dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (i-8)*PXSIZE,
|
dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (i-8)*PXSIZE,
|
||||||
|
@ -206,11 +206,11 @@ int showtext_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
return return_int;
|
return return_int;
|
||||||
}
|
}
|
||||||
|
|
||||||
void showtext_dialog(Game *game, bopti_image_t *face, char *text,
|
void dialogs_text(Game *game, bopti_image_t *face, char *text,
|
||||||
bool dialog_start, bool dialog_end) {
|
bool dialog_start, bool dialog_end) {
|
||||||
/* Run showtext_opt with some default values. It makes it easier to use in
|
/* Run showtext_opt with some default values. It makes it easier to use in
|
||||||
* simple dialogs. */
|
* simple dialogs. */
|
||||||
showtext_opt(game, face, text, NULL, dialog_start, dialog_end, NULL, 100,
|
dialogs_text_opt(game, face, text, NULL, dialog_start, dialog_end, NULL, 100,
|
||||||
true, 0, true);
|
true, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,8 +312,8 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
|
||||||
for(i=DWIDTH/8+1;i>0;i--){
|
for(i=DWIDTH/8+1;i>0;i--){
|
||||||
/* I'm drawing the same box as on the start animation */
|
/* I'm drawing the same box as on the start animation */
|
||||||
update_npc(game);
|
update_npc(game);
|
||||||
draw(game);
|
game_draw(game);
|
||||||
showtext_opt(game, _face, _text, NULL, false, false, NULL, 0, false,
|
dialogs_text_opt(game, _face, _text, NULL, false, false, NULL, 0, false,
|
||||||
_i, false);
|
_i, false);
|
||||||
drect(0, (BOX_HEIGHT+1)*PXSIZE+1, i*(DWIDTH/8),
|
drect(0, (BOX_HEIGHT+1)*PXSIZE+1, i*(DWIDTH/8),
|
||||||
(BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, C_WHITE);
|
(BOX_HEIGHT+CHOICE_BOX_HEIGHT)*PXSIZE, C_WHITE);
|
||||||
|
@ -330,7 +330,7 @@ int _choice_call_before_end(Game *game, [[maybe_unused]] unsigned int org_i) {
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
int showtext_dialog_ask(Game *game, bopti_image_t *face, char *text, bool start,
|
int dialogs_ask(Game *game, bopti_image_t *face, char *text, bool start,
|
||||||
bool end, char *choices, int choices_amount,
|
bool end, char *choices, int choices_amount,
|
||||||
int default_choice) {
|
int default_choice) {
|
||||||
/* Put some arguments in global pointers and variables to make them
|
/* Put some arguments in global pointers and variables to make them
|
||||||
|
@ -342,16 +342,15 @@ int showtext_dialog_ask(Game *game, bopti_image_t *face, char *text, bool start,
|
||||||
_text = text;
|
_text = text;
|
||||||
/* Run showtext_opt and return his return value (the return value of
|
/* Run showtext_opt and return his return value (the return value of
|
||||||
*_choice_call_before_end) */
|
*_choice_call_before_end) */
|
||||||
return showtext_opt(game, face, text, _choice_call_before_end, start, end,
|
return dialogs_text_opt(game, face, text, _choice_call_before_end, start,
|
||||||
_choice_screen_call, 100, true, 0, true);
|
end, _choice_screen_call, 100, true, 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void initiate_dialog_sequence(Game *game, bopti_image_t *face,
|
void dialogs_initiate_sequence(Game *game, bopti_image_t *face,
|
||||||
uint32_t dialogNumber )
|
uint32_t dialogNumber) {
|
||||||
{
|
|
||||||
Dialog *currentDiag = &game->map_level->dialogs[dialogNumber];
|
Dialog *currentDiag = &game->map_level->dialogs[dialogNumber];
|
||||||
|
|
||||||
/* we collect the information */
|
/* we collect the information */
|
||||||
|
@ -366,27 +365,23 @@ void initiate_dialog_sequence(Game *game, bopti_image_t *face,
|
||||||
int isQuestion = currentDiag->isQuestion;
|
int isQuestion = currentDiag->isQuestion;
|
||||||
|
|
||||||
/* we treat the action - i.e. we show a dialog */
|
/* we treat the action - i.e. we show a dialog */
|
||||||
if (isQuestion == 1) /* we have to manage a question */
|
if (isQuestion == 1){
|
||||||
{
|
/* we have to manage a question */
|
||||||
int answer = showtext_dialog_ask( game, face, text, true, true, choices, 2, 0 );
|
int answer = dialogs_ask(game, face, text, true, true,
|
||||||
|
choices, 2, 0);
|
||||||
|
|
||||||
/* TO DO we need to split the strings conclusion1 and conclusion2 */
|
/* TO DO we need to split the strings conclusion1 and conclusion2 */
|
||||||
/* to extract the "gift" part */
|
/* to extract the "gift" part */
|
||||||
|
|
||||||
if (answer==0)
|
if(answer==0){
|
||||||
{
|
dialogs_text(game, face, conclusion1, true, true);
|
||||||
showtext_dialog( game, face, conclusion1, true, true );
|
if (next1!=-1) dialogs_initiate_sequence(game, face, next1);
|
||||||
if (next1!=-1) initiate_dialog_sequence( game, face, next1 );
|
}else{
|
||||||
|
dialogs_text(game, face, conclusion2, true, true);
|
||||||
|
if (next2!=-1) dialogs_initiate_sequence(game, face, next2);
|
||||||
}
|
}
|
||||||
else
|
}else{
|
||||||
{
|
dialogs_text(game, face, text, true, true);
|
||||||
showtext_dialog( game, face, conclusion2, true, true );
|
if (nextOther!=-1) dialogs_initiate_sequence(game, face, nextOther);
|
||||||
if (next2!=-1) initiate_dialog_sequence( game, face, next2 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
showtext_dialog( game, face, text, true, true );
|
|
||||||
if (nextOther!=-1) initiate_dialog_sequence( game, face, nextOther );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,7 +7,7 @@
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
/* showtext_opt()
|
/* dialogs_text_opt()
|
||||||
*
|
*
|
||||||
* Show some text in a box with word wrap for dialogs.
|
* Show some text in a box with word wrap for dialogs.
|
||||||
*
|
*
|
||||||
|
@ -35,17 +35,17 @@
|
||||||
* wait_continue: If I should wait that EXE is pressed after drawing a page.
|
* wait_continue: If I should wait that EXE is pressed after drawing a page.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int showtext_opt(Game *game, bopti_image_t *face, char *text,
|
int dialogs_text_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
int call_before_end(Game *game, unsigned int i),
|
int call_before_end(Game *game, unsigned int i),
|
||||||
bool start_anim,
|
bool start_anim,
|
||||||
bool end_anim,
|
bool end_anim,
|
||||||
void for_each_screen(Game *game, unsigned int i),
|
void for_each_screen(Game *game, unsigned int i),
|
||||||
int line_duration, bool update_screen, unsigned int start_i,
|
int line_duration, bool update_screen,
|
||||||
bool wait_continue);
|
unsigned int start_i, bool wait_continue);
|
||||||
|
|
||||||
/* showtext_dialog()
|
/* dialogs_text()
|
||||||
*
|
*
|
||||||
* Calls showtext_opt with default parameters.
|
* Calls dialogs_text_opt with default parameters.
|
||||||
*
|
*
|
||||||
* game: The game struct of the current game.
|
* game: The game struct of the current game.
|
||||||
* face: A bopti_image_t of the face of the person who's saying this
|
* face: A bopti_image_t of the face of the person who's saying this
|
||||||
|
@ -58,12 +58,12 @@ int showtext_opt(Game *game, bopti_image_t *face, char *text,
|
||||||
* shown at the end of showtext_opt.
|
* shown at the end of showtext_opt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void showtext_dialog(Game *game, bopti_image_t *face, char *text,
|
void dialogs_text(Game *game, bopti_image_t *face, char *text,
|
||||||
bool dialog_start, bool dialog_end);
|
bool dialog_start, bool dialog_end);
|
||||||
|
|
||||||
/* showtext_dialog_ask()
|
/* dialogs_ask()
|
||||||
*
|
*
|
||||||
* Like showtext_dialog, but lets the user choose between multiple possible
|
* Like dialogs_text, but lets the user choose between multiple possible
|
||||||
* choices after displaying the text.
|
* choices after displaying the text.
|
||||||
*
|
*
|
||||||
* game: The game struct of the current game.
|
* game: The game struct of the current game.
|
||||||
|
@ -83,12 +83,12 @@ void showtext_dialog(Game *game, bopti_image_t *face, char *text,
|
||||||
* default_choice: The choice choosen by default when the dialog just opened.
|
* default_choice: The choice choosen by default when the dialog just opened.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int showtext_dialog_ask(Game *game, bopti_image_t *face, char *text, bool start,
|
int dialogs_ask(Game *game, bopti_image_t *face, char *text, bool start,
|
||||||
bool end, char *choices, int choices_amount,
|
bool end, char *choices, int choices_amount,
|
||||||
int default_choice);
|
int default_choice);
|
||||||
|
|
||||||
/* TODO: Doc. */
|
/* TODO: Doc. */
|
||||||
void initiate_dialog_sequence(Game *game, bopti_image_t *face,
|
void dialogs_initiate_sequence(Game *game, bopti_image_t *face,
|
||||||
uint32_t dialogNumber);
|
uint32_t dialogNumber);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
33
src/game.c
33
src/game.c
|
@ -27,8 +27,7 @@ void game_logic(Game *game) {
|
||||||
update_npc( game );
|
update_npc( game );
|
||||||
|
|
||||||
/* we check if interactions are possible close to the player */
|
/* we check if interactions are possible close to the player */
|
||||||
for( uint32_t i=0; i<game->map_level->nbextradata; i++ )
|
for( uint32_t i=0; i<game->map_level->nbextradata; i++ ){
|
||||||
{
|
|
||||||
/* simple distance check along X and Y axis */
|
/* simple distance check along X and Y axis */
|
||||||
/* Be careful to use world coordinates, not local (i.e.map) ones */
|
/* Be careful to use world coordinates, not local (i.e.map) ones */
|
||||||
if ((abs((int) game->player.wx -
|
if ((abs((int) game->player.wx -
|
||||||
|
@ -37,8 +36,7 @@ void game_logic(Game *game) {
|
||||||
&& (abs((int) game->player.wy -
|
&& (abs((int) game->player.wy -
|
||||||
(int) game->map_level->extradata[i].y*PXSIZE )
|
(int) game->map_level->extradata[i].y*PXSIZE )
|
||||||
< MAX_INTERACTION_DISTANCE*PXSIZE)
|
< MAX_INTERACTION_DISTANCE*PXSIZE)
|
||||||
&& strcmp( game->map_level->extradata[i].type, "NPC") !=0 )
|
&& strcmp(game->map_level->extradata[i].type, "NPC") != 0){
|
||||||
{
|
|
||||||
/* the player can do something */
|
/* the player can do something */
|
||||||
game->player.canDoSomething = true;
|
game->player.canDoSomething = true;
|
||||||
/* we mark the action for futur treatment in player_action() */
|
/* we mark the action for futur treatment in player_action() */
|
||||||
|
@ -49,8 +47,7 @@ void game_logic(Game *game) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( uint32_t i=0; i<nbNPC; i++ )
|
for(uint32_t i=0; i<nbNPC; i++){
|
||||||
{
|
|
||||||
/* simple distance check along X and Y axis */
|
/* simple distance check along X and Y axis */
|
||||||
/* Be careful to use world coordinates, not local (i.e.map) ones */
|
/* Be careful to use world coordinates, not local (i.e.map) ones */
|
||||||
if ((abs((int) game->player.wx -
|
if ((abs((int) game->player.wx -
|
||||||
|
@ -59,8 +56,7 @@ void game_logic(Game *game) {
|
||||||
&& (abs((int) game->player.wy -
|
&& (abs((int) game->player.wy -
|
||||||
(int) npcRPG[i].cury*PXSIZE )
|
(int) npcRPG[i].cury*PXSIZE )
|
||||||
< MAX_INTERACTION_DISTANCE*PXSIZE)
|
< MAX_INTERACTION_DISTANCE*PXSIZE)
|
||||||
&& strcmp( game->map_level->extradata[i].type, "NPC") !=0 )
|
&& strcmp( game->map_level->extradata[i].type, "NPC") !=0){
|
||||||
{
|
|
||||||
/* the player can do something */
|
/* the player can do something */
|
||||||
game->player.canDoSomething = true;
|
game->player.canDoSomething = true;
|
||||||
/* we mark the action for futur treatment in player_action() */
|
/* we mark the action for futur treatment in player_action() */
|
||||||
|
@ -80,34 +76,30 @@ void game_logic(Game *game) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void render_indicator(Game *game) {
|
void game_render_indicator(Game *game) {
|
||||||
/* nothing to do for the player so we quit */
|
/* nothing to do for the player so we quit */
|
||||||
if (game->player.canDoSomething==false)
|
if(game->player.canDoSomething==false) return;
|
||||||
return;
|
|
||||||
|
|
||||||
/* else we draw a small indicator on the screen */
|
/* else we draw a small indicator on the screen */
|
||||||
dimage(5, 5, &SignAction_img);
|
dimage(5, 5, &SignAction_img);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void draw(Game *game) {
|
void game_draw(Game *game) {
|
||||||
/* Draw everything. */
|
/* Draw everything. */
|
||||||
render_map_by_layer(game, BACKGROUND);
|
map_render_by_layer(game, BACKGROUND);
|
||||||
npc_draw(game);
|
npc_draw(game);
|
||||||
player_draw(game);
|
player_draw(game);
|
||||||
render_map_by_layer(game, FOREGROUND);
|
map_render_by_layer(game, FOREGROUND);
|
||||||
render_indicator( game );
|
game_render_indicator(game);
|
||||||
dprint(8, 8, C_BLACK, "Lifes: %d", game->player.life);
|
dprint(8, 8, C_BLACK, "Lifes: %d", game->player.life);
|
||||||
dprint(8, 16, C_BLACK, "Mana: %d", game->mana);
|
dprint(8, 16, C_BLACK, "Mana: %d", game->mana);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Key management */
|
/* Key management */
|
||||||
|
|
||||||
void get_inputs(Game *game) {
|
void game_get_inputs(Game *game) {
|
||||||
key_event_t ev;
|
clearevents();
|
||||||
while((ev = pollevent()).type != KEYEV_NONE){
|
|
||||||
/**/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Key binding for the Player action */
|
/* Key binding for the Player action */
|
||||||
|
|
||||||
|
@ -144,4 +136,3 @@ void get_inputs(Game *game) {
|
||||||
|
|
||||||
#endif //USB_FEATURE
|
#endif //USB_FEATURE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
src/game.h
12
src/game.h
|
@ -155,27 +155,27 @@ typedef struct {
|
||||||
/* (Mibi88) TODO: Describe what this function is doing. */
|
/* (Mibi88) TODO: Describe what this function is doing. */
|
||||||
void game_logic(Game *game);
|
void game_logic(Game *game);
|
||||||
|
|
||||||
/* draw()
|
/* game_draw()
|
||||||
*
|
*
|
||||||
* Draws everything on screen.
|
* Draws everything on screen.
|
||||||
* game: The game struct.
|
* game: The game struct.
|
||||||
*/
|
*/
|
||||||
void draw(Game *game);
|
void game_draw(Game *game);
|
||||||
|
|
||||||
/* render_indicator()
|
/* game_render_indicator()
|
||||||
*
|
*
|
||||||
* This render a small sign on the upper left corner of the screen
|
* This render a small sign on the upper left corner of the screen
|
||||||
* if the player can do an action
|
* if the player can do an action
|
||||||
* game: The game struct.
|
* game: The game struct.
|
||||||
*/
|
*/
|
||||||
void render_indicator(Game *game);
|
void game_render_indicator(Game *game);
|
||||||
|
|
||||||
/* get_inputs()
|
/* game_get_inputs()
|
||||||
*
|
*
|
||||||
* Handle key presses.
|
* Handle key presses.
|
||||||
* game: The game struct.
|
* game: The game struct.
|
||||||
*/
|
*/
|
||||||
void get_inputs(Game *game);
|
void game_get_inputs(Game *game);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ int main(void) {
|
||||||
dclear(C_WHITE);
|
dclear(C_WHITE);
|
||||||
|
|
||||||
/* render the map */
|
/* render the map */
|
||||||
draw(&game);
|
game_draw(&game);
|
||||||
|
|
||||||
#if DEBUGMODE && GINT_RENDER_RGB
|
#if DEBUGMODE && GINT_RENDER_RGB
|
||||||
if (game.debug_map)
|
if (game.debug_map)
|
||||||
|
@ -178,7 +178,7 @@ int main(void) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Management of the inputs */
|
/* Management of the inputs */
|
||||||
get_inputs(&game);
|
game_get_inputs(&game);
|
||||||
/* Run the game at max. 50fps */
|
/* Run the game at max. 50fps */
|
||||||
while(game.frame_duration < 20) sleep();
|
while(game.frame_duration < 20) sleep();
|
||||||
/* Reset frame_duration for the next frame */
|
/* Reset frame_duration for the next frame */
|
||||||
|
|
10
src/map.c
10
src/map.c
|
@ -8,7 +8,7 @@ extern Map *worldRPG[];
|
||||||
//extern ExtraData *extraRPG[];
|
//extern ExtraData *extraRPG[];
|
||||||
|
|
||||||
|
|
||||||
void render_map(Game *game) {
|
void map_render(Game *game) {
|
||||||
|
|
||||||
Map *map_level = game->map_level;
|
Map *map_level = game->map_level;
|
||||||
Player *player = &game->player;
|
Player *player = &game->player;
|
||||||
|
@ -104,7 +104,7 @@ void render_map(Game *game) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_map_by_layer(Game *game, int layer) {
|
void map_render_by_layer(Game *game, int layer) {
|
||||||
|
|
||||||
Map *map_level = game->map_level;
|
Map *map_level = game->map_level;
|
||||||
Player *player = &game->player;
|
Player *player = &game->player;
|
||||||
|
@ -194,7 +194,7 @@ void render_map_by_layer(Game *game, int layer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
short int get_tile(Game *game, int x, int y, int l) {
|
short int map_get_tile(Game *game, int x, int y, int l) {
|
||||||
|
|
||||||
Map *map_level = game->map_level;
|
Map *map_level = game->map_level;
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ short int get_tile(Game *game, int x, int y, int l) {
|
||||||
map_level->layers[l][y * map_level->w + x] : MAP_OUTSIDE;
|
map_level->layers[l][y * map_level->w + x] : MAP_OUTSIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
short int get_walkable(Game *game, int x, int y) {
|
short int map_get_walkable(Game *game, int x, int y) {
|
||||||
|
|
||||||
Map *map_level = game->map_level;
|
Map *map_level = game->map_level;
|
||||||
/* Get the tile at (x, y). Returns the tile ID or MAP_OUTSIDE if she's not
|
/* Get the tile at (x, y). Returns the tile ID or MAP_OUTSIDE if she's not
|
||||||
|
@ -214,7 +214,7 @@ short int get_walkable(Game *game, int x, int y) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return the pointer to the map containing the given position */
|
/* return the pointer to the map containing the given position */
|
||||||
Map *get_map_for_coordinates( Game *game, int x, int y )
|
Map *map_get_for_coordinates( Game *game, int x, int y )
|
||||||
{
|
{
|
||||||
/* check if the current map contains the point */
|
/* check if the current map contains the point */
|
||||||
if (x>= (int)game->map_level->xmin && x< (int)game->map_level->xmax &&
|
if (x>= (int)game->map_level->xmin && x< (int)game->map_level->xmax &&
|
||||||
|
|
20
src/map.h
20
src/map.h
|
@ -19,22 +19,22 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* render_map()
|
/* map_render()
|
||||||
*
|
*
|
||||||
* Draws the map map on the entire screen to be viewed by the player player.
|
* Draws the map map on the entire screen to be viewed by the player player.
|
||||||
* game: The game struct.
|
* game: The game struct.
|
||||||
*/
|
*/
|
||||||
void render_map(Game *game);
|
void map_render(Game *game);
|
||||||
|
|
||||||
/* render_map_by_layer()
|
/* map_render_by_layer()
|
||||||
*
|
*
|
||||||
* Draws the map layer on the entire screen to be viewed by the player player.
|
* Draws the map layer on the entire screen to be viewed by the player player.
|
||||||
* game: The game struct.
|
* game: The game struct.
|
||||||
* layer: The layer to render.
|
* layer: The layer to render.
|
||||||
*/
|
*/
|
||||||
void render_map_by_layer(Game *game, int layer);
|
void map_render_by_layer(Game *game, int layer);
|
||||||
|
|
||||||
/* get_tile()
|
/* map_get_tile()
|
||||||
*
|
*
|
||||||
* Get the tile at (x, y) of the map map. If the tile is located outside of the
|
* Get the tile at (x, y) of the map map. If the tile is located outside of the
|
||||||
* screen, MAP_OUTSIDE is returned.
|
* screen, MAP_OUTSIDE is returned.
|
||||||
|
@ -43,24 +43,24 @@ void render_map_by_layer(Game *game, int layer);
|
||||||
* y: The coordinates of the tile.
|
* y: The coordinates of the tile.
|
||||||
* l: The layer of the tile.
|
* l: The layer of the tile.
|
||||||
*/
|
*/
|
||||||
short int get_tile(Game *game, int x, int y, int l);
|
short int map_get_tile(Game *game, int x, int y, int l);
|
||||||
|
|
||||||
/* get_walkable()
|
/* map_get_walkable()
|
||||||
*
|
*
|
||||||
* Returns what is in the walkable layer at (x, y).
|
* Returns what is in the walkable layer at (x, y).
|
||||||
* game: The game struct.
|
* game: The game struct.
|
||||||
* x: The coordinates of the tile.
|
* x: The coordinates of the tile.
|
||||||
* y: The coordinates of the tile.
|
* y: The coordinates of the tile.
|
||||||
*/
|
*/
|
||||||
short int get_walkable(Game *game, int x, int y);
|
short int map_get_walkable(Game *game, int x, int y);
|
||||||
|
|
||||||
/* get_map_for_coordinates()
|
/* map_get_for_coordinates()
|
||||||
*
|
*
|
||||||
* return the pointer to the map containing the given position.
|
* return the pointer to the map containing the given position.
|
||||||
* game: The game struct.
|
* game: The game struct.
|
||||||
* x: The coordinates to look at.
|
* x: The coordinates to look at.
|
||||||
* y: The coordinates to look at.
|
* y: The coordinates to look at.
|
||||||
*/
|
*/
|
||||||
Map* get_map_for_coordinates(Game *game, int x, int y );
|
Map* map_get_for_coordinates(Game *game, int x, int y );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
bool is_in(short int *array, short int array_length, short int item) {
|
bool memory_is_in(short int *array, short int array_length, short int item) {
|
||||||
short int i;
|
short int i;
|
||||||
for(i=0;i<array_length;i++){
|
for(i=0;i<array_length;i++){
|
||||||
if(array[i] == item){
|
if(array[i] == item){
|
||||||
|
|
10
src/memory.h
10
src/memory.h
|
@ -2,8 +2,14 @@
|
||||||
#define MEMORY_H
|
#define MEMORY_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
/* memory_is_in()
|
||||||
bool is_in(short int *array, short int array_length, short int item);
|
*
|
||||||
|
* returns true if item is in array.
|
||||||
|
* array: The array to search in.
|
||||||
|
* array_length: The length of the array.
|
||||||
|
* item: The item to search for.
|
||||||
|
*/
|
||||||
|
bool memory_is_in(short int *array, short int array_length, short int item);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
31
src/player.c
31
src/player.c
|
@ -91,10 +91,11 @@ extern bopti_image_t INFO_Icon_img;
|
||||||
|
|
||||||
|
|
||||||
void player_action(Game *game) {
|
void player_action(Game *game) {
|
||||||
if( game->player.isDoingAction ) return; /* alreday doing something (action IS NOT with an NPC ) */
|
/* already doing something (action IS NOT with an NPC) */
|
||||||
|
if(game->player.isDoingAction) return;
|
||||||
|
|
||||||
if( game->player.canDoSomething && !game->player.isInteractingWithNPC ) /* we can do something */
|
if(game->player.canDoSomething && !game->player.isInteractingWithNPC){
|
||||||
{
|
/* we can do something */
|
||||||
/* we indicate that the player is occupied */
|
/* we indicate that the player is occupied */
|
||||||
game->player.isDoingAction = true;
|
game->player.isDoingAction = true;
|
||||||
|
|
||||||
|
@ -116,13 +117,12 @@ void player_action(Game *game) {
|
||||||
|
|
||||||
uint32_t dialogStart = currentData->dialogID;
|
uint32_t dialogStart = currentData->dialogID;
|
||||||
|
|
||||||
initiate_dialog_sequence( game, face, dialogStart );
|
dialogs_initiate_sequence(game, face, dialogStart);
|
||||||
|
|
||||||
/* when done we release the occupied status of the player */
|
/* when done we release the occupied status of the player */
|
||||||
game->player.isDoingAction = false;
|
game->player.isDoingAction = false;
|
||||||
}
|
}else if(game->player.canDoSomething && game->player.isInteractingWithNPC){
|
||||||
else if( game->player.canDoSomething && game->player.isInteractingWithNPC ) /* we can do something (action IS with an NPC ) */
|
/* we can do something (action IS with an NPC) */
|
||||||
{
|
|
||||||
/* we indicate that the player is occupied */
|
/* we indicate that the player is occupied */
|
||||||
game->player.isDoingAction = true;
|
game->player.isDoingAction = true;
|
||||||
|
|
||||||
|
@ -133,11 +133,12 @@ void player_action(Game *game) {
|
||||||
bopti_image_t *face = &NPC_Icon_img;
|
bopti_image_t *face = &NPC_Icon_img;
|
||||||
uint32_t dialogStart = currentNPC->dialogID;
|
uint32_t dialogStart = currentNPC->dialogID;
|
||||||
|
|
||||||
/* we setr this NPC to paused to avoid changing its position while talking (the rest of the NPCs pursue their action)*/
|
/* we set this NPC to paused to avoid changing its position while
|
||||||
|
* talking (the rest of the NPCs pursue their action) */
|
||||||
currentNPC->paused = true;
|
currentNPC->paused = true;
|
||||||
|
|
||||||
|
|
||||||
initiate_dialog_sequence( game, face, dialogStart );
|
dialogs_initiate_sequence(game, face, dialogStart);
|
||||||
|
|
||||||
/* when done we release the occupied status of the player */
|
/* when done we release the occupied status of the player */
|
||||||
game->player.isDoingAction = false;
|
game->player.isDoingAction = false;
|
||||||
|
@ -174,15 +175,13 @@ bool player_collision(Game *game, Direction direction,
|
||||||
/* check where the player is expected to go on the next move */
|
/* check where the player is expected to go on the next move */
|
||||||
/* if outside the map, we check if there is a map on the other */
|
/* if outside the map, we check if there is a map on the other */
|
||||||
/* side of the current map*/
|
/* side of the current map*/
|
||||||
if (get_walkable(game, player_tile_x, player_tile_y) == MAP_OUTSIDE)
|
if (map_get_walkable(game, player_tile_x, player_tile_y) == MAP_OUTSIDE){
|
||||||
{
|
|
||||||
// we compute the expected world coordinates accordingly
|
// we compute the expected world coordinates accordingly
|
||||||
// while taking care of the scaling between fx and cg models (PXSIZE)
|
// while taking care of the scaling between fx and cg models (PXSIZE)
|
||||||
int worldX = (player->wx+dx) / PXSIZE;
|
int worldX = (player->wx+dx) / PXSIZE;
|
||||||
int worldY = (player->wy+dy) / PXSIZE;
|
int worldY = (player->wy+dy) / PXSIZE;
|
||||||
Map *map = get_map_for_coordinates(game, worldX, worldY );
|
Map *map = map_get_for_coordinates(game, worldX, worldY);
|
||||||
if (map!=NULL && map!=game->map_level)
|
if (map!=NULL && map!=game->map_level){
|
||||||
{
|
|
||||||
Map *backupmap = game->map_level;
|
Map *backupmap = game->map_level;
|
||||||
int backupx = player->x;
|
int backupx = player->x;
|
||||||
int backupy = player->y;
|
int backupy = player->y;
|
||||||
|
@ -197,7 +196,7 @@ bool player_collision(Game *game, Direction direction,
|
||||||
player->x = (worldX - map->xmin ) * PXSIZE;
|
player->x = (worldX - map->xmin ) * PXSIZE;
|
||||||
player->y = (worldY - map->ymin ) * PXSIZE;
|
player->y = (worldY - map->ymin ) * PXSIZE;
|
||||||
|
|
||||||
int on_walkable = get_walkable(game, player->x/T_WIDTH,
|
int on_walkable = map_get_walkable(game, player->x/T_WIDTH,
|
||||||
player->y/T_HEIGHT);
|
player->y/T_HEIGHT);
|
||||||
|
|
||||||
int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ?
|
int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ?
|
||||||
|
@ -231,7 +230,7 @@ bool player_collision(Game *game, Direction direction,
|
||||||
if(player_tile_y < 0) player_tile_y = player_tile_y/T_HEIGHT-1;
|
if(player_tile_y < 0) player_tile_y = player_tile_y/T_HEIGHT-1;
|
||||||
else player_tile_y = player_tile_y/T_HEIGHT;
|
else player_tile_y = player_tile_y/T_HEIGHT;
|
||||||
|
|
||||||
int on_walkable = get_walkable(game, player_tile_x, player_tile_y);
|
int on_walkable = map_get_walkable(game, player_tile_x, player_tile_y);
|
||||||
|
|
||||||
int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ?
|
int speed = (on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX) ?
|
||||||
walkable_speed[on_walkable] : 0;
|
walkable_speed[on_walkable] : 0;
|
||||||
|
|
42
src/player.h
42
src/player.h
|
@ -12,27 +12,53 @@
|
||||||
/* only methods propotypes are now in dedicated header files */
|
/* only methods propotypes are now in dedicated header files */
|
||||||
|
|
||||||
|
|
||||||
/* Draws the player player. This function should be called after drawing the
|
/* player_draw()
|
||||||
* map! */
|
*
|
||||||
|
* Draws the player. This function should be called after drawing the
|
||||||
|
* map!
|
||||||
|
* game: The game struct which contains the player struct used.
|
||||||
|
*/
|
||||||
void player_draw(Game *game);
|
void player_draw(Game *game);
|
||||||
|
|
||||||
/* Move the player player in the direction direction. */
|
/* player_move()
|
||||||
|
*
|
||||||
|
* Move the player in a direction.
|
||||||
|
* game: The game struct.
|
||||||
|
* direction: The direction to move the player in.
|
||||||
|
*/
|
||||||
void player_move(Game *game, Direction direction);
|
void player_move(Game *game, Direction direction);
|
||||||
|
|
||||||
/* (Mibi88) TODO: Describe this function please, I've no idea what she's for! */
|
/* (Mibi88) TODO: Describe this function please, I've no idea what she's for! */
|
||||||
void player_action(Game *game);
|
void player_action(Game *game);
|
||||||
|
|
||||||
/* Check if the player is in collision with the map or a NPC. Checkpos is used
|
/* player_collision()
|
||||||
* to check the axis where the player is not moving. */
|
*
|
||||||
|
* Check if the player is in collision with the map or a NPC. Checkpos is used
|
||||||
|
* to check the axis where the player is not moving.
|
||||||
|
* game: The game struct.
|
||||||
|
* direction: The direction the player is moving in.
|
||||||
|
* nomov_axis_check: The axis that isn't changed by this movement.
|
||||||
|
*/
|
||||||
bool player_collision(Game *game, Direction direction,
|
bool player_collision(Game *game, Direction direction,
|
||||||
Checkpos nomov_axis_check);
|
Checkpos nomov_axis_check);
|
||||||
|
|
||||||
/* Fix the position of the player so that he's not a bit inside of a hard block
|
/* player_fix_position()
|
||||||
* after a collision. */
|
*
|
||||||
|
* Fix the position of the player so that he's not a bit inside of a hard block
|
||||||
|
* after a collision.
|
||||||
|
* game: The game struct.
|
||||||
|
* fix_x: If we should fix the position on the X axis.
|
||||||
|
* fix_y: If we should fix the position on the Y axis.
|
||||||
|
*/
|
||||||
void player_fix_position(Game *game, bool fix_x, bool fix_y);
|
void player_fix_position(Game *game, bool fix_x, bool fix_y);
|
||||||
|
|
||||||
|
|
||||||
/* Apply damage to player */
|
/* player_damage()
|
||||||
|
*
|
||||||
|
* Apply damage to player
|
||||||
|
* game: The game struct.
|
||||||
|
* amount: The amount of damage to apply.
|
||||||
|
*/
|
||||||
void player_damage(Game *game, int amount);
|
void player_damage(Game *game, int amount);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue