Simple Player vs. Enemy hits

This commit is contained in:
Linus Probert 2017-12-15 08:08:45 +01:00
parent c4d142860c
commit 916193ecb3
16 changed files with 157 additions and 64 deletions

View File

@ -44,6 +44,7 @@ add_executable(breakhack
src/roommatrix src/roommatrix
src/position src/position
src/monster src/monster
src/stats
) )
target_link_libraries(breakhack target_link_libraries(breakhack

View File

@ -5,7 +5,8 @@ x Add enemies (generated through lua)
x Lua bindings for creation x Lua bindings for creation
x Making some better generation and randomeness x Making some better generation and randomeness
x Move "clip" from texture to sprite x Move "clip" from texture to sprite
o Hitting enemies x Hitting enemies
- Nicer enemy hits (Text textures, healthbars?)
- Moving enemies - Moving enemies
- Lower levels - Lower levels
- XP - XP

View File

@ -120,8 +120,10 @@ void linkedlist_destroy(LinkedList **head)
linkedlist_destroy(&(*head)->next); linkedlist_destroy(&(*head)->next);
if ((*head)->data != NULL) {
free((*head)->data); free((*head)->data);
(*head)->data = NULL; (*head)->data = NULL;
}
free(*head); free(*head);
*head = NULL; *head = NULL;
} }

View File

@ -30,9 +30,9 @@ bool initSDL()
//Dimension dim = (Dimension) { 1920, 1080 }; //Dimension dim = (Dimension) { 1920, 1080 };
double scale = 1.0; double scale = 1.0;
if (dim.height > 1080) { if (dim.height > 768) {
printf("[**] Hi resolution screen detected (%u x %u)\n", dim.width, dim.height); printf("[**] Hi resolution screen detected (%u x %u)\n", dim.width, dim.height);
scale = ((double) dim.height)/1080; scale = ((double) dim.height)/768;
printf("[**] Scaling by %f\n", scale); printf("[**] Scaling by %f\n", scale);
} }
@ -115,7 +115,7 @@ bool handle_events()
if (event.type == SDL_QUIT) { if (event.type == SDL_QUIT) {
quit = true; quit = true;
} else { } else {
gPlayer->sprite->handle_event(gPlayer->sprite, gPlayer->handle_event(gPlayer,
gRoomMatrix, gRoomMatrix,
&event); &event);
camera_follow_position(&gCamera, &gPlayer->sprite->pos); camera_follow_position(&gCamera, &gPlayer->sprite->pos);
@ -136,6 +136,7 @@ void run()
timer_start(fpsTimer); timer_start(fpsTimer);
quit = handle_events(); quit = handle_events();
map_clear_dead_monsters(gMap);
roommatrix_populate_from_map(gRoomMatrix, gMap); roommatrix_populate_from_map(gRoomMatrix, gMap);
roommatrix_add_lightsource(gRoomMatrix, roommatrix_add_lightsource(gRoomMatrix,
&gPlayer->sprite->pos); &gPlayer->sprite->pos);

View File

@ -75,6 +75,34 @@ map_add_monster_texture(Map *map, const char *path, SDL_Renderer *renderer)
return t; return t;
} }
void
map_clear_dead_monsters(Map *map)
{
LinkedList *last, *current, *next;
last = NULL;
current = map->monsters;
while (current != NULL) {
if (((Monster*) current->data)->stats.hp <= 0) {
if (last == NULL)
map->monsters = current->next;
else
last->next = current->next;
monster_destroy(current->data);
current->data = NULL;
next = current->next;
current->next = NULL;
linkedlist_destroy(&current);
current = next;
continue;
}
last = current;
current = current->next;
}
}
void void
map_add_monster(Map *map, Monster *m) map_add_monster(Map *map, Monster *m)
{ {

View File

@ -48,6 +48,8 @@ void map_add_decoration(Map *map, Position *tile_pos, MapTile*);
Texture* map_add_monster_texture(Map*, const char *path, SDL_Renderer*); Texture* map_add_monster_texture(Map*, const char *path, SDL_Renderer*);
void map_clear_dead_monsters(Map*);
void map_add_monster(Map*, Monster*); void map_add_monster(Map*, Monster*);
void map_render(Map*, Camera*); void map_render(Map*, Camera*);

View File

@ -1,5 +1,7 @@
#include "monster.h" #include "monster.h"
#include "util.h" #include "util.h"
#include "player.h"
#include "monster.h"
Monster* Monster*
monster_create() monster_create()
@ -7,6 +9,7 @@ monster_create()
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 };
return m; return m;
} }

