Collisions are now entirely working, started implementing dialogs (I know currently it is only an animation and a little message that it is not implemented).

This commit is contained in:
mibi88 2023-07-09 22:02:59 +02:00
parent a7d6e8f2d7
commit 474aa17573
13 changed files with 139 additions and 60 deletions

View file

@ -39,6 +39,7 @@ set(SOURCES
src/player.c
src/memory.c
src/game.c
src/dialogs.c
# ...
)
# Shared assets, fx-9860G-only assets and fx-CG-50-only assets
@ -49,6 +50,7 @@ set(ASSETS
set(ASSETS_cg
assets-cg/demo_player.png
assets-cg/player_face.png
)
set(ASSETS_cg_2b
@ -61,6 +63,7 @@ set(ASSETS_cg_EGA64
set(ASSETS_fx
assets-fx/demo_player.png
assets-fx/player_face.png
# ...
)

View file

@ -1,3 +1,7 @@
demo_player.png:
type: bopti-image
name: demo_player_img
player_face.png:
type: bopti-image
name: player_face_img

BIN
assets-cg/player_face.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

View file

@ -1,3 +1,7 @@
demo_player.png:
type: bopti-image
name: demo_player_img
player_face.png:
type: bopti-image
name: player_face_img

BIN
assets-fx/player_face.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

43
src/dialogs.c Normal file
View file

@ -0,0 +1,43 @@
#include "dialogs.h"
#include <gint/keyboard.h>
#include <gint/cpu.h>
#define BOX_HEIGHT (F_HEIGHT/PXSIZE+8)
void showtext(Game *game, bopti_image_t *face, char *text) {
unsigned int i;
for(i=0;i<BOX_HEIGHT;i++){
draw(game);
drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE);
drect(0, i*PXSIZE, DWIDTH, (i+1)*PXSIZE, C_BLACK);
dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (i-8)*PXSIZE,
DIMAGE_NONE);
dupdate();
while(game->frame_duration < 20) sleep();
game->frame_duration = 0;
}
/* We should start to drawint the text on the x axis at BOX_HEIGHT to avoid
* drawing on the face. */
/* Show a little message that showing text in dialogs is not implemented
* yet. */
dtext(BOX_HEIGHT*PXSIZE, 1, C_BLACK, "Dialogs not implemented");
dtext(BOX_HEIGHT*PXSIZE, 8, C_BLACK, "Press any key");
dupdate();
getkey();
for(i=0;i<strlen(text);i++){
/**/
}
for(i=40;i>0;i--){
draw(game);
drect(0, 0, DWIDTH, i*PXSIZE, C_WHITE);
drect(0, i*PXSIZE, DWIDTH, (i+1)*PXSIZE, C_BLACK);
dsubimage(4*PXSIZE, 2*PXSIZE, face, 0, 0, F_WIDTH, (i-8)*PXSIZE,
DIMAGE_NONE);
dupdate();
while(game->frame_duration < 20) sleep();
game->frame_duration = 0;
}
}

14
src/dialogs.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef DIALOG_H
#define DIALOG_H
#include <gint/display.h>
#include <string.h>
#include "game.h"
#include "map.h"
#define F_WIDTH (32*PXSIZE)
#define F_HEIGHT (32*PXSIZE)
void showtext(Game *game, bopti_image_t *face, char *text);
#endif

View file

@ -26,10 +26,14 @@
#include "game.h"
#include "mapdata.h"
#include "dialogs.h"
extern bopti_image_t player_face_img;
/* Game data (defined in "game.h")*/
Game game = {
&map_level0,
{10, 5, 0, 0, 100},
{10, 48, 0, 0, 100, SPEED},
false, false, false, 0
};
@ -97,7 +101,7 @@ int main(void) {
dgray(DGRAY_ON);
#endif
showtext(&game, &player_face_img, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. Ut velit mauris, egestas sed, gravida nec, ornare ut, mi. Aenean ut orci vel massa suscipit pulvinar. Nulla sollicitudin. Fusce varius, ligula non tempus aliquam, nunc turpis ullamcorper nibh, in tempus sapien eros vitae ligula. Pellentesque rhoncus nunc et augue. Integer id felis. Curabitur aliquet pellentesque diam. Integer quis metus vitae elit lobortis egestas. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi vel erat non mauris convallis vehicula. Nulla et sapien. Integer tortor tellus, aliquam faucibus, convallis id, congue eu, quam. Mauris ullamcorper felis vitae erat. Proin feugiat, augue non elementum posuere, metus purus iaculis lectus, et tristique ligula justo vitae magna. Aliquam convallis sollicitudin purus. Praesent aliquam, enim at fermentum mollis, ligula massa adipiscing nisl, ac euismod nibh nisl eu lectus. Fusce vulputate sem at sapien. Vivamus leo. Aliquam euismod libero eu enim. Nulla nec felis sed leo placerat imperdiet. Aenean suscipit nulla in justo. Suspendisse cursus rutrum augue. Nulla tincidunt tincidunt mi. Curabitur iaculis, lorem vel rhoncus faucibus, felis magna fermentum augue, et ultricies lacus lorem varius purus. Curabitur eu amet.");
do{
/* clear screen */
dclear(C_WHITE);

View file

@ -71,9 +71,10 @@ void render_map(Player *player, Map *map_level) {
* I draw it. */
if(tx+x>=0 && tx+x < map_level->w &&
ty+y>=0 && ty+y < map_level->h){
// index of the current tile
/* index of the current tile */
int currentIndex = (y+ty) * map_level->w + tx+x;
//we get the ID of the tile in the current drawable layers
/* we get the ID of the tile in the current drawable layers
*/
tile = map_level->layers[l][currentIndex];
/* tile == -1 means nothing to be drawn */
@ -90,30 +91,6 @@ void render_map(Player *player, Map *map_level) {
}
}
}
// This is for debut only
// I let this portion of code to indicate how the walkable layer can be use to know if tile is accessible and/or if specific behaviour is expected
// juste uncomment to activate
/*
for(y=0;y<dh;y++){
for(x=0;x<dw;x++){
// I get the tile number if his position is inside the map. Then
// * I draw it.
if(tx+x>=0 && tx+x < map_level->w &&
ty+y>=0 && ty+y < map_level->h){
// index of the current tile
int currentIndex = (y+ty) * map_level->w + tx+x;
int walkable = map_level->walkable[currentIndex];
// for DEBUG ONLY, we print the ID of the current tile
if (walkable!=0) dprint(x*T_WIDTH-mx + 4, y*T_HEIGHT-my+4, C_RED, "%d", walkable );
}
}
}
*/
}
short int get_tile(Map *map_level, int x, int y, int l) {
@ -123,3 +100,10 @@ short int get_tile(Map *map_level, int x, int y, int l) {
map_level->layers[l][y * map_level->w + x] : MAP_OUTSIDE;
}
short int get_walkable(Map *map_level, int x, int y) {
/* Get the tile at (x, y). Returns the tile ID or MAP_OUTSIDE if she's not
* found. */
return x>=0 && x < map_level->w && y>=0 && y < map_level->h ?
map_level->walkable[y * map_level->w + x] : MAP_OUTSIDE;
}

View file

@ -10,6 +10,12 @@
#define T_WIDTH 8
#endif
#ifdef FXCG50
#define PXSIZE 2
#else
#define PXSIZE 1
#endif
#define MAP_OUTSIDE -2 /* Returned by get_tile_at_pos if the point is outside of
* the map. */
@ -23,5 +29,8 @@ void render_map(Player *player, Map *map_level);
* screen, MAP_OUTSIDE is returned. */
short int get_tile(Map *map_level, int x, int y, int l);
/* Returns what is in the walkable layer at (x, y). */
short int get_walkable(Map *map_level, int x, int y);
#endif

View file

@ -6,7 +6,8 @@
typedef struct {
/* the ID of the tile, as per tiled configuration, first is ID=0, then line by line, each line left to right, +1 at each tile.*/
/* the ID of the tile, as per tiled configuration, first is ID=0, then line
* by line, each line left to right, +1 at each tile.*/
int tileID;
/* maximum speed on that tile for the player */
/* Note : Speed = 0 means that the tile is not walkable */

View file

@ -2,22 +2,6 @@
#include "map.h"
#include <gint/display.h>
#ifdef FXCG50
#define P_WIDTH 16
#define P_HEIGHT 16
#else
#define P_WIDTH 8
#define P_HEIGHT 8
#endif
/* SPEED should NOT be 8 or bigger: it this may cause bugs when handling
* collisions! */
#ifdef FXCG50
#define SPEED 2
#else
#define SPEED 1
#endif
const char one_px_mov[8] = {
0, -1, /* Up */
0, 1, /* Down */
@ -27,10 +11,16 @@ const char one_px_mov[8] = {
/* TODO: Search for all hard tiles in the tileset. hard_tiles is a list of their
* IDs */
/* The tiles where the player can't go trough. */
#define HARD_TILES_AMOUNT 5
const short int hard_tiles[HARD_TILES_AMOUNT] = {
MAP_OUTSIDE, 124, 148, 125, 149
/* The speed of the player on the diffrent tiles in the walkable layer. */
#define WALKABLE_TILE_MAX 4
const short int walkable_speed[WALKABLE_TILE_MAX] = {
SPEED, 0, PXSIZE, PXSIZE
};
/* How much damage the player takes on the diffrent tiles in the walkable
* layer. */
const char damage_taken_walkable[WALKABLE_TILE_MAX] = {
0, 0, 5, 0
};
extern bopti_image_t demo_player_img;
@ -41,12 +31,13 @@ void player_draw(Player *player) {
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;
char dx, dy;
/* If the player will collide with a hard tile or if the will go outside of
* the map. */
if(player_collision(map_level, player, direction, P_CENTER)){
/* If the will collide with the center of the player. */
dx = one_px_mov[direction*2]*player->speed;
dy = one_px_mov[direction*2+1]*player->speed;
player_fix_position(player, dx, dy);
}else{
if(player_collision(map_level, player, direction, P_RIGHTDOWN) ||
@ -56,9 +47,13 @@ void player_move(Map *map_level, Player *player, Direction direction) {
/* I invert dx and dy to fix the axis where he is not moving on. */
/* Do not replace dx==0 with !dx or dy==0 with !dy, it won't work!
*/
dx = one_px_mov[direction*2]*player->speed;
dy = one_px_mov[direction*2+1]*player->speed;
player_fix_position(player, dx==0, dy==0);
}
/* If he won't collide with the center, so I just move him normally */
dx = one_px_mov[direction*2]*player->speed;
dy = one_px_mov[direction*2+1]*player->speed;
player->x += dx;
player->y += dy;
}
@ -70,8 +65,6 @@ void player_action(Player *player) {
bool player_collision(Map *map_level, Player *player, Direction direction,
Checkpos nomov_axis_check) {
/* What's the tile the player is going to. */
short int i;
/* Where is the tile where he will go to from his position. */
char dx = one_px_mov[direction*2];
char dy = one_px_mov[direction*2+1];
@ -90,13 +83,14 @@ bool player_collision(Map *map_level, Player *player, Direction direction,
else player_tile_x = player_tile_x/T_WIDTH;
if(player_tile_y < 0) player_tile_y = player_tile_y/T_HEIGHT-1;
else player_tile_y = player_tile_y/T_HEIGHT;
for(i=0;i<map_level->nblayers;i++){
/* if he's on a hard tile */
if(is_in((short int*)hard_tiles, HARD_TILES_AMOUNT,
get_tile(map_level, player_tile_x, player_tile_y, i))){
return true; /* He will collide with it. */
}
int on_walkable = get_walkable(map_level, player_tile_x, player_tile_y);
int speed = on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX ?
walkable_speed[on_walkable] : 0;
/* if he's on a hard tile */
if(!speed){
return true; /* He will collide with it. */
}
player->speed = speed;
return false; /* He won't collide with a hard tile. */
}
@ -107,3 +101,8 @@ void player_fix_position(Player *player, bool fix_x, bool fix_y) {
if(fix_y) player->y = player->y/T_HEIGHT*T_HEIGHT+P_HEIGHT/2;
}
void player_damage(Player *player, int amount) {
player->life-=amount;
/* TODO: Let the player dye if life < 1. */
};

View file

@ -1,6 +1,19 @@
#ifndef PLAYER_H
#define PLAYER_H
/* The size of the player. */
#ifdef FXCG50
#define P_WIDTH 16
#define P_HEIGHT 16
#else
#define P_WIDTH 8
#define P_HEIGHT 8
#endif
/* SPEED should NOT be 8 or bigger: it this may cause bugs when handling
* collisions! */
#define SPEED PXSIZE*2
#include <stdbool.h>
#include "mapstruct.h"
@ -26,6 +39,7 @@ typedef struct {
unsigned char px, py; /* The position of the player on screen */
unsigned short int life; /* How many lives the player still has between 0
* and 100. */
char speed; /* The speed of the movement of the player. */
} Player;
/* Draws the player player. This function should be called after drawing the