Began designing/writing gui. Added states.

This commit is contained in:
Linus Probert 2017-12-22 15:15:40 +01:00
parent 60b374f84e
commit c4b8766a01
13 changed files with 225 additions and 39 deletions

View File

@ -58,6 +58,7 @@ add_executable(breakhack
src/random src/random
src/linkedlist src/linkedlist
src/hashtable src/hashtable
src/gui
) )
target_link_libraries(breakhack target_link_libraries(breakhack

View File

@ -16,7 +16,8 @@ x Moving enemies
x Add hooks to lua x Add hooks to lua
x Add movement depending on state (aggro, scared, passive) x Add movement depending on state (aggro, scared, passive)
x Lower dungeon levels x Lower dungeon levels
- GUI (lua generated) o GUI
- Player death
- Items (lua generated?) - Items (lua generated?)
- More GUI - More GUI
o XP o XP

View File

@ -4,7 +4,8 @@
typedef enum GameState_t { typedef enum GameState_t {
MENU, MENU,
PLAYING, PLAYING,
NEXT_LEVEL IN_GAME_MENU,
GAME_OVER
} GameState; } GameState;
#endif // GAMESTATE_H_ #endif // GAMESTATE_H_

116
src/gui.c Normal file
View File

@ -0,0 +1,116 @@
#include <assert.h>
#include "gui.h"
#include "util.h"
Gui*
gui_create()
{
Gui *gui = ec_malloc(sizeof(Gui));
gui->sprites = linkedlist_create();
gui->health = linkedlist_create();
gui->textures = ht_create(5);
return gui;
}
static void
clear_sprite_list(LinkedList *list)
{
while (list != NULL)
sprite_destroy(linkedlist_pop(&list));
}
void
gui_set_max_health(Gui *gui, int max, SDL_Renderer *renderer)
{
Sprite *sprite;
Texture *texture;
int i;
assert(max % 3 == 0);
if (((unsigned int) max / 3) == (unsigned int) linkedlist_size(gui->health))
return;
clear_sprite_list(gui->health);
texture = gui_add_texture(gui, "assets/GUI/GUI0.png", renderer);
for (i = 0; i < max/3; ++i) {
sprite = sprite_create();
sprite->fixed = true;
sprite->clip = (SDL_Rect) { 0, 16, 16, 16 };
sprite->pos = (Position) { 16 + i*16, 16 };
sprite_set_texture(sprite, texture, 0);
linkedlist_append(&gui->health, sprite);
}
}
void
gui_set_current_health(Gui *gui, int current)
{
Sprite *sprite;
int partial = current % 3;
int full = (current - partial)/3;
int count = 0;
if (current < 0)
current = 0;
LinkedList *item = gui->health;
while (item != NULL) {
sprite = (Sprite*) item->data;
if (count < full) {
sprite->clip.x = 0;
} else if (count == full) {
sprite->clip.x = 64 - (partial * 16);
} else {
sprite->clip.x = 64;
}
++count;
item = item->next;
}
}
Texture*
gui_add_texture(Gui *gui, const char *path, SDL_Renderer *renderer)
{
Texture *t = ht_get(gui->textures, path);
if (t == NULL) {
t = texture_create();
texture_load_from_file(t, path, renderer);
t->dim = (Dimension) { 16, 16 };
ht_set(gui->textures, path, t);
}
return t;
}
void
gui_render(Gui *gui, Camera *cam)
{
LinkedList *item = gui->health;
while (item != NULL) {
Sprite *s = item->data;
sprite_render(s, cam);
item = item->next;
}
item = gui->sprites;
while (item != NULL) {
Sprite *s = item->data;
sprite_render(s, cam);
item = item->next;
}
}
void
gui_destroy(Gui *gui)
{
while (gui->sprites != NULL)
sprite_destroy(linkedlist_pop(&gui->sprites));
while (gui->health != NULL)
sprite_destroy(linkedlist_pop(&gui->health));
ht_destroy_custom(gui->textures, (void (*)(void*)) &texture_destroy);
free(gui);
}

27
src/gui.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef GUI_H_
#define GUI_H_
#include "linkedlist.h"
#include "hashtable.h"
#include "sprite.h"
#include "camera.h"
typedef struct {
LinkedList *sprites;
LinkedList *health;
Hashtable *textures;
} Gui;
Gui* gui_create(void);
void gui_set_max_health(Gui*, int max, SDL_Renderer*);
void gui_set_current_health(Gui*, int current);
Texture* gui_add_texture(Gui*, const char *path, SDL_Renderer*);
void gui_render(Gui*, Camera*);
void gui_destroy(Gui*);
#endif // GUI_H_

View File

@ -13,6 +13,7 @@
#include "timer.h" #include "timer.h"
#include "roommatrix.h" #include "roommatrix.h"
#include "gamestate.h" #include "gamestate.h"
#include "gui.h"
static SDL_Window *gWindow = NULL; static SDL_Window *gWindow = NULL;
static SDL_Renderer *gRenderer = NULL; static SDL_Renderer *gRenderer = NULL;
@ -20,7 +21,8 @@ static Player *gPlayer = NULL;
static LinkedList *gSpriteList = NULL; static LinkedList *gSpriteList = NULL;
static Map *gMap = NULL; static Map *gMap = NULL;
static RoomMatrix *gRoomMatrix = NULL; static RoomMatrix *gRoomMatrix = NULL;
static GameState gameState; static Gui *gGui = NULL;
static GameState gGameState;
static Camera gCamera; static Camera gCamera;
static static
@ -105,9 +107,10 @@ bool init(void)
gCamera.pos = (Position) { 0, 0 }; gCamera.pos = (Position) { 0, 0 };
gCamera.renderer = gRenderer; gCamera.renderer = gRenderer;
gRoomMatrix = roommatrix_create(); gRoomMatrix = roommatrix_create();
gGui = gui_create();
} }
gameState = PLAYING; gGameState = PLAYING;
return result; return result;
} }
@ -127,7 +130,7 @@ bool handle_events(void)
while (SDL_PollEvent(&event) != 0) { while (SDL_PollEvent(&event) != 0) {
if (event.type == SDL_QUIT) { if (event.type == SDL_QUIT) {
quit = true; quit = true;
} else { } else if (gGameState == PLAYING) {
gPlayer->handle_event(gPlayer, gPlayer->handle_event(gPlayer,
gRoomMatrix, gRoomMatrix,
&event); &event);
@ -158,6 +161,35 @@ check_next_level(void)
} }
} }
static void
run_game(void)
{
map_clear_dead_monsters(gMap);
roommatrix_populate_from_map(gRoomMatrix, gMap);
roommatrix_add_lightsource(gRoomMatrix,
&gPlayer->sprite->pos);
roommatrix_build_lightmap(gRoomMatrix);
gui_set_max_health(gGui, gPlayer->stats.maxhp, gRenderer);
gui_set_current_health(gGui, gPlayer->stats.hp);
if (gPlayer->steps == gPlayer->stats.speed) {
player_reset_steps(gPlayer);
roommatrix_update_with_player(gRoomMatrix, gPlayer);
map_move_monsters(gMap, gRoomMatrix);
}
SDL_RenderClear(gRenderer);
map_render(gMap, &gCamera);
player_render(gPlayer, &gCamera);
roommatrix_render_lightmap(gRoomMatrix, &gCamera);
gui_render(gGui, &gCamera);
SDL_RenderPresent(gRenderer);
check_next_level();
}
static static
void run(void) void run(void)
{ {
@ -169,28 +201,25 @@ void run(void)
timer_start(fpsTimer); timer_start(fpsTimer);
quit = handle_events(); quit = handle_events();
map_clear_dead_monsters(gMap);
roommatrix_populate_from_map(gRoomMatrix, gMap);
roommatrix_add_lightsource(gRoomMatrix,
&gPlayer->sprite->pos);
roommatrix_build_lightmap(gRoomMatrix);
if (gPlayer->steps == gPlayer->stats.speed) { switch (gGameState) {
player_reset_steps(gPlayer); case PLAYING:
roommatrix_update_with_player(gRoomMatrix, gPlayer); run_game();
map_move_monsters(gMap, gRoomMatrix); break;
case MENU:
fprintf(stderr, "[!!] MENU not implemented\n");
break;
case IN_GAME_MENU:
fprintf(stderr,
"[!!] IN_GAME_MENU not implemented\n");
break;
case GAME_OVER:
fprintf(stderr, "[!!] GAME_OVER not implemented\n");
break;
default:
break;
} }
SDL_RenderClear(gRenderer);
map_render(gMap, &gCamera);
player_render(gPlayer, &gCamera);
roommatrix_render_lightmap(gRoomMatrix, &gCamera);
SDL_RenderPresent(gRenderer);
check_next_level();
int ticks = timer_get_ticks(fpsTimer); int ticks = timer_get_ticks(fpsTimer);
if (ticks < 1000/60) if (ticks < 1000/60)
SDL_Delay((1000/60) - ticks); SDL_Delay((1000/60) - ticks);
@ -206,6 +235,8 @@ void close(void)
player_destroy(gPlayer); player_destroy(gPlayer);
map_destroy(gMap); map_destroy(gMap);
roommatrix_destroy(gRoomMatrix); roommatrix_destroy(gRoomMatrix);
gui_destroy(gGui);
SDL_DestroyRenderer(gRenderer);
SDL_DestroyWindow(gWindow); SDL_DestroyWindow(gWindow);
gWindow = NULL; gWindow = NULL;
TTF_Quit(); TTF_Quit();

View File

@ -25,7 +25,7 @@ Map* map_create()
Map *map = ec_malloc(sizeof(Map)); Map *map = ec_malloc(sizeof(Map));
map->textures = linkedlist_create(); map->textures = linkedlist_create();
map->monsterTextures = ht_create(100); map->monsterTextures = ht_create(30);
map->monsters = linkedlist_create(); map->monsters = linkedlist_create();
map->currentRoom = (Position) { 0, 0 }; map->currentRoom = (Position) { 0, 0 };
map->renderTimer = timer_create(); map->renderTimer = timer_create();

View File

@ -191,7 +191,7 @@ l_add_monster(lua_State *L)
texture1->dim = (Dimension) { TILE_DIMENSION, TILE_DIMENSION }; texture1->dim = (Dimension) { TILE_DIMENSION, TILE_DIMENSION };
texture2->dim = (Dimension) { TILE_DIMENSION, TILE_DIMENSION }; texture2->dim = (Dimension) { TILE_DIMENSION, TILE_DIMENSION };
lua_pop(L, 4); lua_pop(L, 6);
monster = monster_create(renderer); monster = monster_create(renderer);
monster->sprite->clip = (SDL_Rect) { clip_x, clip_y, 16, 16 }; monster->sprite->clip = (SDL_Rect) { clip_x, clip_y, 16, 16 };
@ -212,12 +212,13 @@ Map* map_lua_generator_run(SDL_Renderer *renderer)
int status, result; int status, result;
char file[] = "data/mapgen.lua"; char file[] = "data/mapgen.lua";
printf("[**] Running lua script: %s\n", file); printf("[**] Running lua map script: %s\n", file);
lua_State *L = load_lua_state(); lua_State *L = load_lua_state();
status = luaL_loadfile(L, file); status = luaL_loadfile(L, file);
if (status) { if (status) {
fprintf(stderr, "[!!] Couldn't load file: %s\n", lua_tostring(L, -1)); fprintf(stderr, "[!!] Couldn't load file: %s\n",
lua_tostring(L, -1));
exit(-1); exit(-1);
} }

View File

@ -30,7 +30,7 @@ monster_create(SDL_Renderer *renderer)
Monster *m = ec_malloc(sizeof(Monster)); Monster *m = ec_malloc(sizeof(Monster));
m->sprite = sprite_create(); m->sprite = sprite_create();
m->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 }; m->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 };
m->stats = (Stats) { 11, 1, 0, 0, 1, 1 }; m->stats = (Stats) { 12, 12, 1, 0, 0, 1, 1 };
m->state.normal = PASSIVE; m->state.normal = PASSIVE;
m->state.challenge = AGRESSIVE; m->state.challenge = AGRESSIVE;
m->state.current = m->state.normal; m->state.current = m->state.normal;