View File

@ -5,7 +5,7 @@
#include "sprite.h" #include "sprite.h"
#include "stats.h" #include "stats.h"
typedef struct { typedef struct Monster_t {
Sprite *sprite; Sprite *sprite;
Stats stats; Stats stats;
} Monster; } Monster;

View File

@ -1,64 +1,74 @@
#include <string.h> #include <string.h>
#include "player.h" #include "player.h"
#include "monster.h"
static Stats classStats[] = { static Stats classStats[] = {
(Stats) { 11, 11, 11, 1 }, /* ENGINEER */ (Stats) { 11, 5, 7, 2, 1 }, /* ENGINEER */
(Stats) { 11, 11, 11, 1 }, /* MAGE */ (Stats) { 11, 5, 7, 2, 1 }, /* MAGE */
(Stats) { 11, 11, 11, 1 }, /* PALADIN */ (Stats) { 11, 5, 7, 2, 1 }, /* PALADIN */
(Stats) { 11, 11, 11, 2 }, /* ROGUE */ (Stats) { 11, 5, 7, 2, 2 }, /* ROGUE */
(Stats) { 11, 11, 11, 1 }, /* WARRIOR */ (Stats) { 11, 5, 7, 2, 1 }, /* WARRIOR */
}; };
static bool static bool
has_collided(Sprite *sprite, RoomMatrix *matrix) has_collided(Player *player, RoomMatrix *matrix)
{ {
Position roomCoord = position_to_room_coords(&sprite->pos); bool collided = false;
Position roomCoord = position_to_room_coords(&player->sprite->pos);
if (roomCoord.x != matrix->roomPos.x || roomCoord.y != matrix->roomPos.y) { if (roomCoord.x != matrix->roomPos.x || roomCoord.y != matrix->roomPos.y) {
return false; return collided;
} }
Position matrixPos = position_to_matrix_coords(&sprite->pos); Position matrixPos = position_to_matrix_coords(&player->sprite->pos);
return matrix->spaces[matrixPos.x][matrixPos.y].occupied; RoomSpace *space = &matrix->spaces[matrixPos.x][matrixPos.y];
collided = space->occupied;
if (space->monster != NULL) {
stats_fight(&player->stats, &space->monster->stats);
}
return collided;
} }
static void static void
move_left(Sprite *sprite, RoomMatrix *matrix) move_left(Player *player, RoomMatrix *matrix)
{ {
sprite->clip.y = 16; player->sprite->clip.y = 16;
sprite->pos.x -= TILE_DIMENSION; player->sprite->pos.x -= TILE_DIMENSION;
if (has_collided(sprite, matrix)) if (has_collided(player, matrix))
sprite->pos.x += TILE_DIMENSION; player->sprite->pos.x += TILE_DIMENSION;
} }
static static
void move_right(Sprite *sprite, RoomMatrix *matrix) void move_right(Player *player, RoomMatrix *matrix)
{ {
sprite->clip.y = 32; player->sprite->clip.y = 32;
sprite->pos.x += TILE_DIMENSION; player->sprite->pos.x += TILE_DIMENSION;
if (has_collided(sprite, matrix)) if (has_collided(player, matrix))
sprite->pos.x -= TILE_DIMENSION; player->sprite->pos.x -= TILE_DIMENSION;
} }
static static
void move_up(Sprite *sprite, RoomMatrix *matrix) void move_up(Player *player, RoomMatrix *matrix)
{ {
sprite->clip.y = 48; player->sprite->clip.y = 48;
sprite->pos.y -= TILE_DIMENSION; player->sprite->pos.y -= TILE_DIMENSION;
if (has_collided(sprite, matrix)) if (has_collided(player, matrix))
sprite->pos.y += TILE_DIMENSION; player->sprite->pos.y += TILE_DIMENSION;
} }
static static
void move_down(Sprite *sprite, RoomMatrix *matrix) void move_down(Player *player, RoomMatrix *matrix)
{ {
sprite->clip.y = 0; player->sprite->clip.y = 0;
sprite->pos.y += TILE_DIMENSION; player->sprite->pos.y += TILE_DIMENSION;
if (has_collided(sprite, matrix)) if (has_collided(player, matrix))
sprite->pos.y -= TILE_DIMENSION; player->sprite->pos.y -= TILE_DIMENSION;
} }
static static
void handle_player_input(Sprite *sprite, RoomMatrix *matrix, SDL_Event *event) void handle_player_input(Player *player, RoomMatrix *matrix, SDL_Event *event)
{ {
static unsigned int step = 1; static unsigned int step = 1;
@ -66,22 +76,22 @@ void handle_player_input(Sprite *sprite, RoomMatrix *matrix, SDL_Event *event)
switch (event->key.keysym.sym) { switch (event->key.keysym.sym) {
case SDLK_LEFT: case SDLK_LEFT:
case SDLK_h: case SDLK_h:
move_left(sprite, matrix); move_left(player, matrix);
break; break;
case SDLK_RIGHT: case SDLK_RIGHT:
case SDLK_l: case SDLK_l:
move_right(sprite, matrix); move_right(player, matrix);
break; break;
case SDLK_UP: case SDLK_UP:
case SDLK_k: case SDLK_k:
move_up(sprite, matrix); move_up(player, matrix);
break; break;
case SDLK_DOWN: case SDLK_DOWN:
case SDLK_j: case SDLK_j:
move_down(sprite, matrix); move_down(player, matrix);
break; break;
} }
sprite->clip.x = 16*step; player->sprite->clip.x = 16*step;
if (step == 3) if (step == 3)
step = 0; step = 0;
else else
@ -124,7 +134,7 @@ player_create(class_t class, SDL_Renderer *renderer)
player->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 }; player->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 };
player->sprite->textures[0]->dim = (Dimension) { player->sprite->textures[0]->dim = (Dimension) {
TILE_DIMENSION, TILE_DIMENSION }; TILE_DIMENSION, TILE_DIMENSION };
player->sprite->handle_event = &handle_player_input; player->handle_event = &handle_player_input;
return player; return player;
} }

