Some rewrites and lots of nice gui labels

This commit is contained in:
Linus Probert 2018-01-31 20:59:55 +01:00
parent a0b86eb06d
commit 6c1591a92d
5 changed files with 152 additions and 66 deletions

153
src/gui.c
View File

@ -6,6 +6,7 @@
#include "gui.h" #include "gui.h"
#include "util.h" #include "util.h"
#include "map.h"
#define DEFAULT_LOG { NULL, 50, 0, 200 } #define DEFAULT_LOG { NULL, 50, 0, 200 }
#define POS_Y_XPBAR 96 #define POS_Y_XPBAR 96
@ -53,11 +54,31 @@ gui_malloc_log(void)
log_data.log[i] = NULL; log_data.log[i] = NULL;
} }
static Sprite*
create_xp_sprite(Texture *t, SDL_Rect clip, Position pos)
{
Sprite *s = sprite_create();
sprite_set_texture(s, t, 0);
s->fixed = true;
s->clip = clip;
s->pos = pos;
return s;
}
static Sprite*
create_label_sprite(Position pos)
{
Sprite *s = sprite_create();
s->fixed = true;
s->pos = pos;
sprite_load_text_texture(s, "assets/GUI/SDS_8x8.ttf", 0, LABEL_FONT_SIZE);
return s;
}
static void static void
init_sprites(Gui *gui, SDL_Renderer *renderer) init_sprites(Gui *gui, SDL_Renderer *renderer)
{ {
Texture *t; Texture *t;
Sprite *s;
unsigned int i; unsigned int i;
t = add_texture(gui, "assets/GUI/GUI0.png", renderer); t = add_texture(gui, "assets/GUI/GUI0.png", renderer);
@ -67,37 +88,33 @@ init_sprites(Gui *gui, SDL_Renderer *renderer)
*/ */
// Left end // Left end
s = sprite_create(); linkedlist_append(&gui->sprites, create_xp_sprite(
sprite_set_texture(s, t, 0); t,
s->fixed = true; (SDL_Rect) { 6 * 16, 0, 16, 16 },
s->clip = (SDL_Rect) { 6 * 16, 0, 16, 16 }; (Position) { 16, POS_Y_XPBAR }
s->pos = (Position) { 16 , POS_Y_XPBAR }; ));
linkedlist_append(&gui->sprites, s);
// Right end // Right end
s = sprite_create(); linkedlist_append(&gui->sprites, create_xp_sprite(
sprite_set_texture(s, t, 0); t,
s->fixed = true; (SDL_Rect) { 8 * 16, 0, 16, 16 },
s->clip = (SDL_Rect) { 8 * 16, 0, 16, 16 }; (Position) { 16 + (16 * 7), POS_Y_XPBAR }
s->pos = (Position) { 16 + (16 * 7), POS_Y_XPBAR }; ));
linkedlist_append(&gui->sprites, s);
for (i = 1; i < 7; ++i) { for (i = 1; i < 7; ++i) {
s = sprite_create(); linkedlist_append(&gui->sprites, create_xp_sprite(
sprite_set_texture(s, t, 0); t,
s->fixed = true; (SDL_Rect) { 7 * 16, 0, 16, 16 },
s->clip = (SDL_Rect) { 7 * 16, 0, 16, 16 }; (Position) { 16 + (i * 16), POS_Y_XPBAR }
s->pos = (Position) { 16 + (i * 16), POS_Y_XPBAR }; ));
linkedlist_append(&gui->sprites, s);
} }
for (i = 0; i < 8; ++i) { for (i = 0; i < 8; ++i) {
s = sprite_create(); linkedlist_append(&gui->xp_bar, create_xp_sprite(
sprite_set_texture(s, t, 0); t,
s->fixed = true; (SDL_Rect) { 6 * 16, 4 * 16, 16, 16 },
s->clip = (SDL_Rect) { 6 * 16, 4 * 16, 16, 16 }; (Position) { 16 + (i * 16), POS_Y_XPBAR }
s->pos = (Position) { 16 + (i * 16), POS_Y_XPBAR }; ));
linkedlist_append(&gui->xp_bar, s);
} }
} }
@ -119,6 +136,11 @@ gui_create(SDL_Renderer *renderer)
gui->log_lines[i] = t; gui->log_lines[i] = t;
} }
gui->labels[CURRENT_XP_LABEL] = create_label_sprite((Position) { 16, 116 });
gui->labels[LEVEL_LABEL] = create_label_sprite((Position) { 16, 128 });
gui->labels[DUNGEON_LEVEL_LABEL] = create_label_sprite((Position) { 16, 156 });
gui->labels[GOLD_LABEL] = create_label_sprite((Position) { 16, 142 });
gui_malloc_log(); gui_malloc_log();
init_sprites(gui, renderer); init_sprites(gui, renderer);
@ -180,47 +202,80 @@ gui_set_current_health(Gui *gui, int current)
} }
void void
gui_set_current_xp(Gui *gui, ExperienceData data) gui_update_player_stats(Gui *gui, Player *player, Map *map, SDL_Renderer *renderer)
{ {
// TODO(Linus): Perhaps split this up a bit?
// some static functions maybe?
static unsigned int last_level = 0; static unsigned int last_level = 0;
static int last_xp = -1;
static double last_gold = -1;
static unsigned int dungeon_level = 0;
static SDL_Color color = { 255, 255, 255, 255 };
unsigned int xp_from_levelup, xp_required_from_last_level; unsigned int xp_from_levelup, xp_required_from_last_level;
float xp_step, xp_current_step; float xp_step, xp_current_step;
unsigned int full_xp_blocks, partial_xp_block; unsigned int full_xp_blocks, partial_xp_block;
LinkedList *xp_bars; LinkedList *xp_bars;
unsigned int i; unsigned int i;
char buffer[200];
xp_from_levelup = data.current - data.previousLevel; ExperienceData data = player_get_xp_data(player);
xp_required_from_last_level = data.nextLevel - data.previousLevel;
xp_step = ((float) xp_required_from_last_level) / 32; // 4 * 8
xp_current_step = xp_from_levelup / xp_step;
partial_xp_block = ((unsigned int) xp_current_step) % 4; if (last_xp != data.current) {
full_xp_blocks = (unsigned int)((xp_current_step - partial_xp_block) / 4); xp_from_levelup = data.current - data.previousLevel;
xp_required_from_last_level = data.nextLevel - data.previousLevel;
xp_step = ((float)xp_required_from_last_level) / 32; // 4 * 8
xp_current_step = xp_from_levelup / xp_step;
xp_bars = gui->xp_bar; partial_xp_block = ((unsigned int)xp_current_step) % 4;
i = 0; full_xp_blocks = (unsigned int)((xp_current_step - partial_xp_block) / 4);
while (xp_bars != NULL) {
Sprite *s = xp_bars->data;
s->hidden = false;
xp_bars = xp_bars->next;
if (i < full_xp_blocks) { xp_bars = gui->xp_bar;
s->clip.x = 6 * 16; i = 0;
} else if (i == full_xp_blocks && partial_xp_block != 0) { while (xp_bars != NULL) {
s->clip.x = (6 * 16) + (16 * (4 - partial_xp_block)); Sprite *s = xp_bars->data;
} else { s->hidden = false;
s->hidden = true; xp_bars = xp_bars->next;
if (i < full_xp_blocks) {
s->clip.x = 6 * 16;
}
else if (i == full_xp_blocks && partial_xp_block != 0) {
s->clip.x = (6 * 16) + (16 * (4 - partial_xp_block));
}
else {
s->hidden = true;
}
++i;
} }
}
++i; if (dungeon_level != map->level) {
m_sprintf(buffer, 200, "Dungeon level: %d", map->level);
texture_load_from_text(gui->labels[DUNGEON_LEVEL_LABEL]->textures[0], buffer, color, renderer);
dungeon_level = (unsigned int) map->level;
}
if (last_gold != player->gold) {
m_sprintf(buffer, 200, "Gold: %.2f", player->gold);
texture_load_from_text(gui->labels[GOLD_LABEL]->textures[0], buffer, color, renderer);
last_gold = player->gold;
}
if (last_xp != data.current) {
m_sprintf(buffer, 200, "XP: %u / %u", data.current, data.nextLevel);
texture_load_from_text(gui->labels[CURRENT_XP_LABEL]->textures[0], buffer, color, renderer);
last_xp = data.current;
} }
if (last_level != data.level) { if (last_level != data.level) {
// TODO(Linus): Update the indicators m_sprintf(buffer, 200, "Level: %u", data.level);
texture_load_from_text(gui->labels[LEVEL_LABEL]->textures[0], buffer, color, renderer);
last_level = data.level; last_level = data.level;
} }
} }
static void static void
@ -282,6 +337,8 @@ gui_render_panel(Gui *gui, unsigned int width, unsigned int height, Camera *cam)
item = item->next; item = item->next;
} }
for (int i = 0; i < LABEL_COUNT; ++i)
sprite_render(gui->labels[i], cam);
} }
void void

