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/position
src/monster
src/stats
)
target_link_libraries(breakhack

View File

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

View File

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

View File

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

View File

@ -75,6 +75,34 @@ map_add_monster_texture(Map *map, const char *path, SDL_Renderer *renderer)
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
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*);
void map_clear_dead_monsters(Map*);
void map_add_monster(Map*, Monster*);
void map_render(Map*, Camera*);

View File

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

View File

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

View File

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

View File

@ -8,9 +8,10 @@
enum PlayerClass { ENGINEER, MAGE, PALADIN, ROGUE, WARRIOR };
typedef enum PlayerClass class_t;
typedef struct {
typedef struct Player_t {
Sprite *sprite;
Stats stats;
void (*handle_event)(struct Player_t*, RoomMatrix*, SDL_Event*);
} Player;
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 (j = 0; j < MAP_ROOM_HEIGHT; ++j) {
if (r->tiles[i][j]) {
rm->spaces[i][j].occupied = r->tiles[i][j]->collider;
rm->spaces[i][j].lightsource = r->tiles[i][j]->lightsource;
rm->spaces[i][j].occupied =
r->tiles[i][j]->collider;
rm->spaces[i][j].lightsource =
r->tiles[i][j]->lightsource;
}
if (r->decorations[i][j]) {
rm->spaces[i][j].occupied |= r->decorations[i][j]->collider;
rm->spaces[i][j].lightsource |= r->decorations[i][j]->lightsource;
rm->spaces[i][j].occupied |=
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);
if (!position_in_room(&monster->sprite->pos, &m->currentRoom))
continue;
monster_matrix_pos = position_to_matrix_coords(&monster->sprite->pos);
rm->spaces[monster_matrix_pos.x][monster_matrix_pos.y].occupied = true;
monster_matrix_pos =
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 (j = y_min; j <= y_max; ++j) {
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 = min(255, lightval);
lightval = max(0, lightval);
@ -136,7 +148,7 @@ void roommatrix_reset(RoomMatrix *m)
m->spaces[i][j].occupied = false;
m->spaces[i][j].lightsource = false;
m->spaces[i][j].light = 0;
m->spaces[i][j].character = NULL;
m->spaces[i][j].monster = NULL;
m->spaces[i][j].player = NULL;
}
}

View File

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

View File

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

View File

@ -16,7 +16,6 @@ typedef struct Sprite_t {
Position pos;
Timer *renderTimer;
unsigned int texture_index;
void (*handle_event)(struct Sprite_t*, RoomMatrix*, SDL_Event*);
} Sprite;
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_
typedef struct {
unsigned int hp; /* Hit points */
unsigned int dmg; /* Damage modifier */
unsigned int atk; /* Attack rating */
unsigned int speed; /* Speed */
int hp; /* Hit points */
int dmg; /* Damage modifier */
int atk; /* Attack rating */
int def; /* Defence rating */
int speed; /* Speed */
} Stats;
void
stats_fight(Stats *attacker, Stats *defender);
#endif // STATS_H_