Adds falling into pits

Monsters also avoid pits. Still need more pit layouts and
prevent monsters from "spawning"  in pits.
This commit is contained in:
Linus Probert 2018-03-25 23:30:26 +02:00
parent 1206ec8a2d
commit 0a21a2d915
20 changed files with 202 additions and 107 deletions

BIN
assets/Sounds/FX/fall.wav Normal file

Binary file not shown.

View File

@ -126,6 +126,7 @@ local function repack(data)
isCollider = data[5] or false, isCollider = data[5] or false,
isLightSource = data[6] or false, isLightSource = data[6] or false,
isLevelExit = data[7] or false, isLevelExit = data[7] or false,
isLethal = data[8] or false
} }
end end
@ -154,6 +155,12 @@ end
local function add_pits_to_room(map) local function add_pits_to_room(map)
if CURRENT_LEVEL < 2 then
return
elseif not random(4) == 1 then
return
end
local pitdata = read_file("pitlayouts.dat") local pitdata = read_file("pitlayouts.dat")
local cleanData = "" local cleanData = ""
@ -176,7 +183,7 @@ local function add_pits_to_room(map)
end end
for i=0, #cleanData-1 do for i=0, #cleanData-1 do
local c = cleanData:sub(i+1, i+1) local c = cleanData:sub(i, i)
local col = i % 16 local col = i % 16
local row = (i - (i % 16))/16 local row = (i - (i % 16))/16
if c == "#" then if c == "#" then
@ -197,8 +204,8 @@ local function add_pits_to_room(map)
io.write("\n") io.write("\n")
end end
for i=2,12 do for i=2,13 do
for j=2,9 do for j=2,10 do
if not tile_occupied(map, (i), (j)) and matrix[i][j] then if not tile_occupied(map, (i), (j)) and matrix[i][j] then
if not matrix[i-1][j-1] and not matrix[i+1][j-1] and matrix[i-1][j] and matrix[i+1][j] and matrix[i][j-1] then if not matrix[i-1][j-1] and not matrix[i+1][j-1] and matrix[i-1][j] and matrix[i+1][j] and matrix[i][j-1] then
add_tile(map, i, j, repack(pits.innermid)) add_tile(map, i, j, repack(pits.innermid))
@ -458,7 +465,7 @@ function module.build_square_room(map, room)
add_level_exit(map); add_level_exit(map);
end end
if CURRENT_LEVEL > 2 and random(10) == 1 then if CURRENT_LEVEL > 3 and random(10) == 1 then
directions = { "LEFT", "RIGHT", "UP", "DOWN" } directions = { "LEFT", "RIGHT", "UP", "DOWN" }
set_modifier(map, "WINDY", directions[random(#directions)]); set_modifier(map, "WINDY", directions[random(#directions)]);
end end
@ -489,17 +496,17 @@ function module.load_textures(map)
floor.singleright = { t_floor, -1, xo + 96, yo + 16, false } floor.singleright = { t_floor, -1, xo + 96, yo + 16, false }
local pit_yo = (random(5) + random(3)) * (16 * 2) local pit_yo = (random(5) + random(3)) * (16 * 2)
pits.topleft = { t_pit0, t_pit1, 0, pit_yo, true } pits.topleft = { t_pit0, t_pit1, 0, pit_yo, false, false, false, true }
pits.top = { t_pit0, t_pit1, 16, pit_yo, true } pits.top = { t_pit0, t_pit1, 16, pit_yo, false, false, false, true }
pits.topright = { t_pit0, t_pit1, 32, pit_yo, true } pits.topright = { t_pit0, t_pit1, 32, pit_yo, false, false, false, true }
pits.left = { t_pit0, t_pit1, 0, pit_yo + 16, true } pits.left = { t_pit0, t_pit1, 0, pit_yo + 16, false, false, false, true }
pits.center = { t_pit0, t_pit1, 16, pit_yo + 16, true } pits.center = { t_pit0, t_pit1, 16, pit_yo + 16, false, false, false, true }
pits.right = { t_pit0, t_pit1, 32, pit_yo + 16, true } pits.right = { t_pit0, t_pit1, 32, pit_yo + 16, false, false, false, true }
pits.innerleft = { t_pit0, t_pit1, 80, pit_yo, true } pits.innerleft = { t_pit0, t_pit1, 80, pit_yo, false, false, false, true }
pits.innermid = { t_pit0, t_pit1, 96, pit_yo, true } pits.innermid = { t_pit0, t_pit1, 96, pit_yo, false, false, false, true }
pits.innerright = { t_pit0, t_pit1, 112, pit_yo, true } pits.innerright = { t_pit0, t_pit1, 112, pit_yo, false, false, false, true }
pits.topcrevice = { t_pit0, t_pit1, 64, pit_yo, true } pits.topcrevice = { t_pit0, t_pit1, 64, pit_yo, false, false, false, true }
pits.bottomcrevice = { t_pit0, t_pit1, 64, pit_yo + 16, true } pits.bottomcrevice = { t_pit0, t_pit1, 64, pit_yo + 16, false, false, false, true }
wall.topleft = { t_wall, -1, xo + 0, yo + 0, true } wall.topleft = { t_wall, -1, xo + 0, yo + 0, true }
wall.topright = { t_wall, -1, xo + 32, yo + 0, true } wall.topright = { t_wall, -1, xo + 32, yo + 0, true }

View File

@ -1,12 +1,12 @@
---------------- ----------------
---------------- ----------------
----##--#------- --##--------##--
----######------ --##--####--##--
---######------- -------##-------
----####-------- -------##-------
------#--------- -------##-------
-----###-------- -------##-------
-----###-------- --##--####--##--
---------------- --##--------##--
---------------- ----------------
---------------- ----------------

View File

@ -480,7 +480,7 @@ run_game(void)
roommatrix_update_with_player(gRoomMatrix, gPlayer); roommatrix_update_with_player(gRoomMatrix, gPlayer);
if (currentTurn == PLAYER) { if (currentTurn == PLAYER) {
if (gPlayer->steps >= gPlayer->stats.speed) { if (gPlayer->stat_data.steps >= gPlayer->stats.speed) {
currentTurn = MONSTER; currentTurn = MONSTER;
player_reset_steps(gPlayer); player_reset_steps(gPlayer);
} }

View File

@ -42,7 +42,8 @@ Room* create_room(void)
return room; return room;
} }
Map* map_create() Map*
map_create(void)
{ {
int i, j; int i, j;
@ -64,7 +65,22 @@ Map* map_create()
return map; return map;
} }
void map_add_tile(Map *map, Position *tile_pos, MapTile *tile) MapTile*
map_create_tile(void)
{
MapTile *tile = ec_malloc(sizeof(MapTile));
tile->textureIndex0 = -1;
tile->textureIndex1 = -1;
tile->clip = CLIP16(0, 0);
tile->collider = false;
tile->lethal = false;
tile->lightsource = false;
tile->levelExit = false;
return tile;
}
void
map_add_tile(Map *map, Position *tile_pos, MapTile *tile)
{ {
const Position *cr = &map->currentRoom; const Position *cr = &map->currentRoom;
Room *room = map->rooms[cr->x][cr->y]; Room *room = map->rooms[cr->x][cr->y];

View File

@ -37,6 +37,7 @@ typedef struct MapTile_t {
int textureIndex1; int textureIndex1;
SDL_Rect clip; SDL_Rect clip;
bool collider; bool collider;
bool lethal;
bool lightsource; bool lightsource;
bool levelExit; bool levelExit;
} MapTile; } MapTile;
@ -61,6 +62,9 @@ typedef struct Map_t {
Map* Map*
map_create(void); map_create(void);
MapTile *
map_create_tile(void);
int int
map_add_texture(Map*, const char *path, SDL_Renderer*); map_add_texture(Map*, const char *path, SDL_Renderer*);

View File

@ -157,7 +157,7 @@ extract_tile_data(lua_State *L,
Map *map; Map *map;
int tile_x, tile_y; int tile_x, tile_y;
int t_index0, t_index1, tile_clip_x, tile_clip_y; int t_index0, t_index1, tile_clip_x, tile_clip_y;
bool collider, lightsource, levelExit; bool collider, lightsource, levelExit, lethal;
map = luaL_checkmap(L, 1); map = luaL_checkmap(L, 1);
tile_x = (int) luaL_checkinteger(L, 2); tile_x = (int) luaL_checkinteger(L, 2);
@ -175,28 +175,31 @@ extract_tile_data(lua_State *L,
lua_getfield(L, 4, "isCollider"); lua_getfield(L, 4, "isCollider");
lua_getfield(L, 4, "isLightSource"); lua_getfield(L, 4, "isLightSource");
lua_getfield(L, 4, "isLevelExit"); lua_getfield(L, 4, "isLevelExit");
lua_getfield(L, 4, "isLethal");
t_index0 = (int) luaL_checkinteger(L, -7); t_index0 = (int) luaL_checkinteger(L, -8);
t_index1 = (int) luaL_checkinteger(L, -6); t_index1 = (int) luaL_checkinteger(L, -7);
tile_clip_x = (int) luaL_checkinteger(L, -5); tile_clip_x = (int) luaL_checkinteger(L, -6);
tile_clip_y = (int) luaL_checkinteger(L, -4); tile_clip_y = (int) luaL_checkinteger(L, -5);
collider = lua_toboolean(L, -3); collider = lua_toboolean(L, -4);
lightsource = lua_toboolean(L, -2); lightsource = lua_toboolean(L, -3);
levelExit = lua_toboolean(L, -1); levelExit = lua_toboolean(L, -2);
lethal = lua_toboolean(L, -1);
// Clear the stack // Clear the stack
lua_pop(L, 7); lua_pop(L, 8);
Position tilePos = (Position) { tile_x, tile_y }; Position tilePos = (Position) { tile_x, tile_y };
SDL_Rect clip = (SDL_Rect) { tile_clip_x, tile_clip_y, 16, 16 }; SDL_Rect clip = (SDL_Rect) { tile_clip_x, tile_clip_y, 16, 16 };
MapTile *tile = malloc(sizeof(MapTile)); MapTile *tile = map_create_tile();
*tile = (MapTile) { t_index0, tile->textureIndex0 = t_index0;
t_index1, tile->textureIndex1 = t_index1;
clip, collider, tile->clip = clip;
lightsource, tile->collider = collider;
levelExit tile->lightsource = lightsource;
}; tile->levelExit = levelExit;
tile->lethal = lethal;
f_add_tile(map, &tilePos, tile); f_add_tile(map, &tilePos, tile);
} }
@ -252,7 +255,7 @@ int l_tile_occupied(lua_State *L)
tile = room->tiles[x][y]; tile = room->tiles[x][y];
decor = room->decorations[x][y]; decor = room->decorations[x][y];
response = response || (tile && (tile->collider || tile->levelExit)); response = response || (tile && (tile->collider || tile->levelExit || tile->lethal));
response = response || (decor && (decor->collider || decor->levelExit)); response = response || (decor && (decor->collider || decor->levelExit));
lua_pushboolean(L, response); lua_pushboolean(L, response);

View File

@ -79,6 +79,7 @@ load_effects(void)
effects[PLAYER_HIT1] = load_effect("Sounds/FX/fistpunch_vocal_02.wav"); effects[PLAYER_HIT1] = load_effect("Sounds/FX/fistpunch_vocal_02.wav");
effects[PLAYER_HIT2] = load_effect("Sounds/FX/fistpunch_vocal_03.wav"); effects[PLAYER_HIT2] = load_effect("Sounds/FX/fistpunch_vocal_03.wav");
effects[DAGGER_PICKUP] = load_effect("Sounds/FX/dagger_pickup.wav"); effects[DAGGER_PICKUP] = load_effect("Sounds/FX/dagger_pickup.wav");
effects[FALL] = load_effect("Sounds/FX/fall.wav");
} }
void void

View File

@ -42,6 +42,7 @@ typedef enum Fx_t {
TRIPPLE_SWORD_HIT, TRIPPLE_SWORD_HIT,
BONK, BONK,
DEATH, DEATH,
FALL,
COIN, COIN,
BOTTLE, BOTTLE,
BUBBLE0, BUBBLE0,

View File

@ -111,7 +111,7 @@ has_collided(Monster *monster, RoomMatrix *matrix)
gui_log("%s missed you", monster->label); gui_log("%s missed you", monster->label);
} }
return space->occupied; return space->occupied || space->lethal;
} }
static bool static bool
@ -220,7 +220,7 @@ monster_agressive_walk(Monster *m, RoomMatrix *rm)
x_dist = abs(next.x - rm->playerRoomPos.x); x_dist = abs(next.x - rm->playerRoomPos.x);
y_dist = abs(next.y - rm->playerRoomPos.y); y_dist = abs(next.y - rm->playerRoomPos.y);
if (rm->spaces[next.x][next.y].occupied) { if (rm->spaces[next.x][next.y].occupied || rm->spaces[next.x][next.y].lethal) {
nextScore += 50; nextScore += 50;
} }

