Make map rendering centered

This commit is contained in:
2024-10-05 10:17:12 -05:00
parent 27ce6526e6
commit bdef59bbe1
8 changed files with 163 additions and 51 deletions

View File

@ -21,38 +21,11 @@ void frameInit() {
} }
void frameUpdate() { void frameUpdate() {
// Draw buffer
entity_t *ent;
tile_t tile;
uint32_t i;
map_t *map = GAME.currentMap; map_t *map = GAME.currentMap;
if(map == NULL) return; if(map == NULL) return;
// Draw the map area. // Draw the map area.
i = 0; frameMapDraw();
for(uint16_t y = 0; y < FRAME_HEIGHT - FRAME_BOTTOM_UI_HEIGHT; y++) {
for(uint16_t x = 0; x < FRAME_WIDTH; x++) {
if(x >= map->width || y >= map->height) {
FRAME_COLOR[i] = COLOR_BLACK;
FRAME_BUFFER[i++] = ' ';
continue;
}
// Entity?
ent = mapEntityGetByPosition(map, x, y);
if(ent != NULL) {
FRAME_COLOR[i] = symbolGetColorByEntity(ent);
FRAME_BUFFER[i++] = symbolGetCharByEntity(ent);
continue;
}
// Tile?
tile = mapTileGetByPosition(map, x, y, 0);
FRAME_COLOR[i] = symbolGetColorByTile(tile);
FRAME_BUFFER[i++] = symbolGetCharByTile(tile);
}
}
} }
void frameUIReset() { void frameUIReset() {
@ -90,4 +63,104 @@ void frameUIReset() {
i = y * FRAME_WIDTH + FRAME_WIDTH - 1; i = y * FRAME_WIDTH + FRAME_WIDTH - 1;
FRAME_BUFFER[i] = '|'; FRAME_BUFFER[i] = '|';
} }
}
void frameMapDraw() {
// Draw the map area.
entity_t *ent;
tile_t tile;
uint32_t i;
map_t *map = GAME.currentMap;
if(map == NULL) return;
// Try get player
entity_t *player = mapEntityGetByType(map, ENTITY_TYPE_PLAYER);
uint16_t cameraPositionX, cameraPositionY;
if(player == NULL) {
cameraPositionX = 0;
cameraPositionY = 0;
} else {
cameraPositionX = player->x;
cameraPositionY = player->y;
}
// If the size of the map's smaller than the frame, center it, otherwise use
// the cameraPosition as the center point.
int16_t offsetX = 0, offsetY = 0;
if(map->width < FRAME_MAP_WIDTH) {
offsetX = (FRAME_MAP_WIDTH - map->width) / 2;
} else {
// Clamp to map bounds
if(cameraPositionX < FRAME_MAP_WIDTH / 2) {
offsetX = 0;
} else if(cameraPositionX >= map->width - (FRAME_MAP_WIDTH / 2)) {
offsetX = -(map->width - FRAME_MAP_WIDTH);
} else {
offsetX = -(cameraPositionX - (FRAME_MAP_WIDTH / 2));
}
}
if(map->height < FRAME_MAP_HEIGHT) {
offsetY = (FRAME_MAP_HEIGHT - map->height) / 2;
} else {
// Clamp to map bounds
if(cameraPositionY < FRAME_MAP_HEIGHT / 2) {
offsetY = 0;
} else if(cameraPositionY >= map->height - (FRAME_MAP_HEIGHT / 2)) {
offsetY = -(map->height - FRAME_MAP_HEIGHT);
} else {
offsetY = -(cameraPositionY - (FRAME_MAP_HEIGHT / 2));
}
}
// Draw the map
i = 0;
for(uint16_t y = 0; y < FRAME_MAP_HEIGHT; y++) {
for(uint16_t x = 0; x < FRAME_MAP_WIDTH; x++) {
if(x < offsetX || y < offsetY || x >= map->width + offsetX || y >= map->height + offsetY) {
FRAME_COLOR[i] = COLOR_BLACK;
FRAME_BUFFER[i++] = ' ';
continue;
}
// Entity?
ent = mapEntityGetByPosition(map, x - offsetX, y - offsetY);
if(ent != NULL) {
FRAME_COLOR[i] = symbolGetColorByEntity(ent);
FRAME_BUFFER[i++] = symbolGetCharByEntity(ent);
continue;
}
// Tile?
tile = mapTileGetByPosition(map, x - offsetX, y - offsetY, 0);
FRAME_COLOR[i] = symbolGetColorByTile(tile);
FRAME_BUFFER[i++] = symbolGetCharByTile(tile);
}
}
// Old code:
// i = 0;
// for(uint16_t y = 0; y < FRAME_HEIGHT - FRAME_BOTTOM_UI_HEIGHT; y++) {
// for(uint16_t x = 0; x < FRAME_WIDTH; x++) {
// if(x >= map->width || y >= map->height) {
// FRAME_COLOR[i] = COLOR_BLACK;
// FRAME_BUFFER[i++] = ' ';
// continue;
// }
// // Entity?
// ent = mapEntityGetByPosition(map, x, y);
// if(ent != NULL) {
// FRAME_COLOR[i] = symbolGetColorByEntity(ent);
// FRAME_BUFFER[i++] = symbolGetCharByEntity(ent);
// continue;
// }
// // Tile?
// tile = mapTileGetByPosition(map, x, y, 0);
// FRAME_COLOR[i] = symbolGetColorByTile(tile);
// FRAME_BUFFER[i++] = symbolGetCharByTile(tile);
// }
// }
} }

