exactly draw map + comment

This commit is contained in:
bgiraudr 2021-08-04 20:12:53 +02:00
parent 484d83df19
commit 44fe7278d1
7 changed files with 112 additions and 141 deletions

2
include/define.h Normal file
View File

@ -0,0 +1,2 @@
#define PLAYER_VIEW_X 12
#define PLAYER_VIEW_Y 7

View File

@ -8,6 +8,7 @@ struct game {
};
void engine_draw(struct game const *game);
void engine_draw_map_around_player(struct game const *game);
void engine_draw_player(struct player const *player);
void engine_move(struct game *game, int direction);
int map_walkable(struct map const *map, int x, int y);

View File

@ -6,6 +6,7 @@ struct player {
int x, y;
int direction;
int frame;
int show_x, show_y;
int idle;
struct anim_data anim;
};

View File

@ -17,8 +17,7 @@ struct sheet const anim_player = {
.frame_h = 21,
};
static struct anim_frame anim_frame(struct sheet const *sheet, int col, int row)
{
static struct anim_frame anim_frame(struct sheet const *sheet, int col, int row) {
struct anim_frame f = {
.source = sheet->img,
.left = sheet->frame_w * col,
@ -29,22 +28,17 @@ static struct anim_frame anim_frame(struct sheet const *sheet, int col, int row)
return f;
}
void dframe(int x, int y, struct anim_frame const frame)
{
void dframe(int x, int y, struct anim_frame const frame) {
dsubimage(x, y, frame.source, frame.left, frame.top, frame.w, frame.h,
DIMAGE_NONE);
}
int anim_player_idle(struct anim_data *data, int init)
{
if(init)
{
int anim_player_idle(struct anim_data *data, int init) {
if(init) {
data->function = anim_player_idle;
data->frame = 0;
data->duration = 100;
}
else
{
} else {
data->frame = (data->frame + 1) % 2;
data->duration += 100;
}

View File

@ -5,87 +5,68 @@
#include "map.h"
#include "player.h"
#include "animation.h"
#include "define.h"
#define TILESET_WIDTH 29
#define HEIGHT_VISIBLE 14
#define WIDTH_VISIBLE 24
/*void engine_draw(struct game const *game) {
dclear(C_BLACK);
for(int y = 0; y < HEIGHT_VISIBLE; y++) {
for(int x = 0; x < WIDTH_VISIBLE; x++) {
int tile = game->map->tiles[y * game->map->w + x] - 1;
if(tile != -1) {
int tile_x = tile % TILESET_WIDTH;
int tile_y = tile / TILESET_WIDTH;
//dprint(x * 55, y * 16, C_BLACK,"%d(%d:%d)",tile, tile_x, tile_y);
dsubimage(x * 16, y * 16, game->map->tileset, tile_x * 16, tile_y * 16, 16, 16, DIMAGE_NONE);
}
}
}
engine_draw_player(game->player);
}*/
void engine_draw(struct game const *game) {
dclear(C_WHITE);
int j = 0;
int x = 0;
engine_draw_map_around_player(game);
engine_draw_player(game->player);
}
int level_width = game->map->w;
int taillemap = game->map->h*game->map->w;
int player_view = 12;
int coomap = game->player->x + game->player->y*level_width;
int beginmap = coomap - player_view - level_width*player_view;
int beginline = coomap - player_view * level_width - coomap%level_width;
void engine_draw_map_around_player(struct game const *game) {
const int level_width = game->map->w;
const int taillemap = game->map->w * game->map->h;
const int posx = game->player->show_x;
const int posy = game->player->show_y;
const int coo_player_map = game->player->x + game->player->y*level_width; //the index of the player on the map
int beginmap = coo_player_map - PLAYER_VIEW_X - level_width*PLAYER_VIEW_Y; //compute the theorical top left corner
int beginline = coo_player_map - PLAYER_VIEW_Y*level_width - coo_player_map%level_width; //index of the tile wich begin the row
//anti begin oob
if(beginmap < 0) {
beginmap = game->player->x - player_view;
beginmap = game->player->x - PLAYER_VIEW_X;
if(beginmap < 0) beginmap = 0;
}
if((coomap - player_view)%level_width > coomap%level_width) {
if(beginline > 0) {
beginmap = beginline;
} else {
beginmap = 0;
}
//anti horizontal oob
if((coo_player_map - PLAYER_VIEW_X)%level_width > coo_player_map%level_width) {
beginmap = beginline > 0 ? beginline : 0;
}
int next = game->player->x + player_view + beginmap/level_width * level_width;
int endline = beginmap+level_width-beginmap%level_width-1;
int next = game->player->x + PLAYER_VIEW_X + beginmap/level_width * level_width; //index of the top right corner
int endline = beginmap+level_width-beginmap%level_width-1; //index of the tile wich end the row
if(next > endline) next = endline;
if(next < 0) next = game->player->x + PLAYER_VIEW_X;
if(next < 0) {
next = game->player->x + player_view;
}
int indypro = game->player->y + PLAYER_VIEW_Y; //y value of the bottom row
//anti bottom oob
if(indypro > taillemap/level_width-1) indypro = taillemap/level_width-1;
int indypro = game->player->y + player_view;
if(indypro > taillemap/level_width-1) {
indypro = taillemap/level_width-1;
}
int endmap = next%level_width + level_width*indypro;
int endmap = next%level_width + level_width*indypro; //index of the bottom right corner
int ecart = next - beginmap; //number of column to draw
int ecart = next - beginmap;
//player x, y on the compute map
int xcentre = 0, ycentre = 0;
for(int i = beginmap; i <= endmap; i++) {
x++;
if(i == coomap) {xcentre = x-1; ycentre = j; break;}
if(i == beginmap + ecart + j * level_width) {
j++;
x=0;
i = beginmap + j*level_width-1;
//calculate the player position in the generated map
for(int i = beginmap; i < coo_player_map; i++) {
xcentre++;
if(i == next + ycentre * level_width) {
ycentre++;
xcentre=0;
i = beginmap + ycentre*level_width-1;
}
}
j=0;
x=12-xcentre;
int j = 0;
int x = posx-xcentre;
for(int i = beginmap; i <= endmap; i++) {
int y = j + (7-ycentre);
int y = j + (posy-ycentre);
for(int layer = 0; layer < game->map->nb_layer; layer++) {
int tile;
@ -93,8 +74,6 @@ void engine_draw(struct game const *game) {
if(tile != -1) {
int tile_x = tile % TILESET_WIDTH;
int tile_y = tile / TILESET_WIDTH;
//dprint(x * 55, y * 16, C_BLACK,"%d(%d:%d)",tile, tile_x, tile_y);
dsubimage(x * 16, y * 16, game->map->tileset, tile_x * 16, tile_y * 16, 16, 16, DIMAGE_NONE);
}
}
@ -102,15 +81,14 @@ void engine_draw(struct game const *game) {
x++;
if(i==beginmap+ecart+j*level_width) {
j++;
x=12-xcentre;
x=posx-xcentre;
i = beginmap + j*level_width-1;
}
}
engine_draw_player(game->player);
}
void engine_draw_player(struct player const *player) {
dframe(12 * 16, 7 * 16 - 5, player->anim.img);
dframe(player->show_x * 16, player->show_y * 16 - 5, player->anim.img); //draw the player 5 pixel up
dprint(1,1,C_BLACK,"%d:%d",player->x, player->y);
}
@ -131,18 +109,15 @@ void engine_move(struct game *game, int direction) {
}
}
void engine_tick(struct game *game, int dt)
{
game->player->anim.duration -= dt;
void engine_tick(struct game *game, int dt) {
game->player->anim.duration -= dt;
/* Call the animation function to generate the next frame */
if(game->player->anim.duration <= 0) {
game->player->idle = !game->player->anim.function(&game->player->anim, 0);
if(game->player->anim.duration <= 0) {
game->player->idle = !game->player->anim.function(&game->player->anim, 0);
}
}
int map_walkable(struct map const *map, int x, int y)
{
int tile = map->info_map[y * map->w + x];
return (tile != TILE_SOLID);
int map_walkable(struct map const *map, int x, int y) {
int tile = map->info_map[y * map->w + x];
return (tile != TILE_SOLID);
}

View File

@ -1,61 +1,7 @@
#include <gint/display.h>
#include <gint/keyboard.h>
#include "game.h"
#include "map.h"
#include "engine.h"
#include "player.h"
#include "animation.h"
#include <gint/timer.h>
#include <gint/clock.h>
extern struct map map_1;
struct map *maps[] = {
&map_1,
};
static int callback_tick(volatile int *tick)
{
*tick = 1;
return TIMER_CONTINUE;
}
void play() {
struct player player = {
.x = 16,
.y = 7,
.direction = DIR_DOWN,
.anim.function = anim_player_idle,
.anim.dir = DIR_DOWN
};
player.idle = !anim_player_idle(&player.anim, 1);
struct game game = {
.map = maps[0],
.player = &player
};
static volatile int tick = 1;
int t = timer_configure(TIMER_ANY, ENGINE_TICK*1000,
GINT_CALL(callback_tick, &tick));
if(t >= 0) timer_start(t);
while(!keydown(KEY_7)) {
while(!tick) sleep();
tick = 0;
engine_draw(&game);
//engine_draw_player(game->player);
dupdate();
int dir = get_inputs();
if(dir >= 0)
engine_move(&game, dir);
engine_tick(&game, ENGINE_TICK);
}
if(t >= 0) timer_stop(t);
}
int get_inputs(void) {
int opt = GETKEY_DEFAULT & ~GETKEY_REP_ARROWS;

View File

@ -1,9 +1,61 @@
#include <gint/display.h>
#include <gint/keyboard.h>
#include "game.h"
#include "map.h"
#include "engine.h"
#include "player.h"
#include "animation.h"
int main(void)
{
play();
return 0;
#include <gint/timer.h>
#include <gint/clock.h>
extern struct map map_1;
struct map *maps[] = {
&map_1,
};
static int callback_tick(volatile int *tick) {
*tick = 1;
return TIMER_CONTINUE;
}
int main(void) {
struct player player = {
.x = 16,
.y = 7,
.show_x = 12,
.show_y = 7,
.direction = DIR_DOWN,
.anim.function = anim_player_idle,
.anim.dir = DIR_DOWN
};
player.idle = !anim_player_idle(&player.anim, 1);
struct game game = {
.map = maps[0],
.player = &player
};
static volatile int tick = 1;
int t = timer_configure(TIMER_ANY, ENGINE_TICK*1000,
GINT_CALL(callback_tick, &tick));
if(t >= 0) timer_start(t);
while(!keydown(KEY_7)) {
while(!tick) sleep();
tick = 0;
engine_draw(&game);
dupdate();
int dir = get_inputs();
if(dir >= 0)
engine_move(&game, dir);
engine_tick(&game, ENGINE_TICK);
}
if(t >= 0) timer_stop(t);
return 0;
}