View File

@ -8,9 +8,10 @@
enum PlayerClass { ENGINEER, MAGE, PALADIN, ROGUE, WARRIOR }; enum PlayerClass { ENGINEER, MAGE, PALADIN, ROGUE, WARRIOR };
typedef enum PlayerClass class_t; typedef enum PlayerClass class_t;
typedef struct { typedef struct Player_t {
Sprite *sprite; Sprite *sprite;
Stats stats; Stats stats;
void (*handle_event)(struct Player_t*, RoomMatrix*, SDL_Event*);
} Player; } Player;
Player* player_create(class_t, SDL_Renderer*); Player* player_create(class_t, SDL_Renderer*);

View File

@ -25,12 +25,18 @@ void roommatrix_populate_from_map(RoomMatrix *rm, Map *m)
for (i = 0; i < MAP_ROOM_WIDTH; ++i) { for (i = 0; i < MAP_ROOM_WIDTH; ++i) {
for (j = 0; j < MAP_ROOM_HEIGHT; ++j) { for (j = 0; j < MAP_ROOM_HEIGHT; ++j) {
if (r->tiles[i][j]) { if (r->tiles[i][j]) {
rm->spaces[i][j].occupied = r->tiles[i][j]->collider; rm->spaces[i][j].occupied =
rm->spaces[i][j].lightsource = r->tiles[i][j]->lightsource; r->tiles[i][j]->collider;
rm->spaces[i][j].lightsource =
r->tiles[i][j]->lightsource;
} }
if (r->decorations[i][j]) { if (r->decorations[i][j]) {
rm->spaces[i][j].occupied |= r->decorations[i][j]->collider; rm->spaces[i][j].occupied |=
rm->spaces[i][j].lightsource |= r->decorations[i][j]->lightsource; r->decorations[i][j]->collider;
rm->spaces[i][j].lightsource |=
r->decorations[i][j]->lightsource;
} }
} }
} }
@ -40,8 +46,13 @@ void roommatrix_populate_from_map(RoomMatrix *rm, Map *m)
monster = linkedlist_get(&m->monsters, i); monster = linkedlist_get(&m->monsters, i);
if (!position_in_room(&monster->sprite->pos, &m->currentRoom)) if (!position_in_room(&monster->sprite->pos, &m->currentRoom))
continue; continue;
monster_matrix_pos = position_to_matrix_coords(&monster->sprite->pos); monster_matrix_pos =
rm->spaces[monster_matrix_pos.x][monster_matrix_pos.y].occupied = true; position_to_matrix_coords(&monster->sprite->pos);
rm->spaces[monster_matrix_pos.x][monster_matrix_pos.y]
.occupied = true;
rm->spaces[monster_matrix_pos.x][monster_matrix_pos.y]
.monster = monster;
} }
} }
@ -85,7 +96,8 @@ set_light_for_tile(RoomMatrix *matrix, int x, int y)
for (i = x_min; i <= x_max; ++i) { for (i = x_min; i <= x_max; ++i) {
for (j = y_min; j <= y_max; ++j) { for (j = y_min; j <= y_max; ++j) {
lightval = matrix->spaces[i][j].light; lightval = matrix->spaces[i][j].light;
distance_modifier = abs(x-i) == abs(y-j) ? abs(x-i) + 1 : max(abs(x-i), abs(y-j)); distance_modifier = abs(x-i) == abs(y-j) ?
abs(x-i) + 1 : max(abs(x-i), abs(y-j));
lightval += 255 - (distance_modifier * 50); lightval += 255 - (distance_modifier * 50);
lightval = min(255, lightval); lightval = min(255, lightval);
lightval = max(0, lightval); lightval = max(0, lightval);
@ -136,7 +148,7 @@ void roommatrix_reset(RoomMatrix *m)
m->spaces[i][j].occupied = false; m->spaces[i][j].occupied = false;
m->spaces[i][j].lightsource = false; m->spaces[i][j].lightsource = false;
m->spaces[i][j].light = 0; m->spaces[i][j].light = 0;
m->spaces[i][j].character = NULL; m->spaces[i][j].monster = NULL;
m->spaces[i][j].player = NULL; m->spaces[i][j].player = NULL;
} }
} }