View File

@ -84,8 +84,8 @@ player_gain_xp(Player *player, unsigned int xp_gain)
static void static void
action_spent(Player *p) action_spent(Player *p)
{ {
p->steps++; p->stat_data.steps++;
p->total_steps++; p->stat_data.total_steps++;
for (size_t i = 0; i < PLAYER_SKILL_COUNT; ++i) { for (size_t i = 0; i < PLAYER_SKILL_COUNT; ++i) {
if (p->skills[i] != NULL && p->skills[i]->resetCountdown > 0) if (p->skills[i] != NULL && p->skills[i]->resetCountdown > 0)
@ -125,10 +125,10 @@ has_collided(Player *player, RoomMatrix *matrix)
monster_hit(space->monster, hit); monster_hit(space->monster, hit);
if (hit > 0) { if (hit > 0) {
player->hits += 1; player->stat_data.hits += 1;
mixer_play_effect(SWORD_HIT); mixer_play_effect(SWORD_HIT);
} else { } else {
player->misses += 1; player->stat_data.misses += 1;
} }
if (hit > 0) if (hit > 0)
@ -155,6 +155,11 @@ has_collided(Player *player, RoomMatrix *matrix)
} }
} }
if (space->lethal && !collided) {
mixer_play_effect(FALL);
player->state = FALLING;
}
return collided; return collided;
} }
@ -318,6 +323,9 @@ check_skill_trigger(Player *player, RoomMatrix *matrix, SDL_Event *event)
static void static void
handle_player_input(Player *player, RoomMatrix *matrix, SDL_Event *event) handle_player_input(Player *player, RoomMatrix *matrix, SDL_Event *event)
{ {
if (player->state != ALIVE)
return;
if (event->type != SDL_KEYDOWN) if (event->type != SDL_KEYDOWN)
return; return;
@ -352,16 +360,19 @@ player_create(class_t class, SDL_Renderer *renderer)
{ {
Player *player = malloc(sizeof(Player)); Player *player = malloc(sizeof(Player));
player->sprite = sprite_create(); player->sprite = sprite_create();
player->daggers = 0; player->daggers = 0;
player->total_steps = 0; player->stat_data.total_steps = 0;
player->steps = 0; player->stat_data.steps = 0;
player->xp = 0; player->stat_data.hits = 0;
player->hits = 0; player->stat_data.kills = 0;
player->kills = 0; player->stat_data.misses = 0;
player->misses = 0; player->xp = 0;
player->gold = 0; player->gold = 0;
player->potion_sips = 0; player->potion_sips = 0;
player->class = class; player->class = class;
player->state = ALIVE;
player->projectiles = linkedlist_create();
player->animationTimer = timer_create();
for (size_t i = 0; i < PLAYER_SKILL_COUNT; ++i) { for (size_t i = 0; i < PLAYER_SKILL_COUNT; ++i) {
player->skills[i] = NULL; player->skills[i] = NULL;
@ -401,7 +412,6 @@ player_create(class_t class, SDL_Renderer *renderer)
player->sprite->dim = GAME_DIMENSION; player->sprite->dim = GAME_DIMENSION;
player->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 }; player->sprite->clip = (SDL_Rect) { 0, 0, 16, 16 };
player->handle_event = &handle_player_input; player->handle_event = &handle_player_input;
player->projectiles = linkedlist_create();
player_load_texts(player, renderer); player_load_texts(player, renderer);
return player; return player;
@ -425,8 +435,7 @@ player_monster_kill_check(Player *player, Monster *monster)
if (monster->stats.hp <= 0) { if (monster->stats.hp <= 0) {
unsigned int gained_xp = 5 * monster->stats.lvl; unsigned int gained_xp = 5 * monster->stats.lvl;
player->kills += 1; player->stat_data.kills += 1;
mixer_play_effect(DEATH); mixer_play_effect(DEATH);
gui_log("You killed %s and gained %d xp", gui_log("You killed %s and gained %d xp",
monster->lclabel, gained_xp); monster->lclabel, gained_xp);
@ -473,12 +482,13 @@ player_print(Player *p)
{ {
Position roomPos = position_to_matrix_coords(&p->sprite->pos); Position roomPos = position_to_matrix_coords(&p->sprite->pos);
Position pos = p->sprite->pos; Position pos = p->sprite->pos;
PlayerStatData *data = &p->stat_data;
debug("\n"); debug("\n");
debug("--------=== <[ Player Stats ]> ===--------"); debug("--------=== <[ Player Stats ]> ===--------");
debug("Hits: %u\tMisses:\t%u", p->hits, p->misses); debug("Hits: %u\tMisses:\t%u", data->hits, data->misses);
debug("Kills: %u", p->kills); debug("Kills: %u", data->kills);
debug("Steps: %u", p->total_steps); debug("Steps: %u", data->total_steps);
debug("Pos: %dx%d\tRoomPos: %dx%d", pos.x, pos.y, debug("Pos: %dx%d\tRoomPos: %dx%d", pos.x, pos.y,
roomPos.x, roomPos.y); roomPos.x, roomPos.y);
debug("------------------------------------------"); debug("------------------------------------------");
@ -487,42 +497,53 @@ player_print(Player *p)
void void
player_reset_steps(Player *p) player_reset_steps(Player *p)
{ {
p->steps = 0; p->stat_data.steps = 0;
player_print(p); player_print(p);
} }
void player_update(UpdateData *data) void player_update(UpdateData *data)
{ {
if (!data->player->projectiles) Player *player = data->player;
return; if (player->state == FALLING) {
if (!timer_started(player->animationTimer)) {
LinkedList *last, *current, *next; timer_start(player->animationTimer);
last = NULL; player->sprite->clip = CLIP16(0, 0);
current = data->player->projectiles;
next = NULL;
while (current) {
Projectile *p = current->data;
projectile_update(p, data);
if (!p->alive) {
if (last == NULL)
data->player->projectiles = current->next;
else
last->next = current->next;
projectile_destroy(p);
next = current->next;
current->data = NULL;
current->next = NULL;
linkedlist_destroy(&current);
current = next;
action_spent(data->player);
} else { } else {
last = current; if (timer_get_ticks(player->animationTimer) > 100) {
current = current->next; timer_start(player->animationTimer);
player->sprite->angle += 60;
player->sprite->dim.width -= 4;
player->sprite->dim.height -= 4;
player->sprite->pos.x += 2;
player->sprite->pos.y += 2;
player->sprite->rotationPoint = (SDL_Point) {
player->sprite->dim.width /2,
player->sprite->dim.height /2
};
if (player->sprite->dim.width <= 4)
player->stats.hp = 0;
}
} }
} }
if (!player->projectiles)
return;
LinkedList *remaining = linkedlist_create();
while (player->projectiles) {
Projectile *p = linkedlist_pop(&player->projectiles);
projectile_update(p, data);
if (p->alive) {
linkedlist_push(&remaining, p);
} else {
projectile_destroy(p);
action_spent(player);
}
}
linkedlist_destroy(&player->projectiles);
player->projectiles = remaining;
} }
void void

View File

@ -32,8 +32,16 @@
// Foward declare // Foward declare
struct UpdateData_t; struct UpdateData_t;
enum PlayerClass { ENGINEER, MAGE, PALADIN, ROGUE, WARRIOR }; typedef enum PlayerClass { ENGINEER, MAGE, PALADIN, ROGUE, WARRIOR } class_t;
typedef enum PlayerClass class_t; typedef enum PlayerState { ALIVE, DEAD, FALLING } state_t;
typedef struct PlayerStatData_t {
unsigned int total_steps;
unsigned int steps;
unsigned int hits;
unsigned int kills;
unsigned int misses;
} PlayerStatData;
typedef struct ExperienceData_t { typedef struct ExperienceData_t {
unsigned int previousLevel; unsigned int previousLevel;
@ -50,15 +58,13 @@ typedef struct Player_t {
unsigned int daggers; unsigned int daggers;
LinkedList *projectiles; LinkedList *projectiles;
unsigned int xp; unsigned int xp;
unsigned int total_steps;
unsigned int steps;
unsigned int hits;
unsigned int kills;
unsigned int misses;
double gold; double gold;
PlayerStatData stat_data;
unsigned int potion_sips; unsigned int potion_sips;
class_t class; class_t class;
state_t state;
Skill *skills[PLAYER_SKILL_COUNT]; Skill *skills[PLAYER_SKILL_COUNT];
Timer *animationTimer;
void (*handle_event)(struct Player_t*, RoomMatrix*, SDL_Event*); void (*handle_event)(struct Player_t*, RoomMatrix*, SDL_Event*);
} Player; } Player;

View File

@ -96,7 +96,7 @@ projectile_update(Projectile *p, UpdateData *data)
if (dmg > 0) { if (dmg > 0) {
gui_log("Your dagger pierced %s for %u damage", space->monster->lclabel, dmg); gui_log("Your dagger pierced %s for %u damage", space->monster->lclabel, dmg);
mixer_play_effect(SWORD_HIT); mixer_play_effect(SWORD_HIT);
data->player->hits += 1; data->player->stat_data.hits += 1;
} }
if (get_random(2) >= 1) { if (get_random(2) >= 1) {
Item *item = item_builder_build_item(DAGGER, 1); Item *item = item_builder_build_item(DAGGER, 1);

View File

@ -75,6 +75,8 @@ void roommatrix_populate_from_map(RoomMatrix *rm, Map *m)
r->tiles[i][j]->collider; r->tiles[i][j]->collider;
space->lightsource = space->lightsource =
r->tiles[i][j]->lightsource; r->tiles[i][j]->lightsource;
space->lethal =
r->tiles[i][j]->lethal;
} }
if (r->decorations[i][j]) { if (r->decorations[i][j]) {
space->occupied |= space->occupied |=
@ -253,7 +255,8 @@ roommatrix_render_lightmap(RoomMatrix *matrix, Camera *cam)
} }
} }
void roommatrix_reset(RoomMatrix *m) void
roommatrix_reset(RoomMatrix *m)
{ {
RoomSpace *space; RoomSpace *space;
int i, j; int i, j;
@ -262,6 +265,7 @@ void roommatrix_reset(RoomMatrix *m)
for (j = 0; j < MAP_ROOM_HEIGHT; ++j) { for (j = 0; j < MAP_ROOM_HEIGHT; ++j) {
space = &m->spaces[i][j]; space = &m->spaces[i][j];
space->occupied = false; space->occupied = false;
space->lethal = false;
space->lightsource = false; space->lightsource = false;
space->light = 0; space->light = 0;
space->monster = NULL; space->monster = NULL;

View File

@ -34,6 +34,7 @@ typedef struct Node LinkedList;
typedef struct { typedef struct {
bool occupied; bool occupied;
bool lethal;
bool lightsource; bool lightsource;
unsigned int light; unsigned int light;
Monster *monster; Monster *monster;

View File

@ -101,7 +101,7 @@ skill_use_flurry(Skill *skill, SkillData *data)
mixer_play_effect(TRIPPLE_SWORD_HIT); mixer_play_effect(TRIPPLE_SWORD_HIT);
} }
data->player->hits += hitCount; data->player->stat_data.hits += hitCount;
} else { } else {
gui_log("You swing at thin air with a flurry of strikes"); gui_log("You swing at thin air with a flurry of strikes");
@ -283,7 +283,7 @@ skill_charge(Skill *skill, SkillData *data)
if (dmg > 0) { if (dmg > 0) {
gui_log("You charged %s for %u damage", monster->lclabel, dmg); gui_log("You charged %s for %u damage", monster->lclabel, dmg);
mixer_play_effect(SWORD_HIT); mixer_play_effect(SWORD_HIT);
data->player->hits += 1; data->player->stat_data.hits += 1;
} }
monster_hit(monster, dmg); monster_hit(monster, dmg);
} }

View File

@ -30,6 +30,9 @@ sprite_create_default(void)
s->destroyTextures = false; s->destroyTextures = false;
s->pos = (Position) { 0, 0 }; s->pos = (Position) { 0, 0 };
s->dim = DEFAULT_DIMENSION; s->dim = DEFAULT_DIMENSION;
s->angle = 0;
s->rotationPoint = (SDL_Point) { 0, 0 };
s->flip = SDL_FLIP_NONE;
s->renderTimer = timer_create(); s->renderTimer = timer_create();
s->texture_index = 0; s->texture_index = 0;
s->fixed = false; s->fixed = false;
@ -119,13 +122,20 @@ sprite_render(Sprite *s, Camera *cam)
cameraPos.x, cameraPos.y, s->dim.width, s->dim.height cameraPos.x, cameraPos.y, s->dim.width, s->dim.height
}; };
if (s->clip.w && s->clip.h) { if ((s->clip.w && s->clip.h) || s->angle || s->flip != SDL_FLIP_NONE) {
texture_render_clip_ex(s->textures[s->texture_index],
&box,
&s->clip,
s->angle,
&s->rotationPoint,
s->flip,
cam);
} else if (s->clip.w && s->clip.h) {
texture_render_clip(s->textures[s->texture_index], texture_render_clip(s->textures[s->texture_index],
&box, &box,
&s->clip, &s->clip,
cam); cam);
} } else {
else {
texture_render(s->textures[s->texture_index], texture_render(s->textures[s->texture_index],
&box, &box,
cam); cam);

View File

@ -33,6 +33,9 @@ typedef struct Sprite_t {
bool destroyTextures; bool destroyTextures;
Position pos; Position pos;
Dimension dim; Dimension dim;
double angle;
SDL_Point rotationPoint;
SDL_RendererFlip flip;
Timer *renderTimer; Timer *renderTimer;
unsigned int texture_index; unsigned int texture_index;
bool fixed; bool fixed;

View File

@ -171,6 +171,21 @@ texture_render_clip(Texture *texture, SDL_Rect *box, SDL_Rect *clip, Camera *cam
box); box);
} }
void
texture_render_clip_ex(Texture *texture, SDL_Rect *box, SDL_Rect *clip, double angle, SDL_Point *point, SDL_RendererFlip flipType, Camera *cam)
{
if (!texture->texture)
return;
SDL_RenderCopyEx(cam->renderer,
texture->texture,
clip,
box,
angle,
point,
flipType);
}
void texture_destroy(Texture *texture) void texture_destroy(Texture *texture)
{ {
if (texture->texture) if (texture->texture)

View File

@ -65,6 +65,9 @@ texture_render(Texture*, SDL_Rect*, Camera*);
void void
texture_render_clip(Texture*, SDL_Rect*, SDL_Rect*, Camera*); texture_render_clip(Texture*, SDL_Rect*, SDL_Rect*, Camera*);
void
texture_render_clip_ex(Texture*, SDL_Rect*, SDL_Rect*, double angle, SDL_Point*, SDL_RendererFlip, Camera*);
void void
texture_destroy(Texture *texture); texture_destroy(Texture *texture);