View File

@ -3,6 +3,7 @@
#define LOG_LINES_COUNT 15 #define LOG_LINES_COUNT 15
#define LOG_FONT_SIZE 8 #define LOG_FONT_SIZE 8
#define LABEL_FONT_SIZE 8
#include "linkedlist.h" #include "linkedlist.h"
#include "hashtable.h" #include "hashtable.h"
@ -10,11 +11,20 @@
#include "camera.h" #include "camera.h"
#include "player.h" #include "player.h"
typedef enum Label_e {
LEVEL_LABEL,
CURRENT_XP_LABEL,
GOLD_LABEL,
DUNGEON_LEVEL_LABEL,
LABEL_COUNT
} LabelIndex;
typedef struct { typedef struct {
LinkedList *sprites; LinkedList *sprites;
LinkedList *health; LinkedList *health;
LinkedList *xp_bar; LinkedList *xp_bar;
Hashtable *textures; Hashtable *textures;
Sprite *labels[LABEL_COUNT];
Texture *log_lines[LOG_LINES_COUNT]; Texture *log_lines[LOG_LINES_COUNT];
} Gui; } Gui;
@ -28,10 +38,7 @@ void
gui_set_current_health(Gui*, int current); gui_set_current_health(Gui*, int current);
void void
gui_set_current_xp(Gui*, ExperienceData); gui_update_player_stats(Gui*, Player*, Map*, SDL_Renderer*);
void
gui_set_xp_data(Gui*, ExperienceData);
void void
gui_render_panel(Gui*, unsigned int width, unsigned int height, Camera*); gui_render_panel(Gui*, unsigned int width, unsigned int height, Camera*);