View File

@ -16,6 +16,9 @@
#define FRAME_BOTTOM_UI_HEIGHT 8 #define FRAME_BOTTOM_UI_HEIGHT 8
#define FRAME_MAP_WIDTH FRAME_WIDTH
#define FRAME_MAP_HEIGHT (FRAME_HEIGHT - FRAME_BOTTOM_UI_HEIGHT)
extern char_t FRAME_BUFFER[FRAME_HEIGHT * FRAME_WIDTH]; extern char_t FRAME_BUFFER[FRAME_HEIGHT * FRAME_WIDTH];
extern uint8_t FRAME_COLOR[FRAME_HEIGHT * FRAME_WIDTH]; extern uint8_t FRAME_COLOR[FRAME_HEIGHT * FRAME_WIDTH];
@ -32,4 +35,9 @@ void frameUpdate();
/** /**
* Resets the UI area of the frame. * Resets the UI area of the frame.
*/ */
void frameUIReset(); void frameUIReset();
/**
* Redraws the entire map area of the frame.
*/
void frameMapDraw();

View File

@ -11,8 +11,12 @@
#define GAME_UPDATE_RESULT_CONTINUE 0 #define GAME_UPDATE_RESULT_CONTINUE 0
#define GAME_UPDATE_RESULT_EXIT 1 #define GAME_UPDATE_RESULT_EXIT 1
#define GAME_STATE_RUNNING 0
#define GAME_STATE_PAUSED 1
typedef struct { typedef struct {
map_t *currentMap; map_t *currentMap;
uint8_t state;
} game_t; } game_t;
extern game_t GAME; extern game_t GAME;

View File