View File

@ -6,11 +6,11 @@
#include "monster.h" #include "monster.h"
#include "util.h" #include "util.h"
#define ENGINEER_STATS { 11, 5, 7, 2, 1, 1 } #define ENGINEER_STATS { 12, 12, 5, 7, 2, 1, 1 }
#define MAGE_STATS { 11, 5, 7, 2, 1, 1 } #define MAGE_STATS { 12, 12, 5, 7, 2, 1, 1 }
#define PALADIN_STATS { 11, 5, 7, 2, 1, 1 } #define PALADIN_STATS { 12, 12, 5, 7, 2, 1, 1 }
#define ROGUE_STATS { 11, 5, 7, 2, 2, 1 } #define ROGUE_STATS { 12, 12, 5, 7, 2, 2, 1 }
#define WARRIOR_STATS { 11, 5, 7, 2, 1, 1 } #define WARRIOR_STATS { 12, 12, 5, 7, 2, 1, 1 }
static bool static bool
has_collided(Player *player, RoomMatrix *matrix) has_collided(Player *player, RoomMatrix *matrix)

View File

@ -13,6 +13,7 @@ Sprite* sprite_create_default(void)
s->pos = (Position) { 0, 0 }; s->pos = (Position) { 0, 0 };
s->renderTimer = timer_create(); s->renderTimer = timer_create();
s->texture_index = 0; s->texture_index = 0;
s->fixed = false;
return s; return s;
} }
@ -65,7 +66,12 @@ void sprite_render(Sprite *s, Camera *cam)
} }
} }
Position cameraPos = camera_to_camera_position(cam, &s->pos); Position cameraPos;
if (!s->fixed)
cameraPos = camera_to_camera_position(cam, &s->pos);
else
cameraPos = s->pos;
texture_render_clip(s->textures[s->texture_index], texture_render_clip(s->textures[s->texture_index],
&cameraPos, &cameraPos,
&s->clip, &s->clip,

View File

@ -16,6 +16,7 @@ typedef struct Sprite_t {
Position pos; Position pos;
Timer *renderTimer; Timer *renderTimer;
unsigned int texture_index; unsigned int texture_index;
bool fixed;
} Sprite; } Sprite;
Sprite* sprite_create(void); Sprite* sprite_create(void);

View File

@ -2,10 +2,11 @@
#define STATS_H_ #define STATS_H_
typedef struct Stats_t { typedef struct Stats_t {
int hp; /* Hit points */ int maxhp; /* Max hitpoints */
int dmg; /* Damage modifier */ int hp; /* Current hit points */
int atk; /* Attack rating */ int dmg; /* Damage modifier */
int def; /* Defence rating */ int atk; /* Attack rating */
int def; /* Defence rating */
unsigned int speed; /* Speed */ unsigned int speed; /* Speed */
unsigned int lvl; /* Level */ unsigned int lvl; /* Level */
} Stats; } Stats;