View File

@ -203,7 +203,6 @@ run_game(void)
{ {
static unsigned int player_max_hp = 0; static unsigned int player_max_hp = 0;
static unsigned int player_current_hp = 0; static unsigned int player_current_hp = 0;
static unsigned int player_current_xp = 0;
SDL_RenderSetViewport(gRenderer, NULL); SDL_RenderSetViewport(gRenderer, NULL);
map_clear_dead_monsters(gMap); map_clear_dead_monsters(gMap);
@ -213,6 +212,7 @@ run_game(void)
&gPlayer->sprite->pos); &gPlayer->sprite->pos);
roommatrix_build_lightmap(gRoomMatrix); roommatrix_build_lightmap(gRoomMatrix);
gui_update_player_stats(gGui, gPlayer, gMap, gRenderer);
if (player_max_hp != (unsigned int) gPlayer->stats.maxhp) { if (player_max_hp != (unsigned int) gPlayer->stats.maxhp) {
gui_set_max_health(gGui, gPlayer->stats.maxhp, gRenderer); gui_set_max_health(gGui, gPlayer->stats.maxhp, gRenderer);
@ -222,11 +222,8 @@ run_game(void)
gui_set_current_health(gGui, gPlayer->stats.hp); gui_set_current_health(gGui, gPlayer->stats.hp);
player_current_hp = gPlayer->stats.hp; player_current_hp = gPlayer->stats.hp;
} }
if (player_current_xp != gPlayer->xp) {
gui_set_current_xp(gGui, player_get_xp_data(gPlayer)); if (gPlayer->steps >= gPlayer->stats.speed) {
player_current_xp = gPlayer->xp;
}
if (gPlayer->steps == gPlayer->stats.speed) {
player_reset_steps(gPlayer); player_reset_steps(gPlayer);
roommatrix_update_with_player(gRoomMatrix, gPlayer); roommatrix_update_with_player(gRoomMatrix, gPlayer);
map_move_monsters(gMap, gRoomMatrix); map_move_monsters(gMap, gRoomMatrix);

View File

@ -2,13 +2,13 @@
#include "sprite.h" #include "sprite.h"
#include "util.h" #include "util.h"
static static Sprite*
Sprite* sprite_create_default(void) sprite_create_default(void)
{ {
Sprite *s = ec_malloc(sizeof(Sprite)); Sprite *s = ec_malloc(sizeof(Sprite));
s->textures[0] = NULL; s->textures[0] = NULL;
s->textures[1] = NULL; s->textures[1] = NULL;
s->clip = (SDL_Rect) { 0, 0, 16, 16 }; s->clip = (SDL_Rect) { 0, 0, 0, 0 };
s->destroyTextures = false; s->destroyTextures = false;
s->pos = (Position) { 0, 0 }; s->pos = (Position) { 0, 0 };
s->renderTimer = timer_create(); s->renderTimer = timer_create();
@ -19,7 +19,8 @@ Sprite* sprite_create_default(void)
return s; return s;
} }
Sprite* sprite_create() Sprite*
sprite_create()
{ {
return sprite_create_default(); return sprite_create_default();
} }
@ -43,6 +44,21 @@ sprite_load_texture(Sprite *sprite,
sprite->destroyTextures = true; sprite->destroyTextures = true;
} }
void sprite_load_text_texture(Sprite *sprite, char * path, int index, int size)
{
if (index > 1)
fatal("in sprite_load_texture() index out of bounds");
if (sprite->destroyTextures && sprite->textures[index] != NULL) {
texture_destroy(sprite->textures[index]);
sprite->textures[index] = NULL;
}
sprite->textures[index] = texture_create();
texture_load_font(sprite->textures[index], path, size);
sprite->destroyTextures = true;
}
void void
sprite_set_texture(Sprite *s, Texture *t, int index) sprite_set_texture(Sprite *s, Texture *t, int index)
{ {
@ -76,10 +92,17 @@ void sprite_render(Sprite *s, Camera *cam)
else else
cameraPos = s->pos; cameraPos = s->pos;
texture_render_clip(s->textures[s->texture_index], if (s->clip.w && s->clip.h) {
&cameraPos, texture_render_clip(s->textures[s->texture_index],
&s->clip, &cameraPos,
cam); &s->clip,
cam);
}
else {
texture_render(s->textures[s->texture_index],
&cameraPos,
cam);
}
} }
void sprite_destroy(Sprite *sprite) void sprite_destroy(Sprite *sprite)

View File

@ -24,6 +24,8 @@ Sprite* sprite_create(void);
void sprite_load_texture(Sprite *, char *path, int index, SDL_Renderer *); void sprite_load_texture(Sprite *, char *path, int index, SDL_Renderer *);
void sprite_load_text_texture(Sprite *, char *path, int index, int size);
void sprite_set_texture(Sprite *, Texture *, int index); void sprite_set_texture(Sprite *, Texture *, int index);
void sprite_render(Sprite*, Camera*); void sprite_render(Sprite*, Camera*);