View File

@ -8,13 +8,15 @@
typedef struct Sprite_t Sprite; typedef struct Sprite_t Sprite;
typedef struct Map_t Map; typedef struct Map_t Map;
typedef struct Monster_t Monster;
typedef struct Player_t Player;
typedef struct { typedef struct {
bool occupied; bool occupied;
bool lightsource; bool lightsource;
unsigned int light; unsigned int light;
Sprite* character; Monster* monster;
Sprite* player; Player* player;
} RoomSpace; } RoomSpace;
typedef struct { typedef struct {

View File

@ -12,8 +12,7 @@ Sprite* sprite_create_default()
(SDL_Rect) { 0, 0, 16, 16 }, (SDL_Rect) { 0, 0, 16, 16 },
false, pos, false, pos,
NULL, NULL,
0, 0
NULL
}; };
s->renderTimer = timer_create(); s->renderTimer = timer_create();

View File

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

28
src/stats.c Normal file
View File

@ -0,0 +1,28 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include "stats.h"
void
stats_fight(Stats *attacker, Stats *defender)
{
unsigned int atkRoll, defRoll, dmgRoll;
bool critical = false;
srand(time(NULL));
atkRoll = (rand() % 20);
if (atkRoll == 20)
critical = true;
atkRoll += attacker->atk;
defRoll = (rand() % 20) + defender->def;
printf("Attacking: %d, Defending: %d\n", atkRoll, defRoll);
if (atkRoll > defRoll) {
dmgRoll = (rand() % 8) + attacker->dmg;
defender->hp -= dmgRoll;
if (critical)
defender->hp -= dmgRoll;
}
printf("Attacker hp: %d, Defender hp: %d\n", attacker->hp, defender->hp);
}

View File

@ -2,10 +2,14 @@
#define STATS_H_ #define STATS_H_
typedef struct { typedef struct {
unsigned int hp; /* Hit points */ int hp; /* Hit points */
unsigned int dmg; /* Damage modifier */ int dmg; /* Damage modifier */
unsigned int atk; /* Attack rating */ int atk; /* Attack rating */
unsigned int speed; /* Speed */ int def; /* Defence rating */
int speed; /* Speed */
} Stats; } Stats;
void
stats_fight(Stats *attacker, Stats *defender);
#endif // STATS_H_ #endif // STATS_H_