@ -82,6 +82,18 @@ entity_t * mapEntityGetByPosition(
return NULL; return NULL;
} }
entity_t * mapEntityGetByType(
map_t *map,
const uint8_t type
) {
for(uint8_t i = 0; i < map->entityCount; i++) {
entity_t *entity = &map->entities[i];
if(entity->type == type) return entity;
}
return NULL;
}
tile_t mapTileGetByPosition( tile_t mapTileGetByPosition(
const map_t *map, const map_t *map,
const uint16_t x, const uint16_t x,

View File

@ -68,6 +68,18 @@ entity_t * mapEntityGetByPosition(
const uint16_t y const uint16_t y
); );
/**
* Gets the entity of the specified type.
*
* @param map Map to get the entity from.
* @param type Type of entity to get.
* @return Entity of the specified type, or NULL if no entity is found.
*/
entity_t * mapEntityGetByType(
map_t *map,
const uint8_t type
);
/** /**
* Gets the tile at the specified position. * Gets the tile at the specified position.
* *

View File

@ -9,19 +9,23 @@
#include "rpg/world/map.h" #include "rpg/world/map.h"
#include "assert/assert.h" #include "assert/assert.h"
#define TEST_MAP_WIDTH 50
#define TEST_MAP_HEIGHT 50
#define TEST_MAP_LAYERS 1
void testMapInit(map_t *map) { void testMapInit(map_t *map) {
mapInit(map, 20, 20, 1); mapInit(map, TEST_MAP_WIDTH, TEST_MAP_HEIGHT, TEST_MAP_LAYERS);
entity_t *player = mapEntityAdd(map); entity_t *player = mapEntityAdd(map);
entityInit(player, ENTITY_TYPE_PLAYER, map); entityInit(player, ENTITY_TYPE_PLAYER, map);
entityPositionSet(player, 5, 5); entityPositionSet(player, 5, 5);
entity_t *npc = mapEntityAdd(map); // entity_t *npc = mapEntityAdd(map);
entityInit(npc, ENTITY_TYPE_NPC, map); // entityInit(npc, ENTITY_TYPE_NPC, map);
entityPositionSet(npc, 10, 10); // entityPositionSet(npc, 10, 10);
tile_t tiles[42 * 42]; tile_t tiles[TEST_MAP_WIDTH * TEST_MAP_HEIGHT];
for(uint32_t i = 0; i < 42 * 42; i++) { for(uint32_t i = 0; i < TEST_MAP_WIDTH * TEST_MAP_HEIGHT; i++) {
tiles[i].id = TILE_ID_GRASS; tiles[i].id = TILE_ID_GRASS;
} }
@ -31,22 +35,22 @@ void testMapInit(map_t *map) {
tiles[14].id = TILE_ID_WATER; tiles[14].id = TILE_ID_WATER;
tiles[15].id = TILE_ID_WATER; tiles[15].id = TILE_ID_WATER;
tiles[30].id = TILE_ID_WATER; // tiles[30].id = TILE_ID_WATER;
tiles[31].id = TILE_ID_WATER; // tiles[31].id = TILE_ID_WATER;
tiles[32].id = TILE_ID_WATER; // tiles[32].id = TILE_ID_WATER;
tiles[33].id = TILE_ID_WATER; // tiles[33].id = TILE_ID_WATER;
tiles[34].id = TILE_ID_WATER; // tiles[34].id = TILE_ID_WATER;
tiles[35].id = TILE_ID_WATER; // tiles[35].id = TILE_ID_WATER;
tiles[50].id = TILE_ID_WATER; // tiles[50].id = TILE_ID_WATER;
tiles[51].id = TILE_ID_WATER; // tiles[51].id = TILE_ID_WATER;
tiles[52].id = TILE_ID_WATER; // tiles[52].id = TILE_ID_WATER;
tiles[53].id = TILE_ID_WATER; // tiles[53].id = TILE_ID_WATER;
tiles[70].id = TILE_ID_WATER; // tiles[70].id = TILE_ID_WATER;
tiles[71].id = TILE_ID_WATER; // tiles[71].id = TILE_ID_WATER;
tiles[72].id = TILE_ID_WATER; // tiles[72].id = TILE_ID_WATER;
tiles[73].id = TILE_ID_WATER; // tiles[73].id = TILE_ID_WATER;
mapTilesSet(map, tiles, 0); mapTilesSet(map, tiles, 0);

View File

@ -92,7 +92,6 @@ void textboxUpdate() {
// Update scrolling // Update scrolling
TEXTBOX.nextChar -= TIME.delta; TEXTBOX.nextChar -= TIME.delta;
if(inputIsDown(INPUT_BIND_ACCEPT)) TEXTBOX.nextChar -= TIME.delta;
if(TEXTBOX.nextChar > 0.0f) return; if(TEXTBOX.nextChar > 0.0f) return;
// Scroll text // Scroll text

View File

@ -11,7 +11,7 @@
#define TEXTBOX_TITLE_MAX 16 #define TEXTBOX_TITLE_MAX 16
#define TEXTBOX_TEXT_MAX ((FRAME_BOTTOM_UI_HEIGHT-2) * (FRAME_WIDTH - 2)) #define TEXTBOX_TEXT_MAX ((FRAME_BOTTOM_UI_HEIGHT-2) * (FRAME_WIDTH - 2))
#define TEXTBOX_CHARS_PER_SECOND 15 #define TEXTBOX_CHARS_PER_SECOND 25
#define TEXTBOX_BLINKS_PER_SECOND 2 #define TEXTBOX_BLINKS_PER_SECOND 2
typedef struct { typedef struct {