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/linkedlist
src/hashtable
src/gui
)
target_link_libraries(breakhack

View File

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

View File

@ -4,7 +4,8 @@
typedef enum GameState_t {
MENU,
PLAYING,
NEXT_LEVEL
IN_GAME_MENU,
GAME_OVER
} GameState;
#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 "roommatrix.h"
#include "gamestate.h"
#include "gui.h"
static SDL_Window *gWindow = NULL;
static SDL_Renderer *gRenderer = NULL;
@ -20,7 +21,8 @@ static Player *gPlayer = NULL;
static LinkedList *gSpriteList = NULL;
static Map *gMap = NULL;
static RoomMatrix *gRoomMatrix = NULL;
static GameState gameState;
static Gui *gGui = NULL;
static GameState gGameState;
static Camera gCamera;
static
@ -105,9 +107,10 @@ bool init(void)
gCamera.pos = (Position) { 0, 0 };
gCamera.renderer = gRenderer;
gRoomMatrix = roommatrix_create();
gGui = gui_create();
}
gameState = PLAYING;
gGameState = PLAYING;
return result;
}
@ -127,7 +130,7 @@ bool handle_events(void)
while (SDL_PollEvent(&event) != 0) {
if (event.type == SDL_QUIT) {
quit = true;
} else {
} else if (gGameState == PLAYING) {
gPlayer->handle_event(gPlayer,
gRoomMatrix,
&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
void run(void)
{
@ -169,28 +201,25 @@ void run(void)
timer_start(fpsTimer);
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) {
player_reset_steps(gPlayer);
roommatrix_update_with_player(gRoomMatrix, gPlayer);
map_move_monsters(gMap, gRoomMatrix);
switch (gGameState) {
case PLAYING:
run_game();
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);
if (ticks < 1000/60)
SDL_Delay((1000/60) - ticks);
@ -206,6 +235,8 @@ void close(void)
player_destroy(gPlayer);
map_destroy(gMap);
roommatrix_destroy(gRoomMatrix);
gui_destroy(gGui);
SDL_DestroyRenderer(gRenderer);
SDL_DestroyWindow(gWindow);
gWindow = NULL;
TTF_Quit();

View File

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

View File

@ -191,7 +191,7 @@ l_add_monster(lua_State *L)
texture1->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->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;
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();
status = luaL_loadfile(L, file);
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);
}

View File

@ -30,7 +30,7 @@ monster_create(SDL_Renderer *renderer)
Monster *m = ec_malloc(sizeof(Monster));
m->sprite = sprite_create();
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.challenge = AGRESSIVE;
m->state.current = m->state.normal;

View File

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

View File

@ -13,6 +13,7 @@ Sprite* sprite_create_default(void)
s->pos = (Position) { 0, 0 };
s->renderTimer = timer_create();
s->texture_index = 0;
s->fixed = false;
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],
&cameraPos,
&s->clip,

View File

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

View File

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