Compare commits
10 commits
c939895390
...
208743c2f1
Author | SHA1 | Date | |
---|---|---|---|
![]() |
208743c2f1 | ||
![]() |
f67f95fd6a | ||
![]() |
a63cfdd2b0 | ||
![]() |
3d3d95030b | ||
![]() |
5edea42188 | ||
![]() |
b641589188 | ||
![]() |
630f60af94 | ||
![]() |
6b8dbaee7b | ||
![]() |
2895ce6079 | ||
![]() |
c50a3f3563 |
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -12,3 +12,5 @@ Makefile
|
|||
.vs
|
||||
.idea
|
||||
*.sln
|
||||
.kdev4
|
||||
fencer.kdev4
|
||||
|
|
|
@ -1,47 +1,63 @@
|
|||
#include "animation_sprite.h"
|
||||
#include "debug.h"
|
||||
#include "program.h"
|
||||
#include "list.h"
|
||||
|
||||
struct AnimationSprite {
|
||||
Spritesheet* sheet;
|
||||
Sprite* sprite_target;
|
||||
Spritesheet *sheet;
|
||||
Sprite *sprite_target;
|
||||
|
||||
AnimationSpriteLoopMode loop_mode;
|
||||
AnimationSpriteLoopMode loop_mode;
|
||||
|
||||
float frame_interval;
|
||||
float start_time;
|
||||
float frame_interval;
|
||||
float start_time;
|
||||
|
||||
size_t event_index;
|
||||
List events;
|
||||
};
|
||||
|
||||
AnimationSprite* animation_sprite_new(Sprite* target_sprite, Spritesheet* sheet, float framerate, AnimationSpriteLoopMode loop_mode) {
|
||||
AnimationSprite* self = malloc(sizeof(AnimationSprite));
|
||||
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate memory for AnimationSprite");
|
||||
*self = (AnimationSprite){
|
||||
.sheet = sheet,
|
||||
.frame_interval = 1.0f / framerate,
|
||||
.loop_mode = loop_mode,
|
||||
.start_time = game_time(),
|
||||
.sprite_target = target_sprite
|
||||
};
|
||||
|
||||
return self;
|
||||
AnimationSprite *animation_sprite_new(Sprite *target_sprite, Spritesheet *sheet,
|
||||
float framerate, AnimationSpriteLoopMode loop_mode,
|
||||
AnimationEvent *events, size_t event_count) {
|
||||
AnimationSprite *self = malloc(sizeof(AnimationSprite));
|
||||
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate memory for AnimationSprite");
|
||||
*self = (AnimationSprite){
|
||||
.sheet = sheet,
|
||||
.frame_interval = 1.0f / framerate,
|
||||
.loop_mode = loop_mode,
|
||||
.start_time = game_time(),
|
||||
.sprite_target = target_sprite,
|
||||
.event_index = 0,
|
||||
.events = list_with_len(sizeof(AnimationEvent), event_count),
|
||||
};
|
||||
if(event_count > 0) {
|
||||
memcpy(self->events.data, events, sizeof(AnimationEvent) * event_count);
|
||||
self->events.len = event_count;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void animation_sprite_destroy(AnimationSprite* self) {
|
||||
spritesheet_destroy(self->sheet);
|
||||
free(self);
|
||||
void animation_sprite_destroy(AnimationSprite *self) {
|
||||
spritesheet_destroy(self->sheet);
|
||||
free(self);
|
||||
}
|
||||
|
||||
void animation_sprite_play_from(AnimationSprite* self, float normalized_time) {
|
||||
self->start_time = game_time() - normalized_time * animation_sprite_get_length(self);
|
||||
void animation_sprite_reset(AnimationSprite *self) {
|
||||
self->start_time = game_time();
|
||||
}
|
||||
|
||||
void animation_sprite_draw(AnimationSprite* self, Transform* transform) {
|
||||
void animation_sprite_play_from(AnimationSprite *self, float normalized_time) {
|
||||
self->start_time = game_time() - normalized_time * animation_sprite_get_length(self);
|
||||
}
|
||||
|
||||
void animation_sprite_draw(AnimationSprite *self, Transform *transform) {
|
||||
const size_t frame_count = spritesheet_get_tile_count(self->sheet);
|
||||
const float time = game_time() - self->start_time;
|
||||
|
||||
const float time = game_time() - self->start_time;
|
||||
size_t frame = (size_t)(time / self->frame_interval);
|
||||
|
||||
switch(self->loop_mode) {
|
||||
case LoopMode_Stop:
|
||||
if(frame >= frame_count)
|
||||
frame = frame_count - 1;
|
||||
case LoopMode_Hide:
|
||||
if(frame >= frame_count)
|
||||
return;
|
||||
|
@ -55,36 +71,44 @@ void animation_sprite_draw(AnimationSprite* self, Transform* transform) {
|
|||
if(frame >= frame_count)
|
||||
frame = frame_count - (frame - frame_count);
|
||||
return;
|
||||
case LoopMode_Stop:
|
||||
if(frame >= frame_count)
|
||||
frame = frame_count - 1;
|
||||
}
|
||||
|
||||
|
||||
sprite_set_spritesheet(self->sprite_target, self->sheet);
|
||||
sprite_set_tile(self->sprite_target, frame);
|
||||
sprite_draw(self->sprite_target, *transform);
|
||||
sprite_set_tile(self->sprite_target, frame);
|
||||
sprite_draw(self->sprite_target, *transform);
|
||||
}
|
||||
|
||||
float animation_sprite_get_length(AnimationSprite* self) {
|
||||
return (float)spritesheet_get_tile_count(self->sheet) * self->frame_interval;
|
||||
void animation_sprite_update_events(AnimationSprite *self) {
|
||||
const float current_time = game_time() - self->start_time;
|
||||
for(;self->event_index <= self->events.len; ++self->event_index) {
|
||||
AnimationEvent *event = list_at_as(AnimationEvent, &self->events, self->event_index);
|
||||
if(event->time < current_time)
|
||||
return;
|
||||
else
|
||||
event->fn(event->target, event->arg.data);
|
||||
}
|
||||
}
|
||||
|
||||
void animation_sprite_set_framerate(AnimationSprite* self, float framerate) {
|
||||
self->frame_interval = 1.0f / framerate;
|
||||
float animation_sprite_get_length(AnimationSprite *self) {
|
||||
return (float)spritesheet_get_tile_count(self->sheet) * self->frame_interval;
|
||||
}
|
||||
|
||||
float animation_sprite_get_framerate(const AnimationSprite* self) {
|
||||
return 1.0f / self->frame_interval;
|
||||
void animation_sprite_set_framerate(AnimationSprite *self, float framerate) {
|
||||
self->frame_interval = 1.0f / framerate;
|
||||
}
|
||||
|
||||
Sprite* animation_sprite_get_sprite(AnimationSprite* self) {
|
||||
float animation_sprite_get_framerate(const AnimationSprite *self) {
|
||||
return 1.0f / self->frame_interval;
|
||||
}
|
||||
|
||||
Sprite *animation_sprite_get_sprite(AnimationSprite *self) {
|
||||
return self->sprite_target;
|
||||
}
|
||||
|
||||
float animation_sprite_get_time(AnimationSprite* self) {
|
||||
float animation_sprite_get_time(AnimationSprite *self) {
|
||||
return game_time() - self->start_time;
|
||||
}
|
||||
|
||||
float animation_sprite_get_time_normalized(AnimationSprite* self) {
|
||||
float animation_sprite_get_time_normalized(AnimationSprite *self) {
|
||||
return animation_sprite_get_time(self) / animation_sprite_get_length(self);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef _fencer_animation_sprite_h
|
||||
#define _fencer_animation_sprite_h
|
||||
|
||||
#include "drop.h"
|
||||
#include "sprite.h"
|
||||
#include "spritesheet.h"
|
||||
|
||||
|
@ -11,19 +12,31 @@ typedef enum AnimationSpriteLoopMode {
|
|||
LoopMode_PingPong,
|
||||
} AnimationSpriteLoopMode;
|
||||
|
||||
typedef void (*AnimationEventFn)(void *object, void *arg);
|
||||
|
||||
typedef struct AnimationEvent {
|
||||
float time;
|
||||
void *target;
|
||||
Drop arg;
|
||||
AnimationEventFn fn;
|
||||
} AnimationEvent;
|
||||
|
||||
typedef struct AnimationSprite AnimationSprite;
|
||||
|
||||
extern AnimationSprite* animation_sprite_new(Sprite* target_sprite, Spritesheet* sheet, float framerate, AnimationSpriteLoopMode loop_mode);
|
||||
extern void animation_sprite_destroy(AnimationSprite* self);
|
||||
extern AnimationSprite *animation_sprite_new(Sprite *target_sprite, Spritesheet *sheet, float framerate, AnimationSpriteLoopMode loop_mode, AnimationEvent *events, size_t event_count);
|
||||
extern void animation_sprite_destroy(AnimationSprite *self);
|
||||
|
||||
extern void animation_sprite_play_from(AnimationSprite* self, float normalized_time);
|
||||
extern void animation_sprite_draw(AnimationSprite* self, Transform* transform);
|
||||
extern void animation_sprite_reset(AnimationSprite *self);
|
||||
extern void animation_sprite_play_from(AnimationSprite *self, float normalized_time);
|
||||
extern void animation_sprite_draw(AnimationSprite *self, Transform *transform);
|
||||
|
||||
extern float animation_sprite_get_length(AnimationSprite* self);
|
||||
extern void animation_sprite_set_framerate(AnimationSprite* self, float framerate);
|
||||
extern float animation_sprite_get_framerate(const AnimationSprite* self);
|
||||
extern Sprite* animation_sprite_get_sprite(AnimationSprite* self);
|
||||
extern float animation_sprite_get_time(AnimationSprite* self);
|
||||
extern float animation_sprite_get_time_normalized(AnimationSprite* self);
|
||||
extern void animation_sprite_update_events(AnimationSprite *self);
|
||||
|
||||
extern float animation_sprite_get_length(AnimationSprite *self);
|
||||
extern void animation_sprite_set_framerate(AnimationSprite *self, float framerate);
|
||||
extern float animation_sprite_get_framerate(const AnimationSprite *self);
|
||||
extern Sprite *animation_sprite_get_sprite(AnimationSprite *self);
|
||||
extern float animation_sprite_get_time(AnimationSprite *self);
|
||||
extern float animation_sprite_get_time_normalized(AnimationSprite *self);
|
||||
|
||||
#endif // !_fencer_animation_sprite_h
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "variant.h"
|
||||
#include "ctype.h"
|
||||
|
||||
static Dictionary internal_spawn_functions = {
|
||||
static Dictionary internal_deserializers = {
|
||||
.list = { .data = NULL, .len = 0, .cap = 0, .element_size = 0 },
|
||||
.element_size = 0
|
||||
};
|
||||
|
@ -17,22 +17,22 @@ static int is_colon(int c) { return c == ':'; }
|
|||
static int ends_parameter(int c) { return c == '}' || c == ','; }
|
||||
|
||||
int level_init() {
|
||||
internal_spawn_functions = dictionary_from_type(LevelSpawnFn);
|
||||
internal_deserializers = dictionary_from_type(DeserializeFn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int level_clean() {
|
||||
dictionary_empty(&internal_spawn_functions);
|
||||
dictionary_empty(&internal_deserializers);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int level_register_spawner(const char* object_tag, LevelSpawnFn spawn_function) {
|
||||
dictionary_set_value(LevelSpawnFn, &internal_spawn_functions, object_tag, spawn_function);
|
||||
int level_register_spawner(const char* object_tag, DeserializeFn spawn_function) {
|
||||
dictionary_set_value(DeserializeFn, &internal_deserializers, object_tag, spawn_function);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline
|
||||
void spawn_object(LevelSpawnFn spawner, Dictionary* args) {
|
||||
void spawn_object(DeserializeFn spawner, Dictionary* args) {
|
||||
BehaviourEntity entity = spawner(args);
|
||||
game_world_add_entity(entity);
|
||||
if(TC_MIRRORS(entity, PhysicsEntity))
|
||||
|
@ -140,7 +140,7 @@ int level_parse_file(FILE* fp) {
|
|||
char buffer[length];
|
||||
char* obj_tag = NULL;
|
||||
Dictionary args = dictionary_new(sizeof(Variant));
|
||||
LevelSpawnFn spawner = NULL;
|
||||
DeserializeFn spawner = NULL;
|
||||
do {
|
||||
// read the next line of the level file
|
||||
length = get_until(fp, buffer, sizeof(buffer)-1, is_open_bracket);
|
||||
|
@ -152,7 +152,7 @@ int level_parse_file(FILE* fp) {
|
|||
obj_tag[length - start] = '\0';
|
||||
strncpy(obj_tag, buffer + start, length - start);
|
||||
// find the spawn function
|
||||
if(dictionary_try_get(&internal_spawn_functions, obj_tag, &spawner)) {
|
||||
if(dictionary_try_get(&internal_deserializers, obj_tag, &spawner)) {
|
||||
// load arguments from file and spawn object
|
||||
load_args(fp, &args, buffer, sizeof(buffer));
|
||||
spawn_object(spawner, &args);
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
#include "behaviour_entity.h"
|
||||
#include "dictionary.h"
|
||||
|
||||
typedef BehaviourEntity(*LevelSpawnFn)(Dictionary* args);
|
||||
typedef BehaviourEntity(*DeserializeFn)(Dictionary* args);
|
||||
|
||||
extern int level_init();
|
||||
extern int level_clean();
|
||||
|
||||
extern int level_register_spawner(const char* object_tag, LevelSpawnFn spawn_function);
|
||||
extern int level_register_spawner(const char* object_tag, DeserializeFn spawn_function);
|
||||
|
||||
extern int level_parse_file(FILE* level);
|
||||
extern int level_load_file(const char* path);
|
||||
|
|
176
core/src/list.c
176
core/src/list.c
|
@ -1,176 +0,0 @@
|
|||
#include "list.h"
|
||||
#include "stdint.h"
|
||||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "debug.h"
|
||||
|
||||
#ifndef LIST_DEFAULT_RESERVE
|
||||
#define LIST_DEFAULT_RESERVE 4
|
||||
#endif
|
||||
|
||||
List list_init(size_t element_size) {
|
||||
List self = {
|
||||
.element_size = element_size,
|
||||
.cap = LIST_DEFAULT_RESERVE,
|
||||
.len = 0,
|
||||
.data = malloc(element_size * LIST_DEFAULT_RESERVE),
|
||||
};
|
||||
|
||||
if(self.data == NULL) {
|
||||
LOG_ERROR("Failed to allocate list with starting capacity of %d", LIST_DEFAULT_RESERVE);
|
||||
self.cap = 0;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
List list_copy(const List* source) {
|
||||
List self = list_init(source->element_size);
|
||||
list_reserve(&self, source->cap);
|
||||
if(self.cap > 0) {
|
||||
memcpy(self.data, source->data, source->element_size * source->len);
|
||||
self.len = source->len;
|
||||
} else {
|
||||
LOG_ERROR("Failed to reserve space");
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void list_empty(List* self) {
|
||||
if(self->data == NULL || self->cap == 0)
|
||||
return;
|
||||
self->data = NULL;
|
||||
self->cap = 0;
|
||||
self->len = 0;
|
||||
}
|
||||
|
||||
void list_reserve(List* self, size_t at_least) {
|
||||
if(at_least < self->cap)
|
||||
return;
|
||||
|
||||
size_t new_cap = self->cap > 0 ? self->cap : LIST_DEFAULT_RESERVE;
|
||||
while(at_least >= new_cap) {
|
||||
new_cap *= 2;
|
||||
}
|
||||
|
||||
void* new;
|
||||
if(self->data == NULL)
|
||||
new = malloc(new_cap * self->element_size);
|
||||
else
|
||||
new = realloc(self->data, new_cap * self->element_size);
|
||||
ASSERT_RETURN(new != NULL,, "Failed to reserve space for %zu extra elements in list", new_cap);
|
||||
|
||||
self->data = new;
|
||||
self->cap = new_cap;
|
||||
}
|
||||
|
||||
void* list_at_unchecked(List* self, size_t at) {
|
||||
union {
|
||||
uint8_t* as_byte;
|
||||
void* as_void;
|
||||
} data = {
|
||||
.as_void = self->data
|
||||
};
|
||||
|
||||
return data.as_byte + self->element_size * at;
|
||||
}
|
||||
|
||||
void* list_at(List* self, size_t at) {
|
||||
ASSERT_RETURN(at < self->len, NULL, "Index %zu out of bounds", at);
|
||||
return list_at_unchecked(self, at);
|
||||
}
|
||||
|
||||
size_t list_add(List* self, void* item) {
|
||||
list_reserve(self, self->len + 1);
|
||||
union {
|
||||
uint8_t* as_byte;
|
||||
void* as_void;
|
||||
} data = {
|
||||
.as_void = self->data
|
||||
};
|
||||
|
||||
uint8_t* into = data.as_byte + (self->element_size * self->len);
|
||||
|
||||
memcpy(into, item, self->element_size);
|
||||
++self->len;
|
||||
|
||||
return self->len - 1;
|
||||
}
|
||||
|
||||
void list_insert(List* self, void* item, size_t at) {
|
||||
list_reserve(self, self->len + 1);
|
||||
|
||||
if(at >= self->len) {
|
||||
list_add(self, item);
|
||||
return;
|
||||
}
|
||||
|
||||
union {
|
||||
uint8_t* as_byte;
|
||||
void* as_void;
|
||||
} data = {
|
||||
.as_void = self->data
|
||||
};
|
||||
uint8_t* from = data.as_byte + (self->element_size * at);
|
||||
uint8_t* into = data.as_byte + (self->element_size * (at + 1));
|
||||
uint8_t* end = data.as_byte + (self->element_size * self->len);
|
||||
memmove(into, from, end - from);
|
||||
memcpy(from, item, self->element_size);
|
||||
++self->len;
|
||||
}
|
||||
|
||||
void list_erase(List* self, size_t at) {
|
||||
ASSERT_RETURN(at < self->len,, "Index %zu out of bounds", at);
|
||||
|
||||
union {
|
||||
uint8_t* as_byte;
|
||||
void* as_void;
|
||||
} data = {
|
||||
.as_void = self->data
|
||||
};
|
||||
|
||||
uint8_t* into = data.as_byte + at * self->element_size;
|
||||
uint8_t* from = data.as_byte + (at + 1) * self->element_size;
|
||||
|
||||
if(at < self->len - 1)
|
||||
memmove(into, from, (self->len - at) * self->element_size);
|
||||
--self->len;
|
||||
|
||||
size_t new_cap = self->cap;
|
||||
while(new_cap > self->len) {
|
||||
new_cap /= 2;
|
||||
}
|
||||
new_cap *= 2;
|
||||
|
||||
|
||||
if(new_cap == self->cap)
|
||||
return;
|
||||
|
||||
void* shrunk = realloc(self->data, new_cap * self->element_size);
|
||||
ASSERT_RETURN(shrunk != NULL || new_cap == 0,, "Failed to shrink List to %zu", new_cap);
|
||||
|
||||
self->data = shrunk;
|
||||
self->cap = new_cap;
|
||||
}
|
||||
|
||||
void* list_iterator_begin(List* self) {
|
||||
return list_at_unchecked(self, 0);
|
||||
}
|
||||
|
||||
void* list_iterator_end(List* self) {
|
||||
return list_at_unchecked(self, self->len);
|
||||
}
|
||||
|
||||
size_t list_contains(List* self, void* query) {
|
||||
union {
|
||||
uint8_t* as_byte;
|
||||
void* as_void;
|
||||
} data = {
|
||||
.as_void = self->data
|
||||
};
|
||||
for(size_t i = 0; i < self->len; ++i) {
|
||||
if(memcmp(data.as_byte + (i * self->element_size), query, self->element_size) == 0)
|
||||
return i;
|
||||
}
|
||||
return self->len;
|
||||
}
|
|
@ -1 +1 @@
|
|||
Subproject commit 253cc0cb0c40524ae27b940e57d197a5c38c58d4
|
||||
Subproject commit f84e3a3a27d626405173bd84055c299969cf7033
|
|
@ -8,13 +8,13 @@
|
|||
#include "sprite.h"
|
||||
#include "variant.h"
|
||||
|
||||
START_REFLECT(Enemy)
|
||||
REFLECT_TYPECLASS(Enemy, Transformable)
|
||||
REFLECT_TYPECLASS(Enemy, Drop)
|
||||
REFLECT_TYPECLASS(Enemy, PhysicsEntity)
|
||||
REFLECT_TYPECLASS(Enemy, BehaviourEntity)
|
||||
REFLECT_TYPECLASS(Enemy, Damagable)
|
||||
END_REFLECT(Enemy)
|
||||
START_REFLECT(Enemy);
|
||||
REFLECT_TYPECLASS(Enemy, Transformable);
|
||||
REFLECT_TYPECLASS(Enemy, Drop);
|
||||
REFLECT_TYPECLASS(Enemy, PhysicsEntity);
|
||||
REFLECT_TYPECLASS(Enemy, BehaviourEntity);
|
||||
REFLECT_TYPECLASS(Enemy, Damagable);
|
||||
END_REFLECT(Enemy);
|
||||
|
||||
impl_Transformable_for(Enemy,
|
||||
EnemyGetTransform
|
||||
|
@ -75,9 +75,9 @@ Enemy* MakeEnemy() {
|
|||
sprite_set_origin(self->sprite, MakeVector(0.45f, 0.925f));
|
||||
|
||||
// load and configure animations
|
||||
self->idleAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Idle.png", IVectorFrom(512)), 1.5f, LoopMode_Loop);
|
||||
self->walkAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Walk.png", IVectorFrom(512)), 1.5f, LoopMode_Loop);
|
||||
self->hurtAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Hurt.png", IVectorFrom(512)), 5.f, LoopMode_Stop);
|
||||
self->idleAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Idle.png", IVectorFrom(512)), 1.5f, LoopMode_Loop, NULL, 0);
|
||||
self->walkAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Walk.png", IVectorFrom(512)), 1.5f, LoopMode_Loop, NULL, 0);
|
||||
self->hurtAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Hurt.png", IVectorFrom(512)), 5.f, LoopMode_Stop, NULL, 0);
|
||||
self->behaviour = state_machine_init(self, EnemyIdle());
|
||||
|
||||
return self;
|
||||
|
|
|
@ -18,7 +18,7 @@ void Internal_HurtboxDealDamage(const Hurtbox* self, List* colliders, float min_
|
|||
}
|
||||
}
|
||||
|
||||
int HurtboxCast(Hurtbox* self, float facing_dir) {
|
||||
int HurtboxCast(Hurtbox* self, float facing_dir, List *out) {
|
||||
const IPhysicsEntity* physics_entity = mirror_get_typeclass(self->owner.data, self->owner.mirror, "PhysicsEntity");
|
||||
const ITransformable* transformable = mirror_get_typeclass(self->owner.data, self->owner.mirror, "Transformable");
|
||||
|
||||
|
@ -32,5 +32,9 @@ int HurtboxCast(Hurtbox* self, float facing_dir) {
|
|||
const Vector offset = vaddf(transform->position, MakeVector(facing_dir * self->offset.x, self->offset.y));
|
||||
List found = physics_world_box_query_all(offset, self->size, PHYSICS_LAYER_COMBAT, body);
|
||||
Internal_HurtboxDealDamage(self, &found, transform->position.y - self->depth_extent, transform->position.y + self->depth_extent);
|
||||
if(out == NULL)
|
||||
list_empty(&found);
|
||||
else
|
||||
*out = found;
|
||||
return found.len;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,6 @@ typedef struct Hurtbox {
|
|||
float depth_extent;
|
||||
} Hurtbox;
|
||||
|
||||
int HurtboxCast(Hurtbox* self, float facing_dir);
|
||||
extern int HurtboxCast(Hurtbox* self, float facing_dir, List *out);
|
||||
|
||||
#endif // !FIGHT_HURTBOX_H
|
||||
|
|
|
@ -12,12 +12,12 @@
|
|||
const Vector PLAYER_SPEED = { 1.0f, 0.50f };
|
||||
static const float PLAYER_INPUT_RATE = 1.f/15.f;
|
||||
|
||||
START_REFLECT(Player)
|
||||
REFLECT_TYPECLASS(Player, Drop)
|
||||
REFLECT_TYPECLASS(Player, PhysicsEntity)
|
||||
REFLECT_TYPECLASS(Player, BehaviourEntity)
|
||||
REFLECT_TYPECLASS(Player, Transformable)
|
||||
END_REFLECT(Player)
|
||||
START_REFLECT(Player);
|
||||
REFLECT_TYPECLASS(Player, Drop);
|
||||
REFLECT_TYPECLASS(Player, PhysicsEntity);
|
||||
REFLECT_TYPECLASS(Player, BehaviourEntity);
|
||||
REFLECT_TYPECLASS(Player, Transformable);
|
||||
END_REFLECT(Player);
|
||||
|
||||
impl_Drop_for(Player,
|
||||
DestroyPlayer
|
||||
|
@ -93,6 +93,7 @@ Player* MakePlayer() {
|
|||
.slide = NULL,
|
||||
|
||||
.animationStateMachine = NULL,
|
||||
.boxes = malloc(sizeof(Hurtbox) * 3),
|
||||
|
||||
.pushInputTimer = 0.f,
|
||||
.inputLog = list_from_type(PlayerInputFrame),
|
||||
|
@ -117,15 +118,15 @@ Player* MakePlayer() {
|
|||
sprite_set_origin(self->sprite, MakeVector(0.45f, 0.925f));
|
||||
|
||||
// load and configure animations
|
||||
self->idle = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Idle.png", IVectorFrom(512)), 1.5f, LoopMode_Loop);
|
||||
self->walk = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Walk.png", IVectorFrom(512)), 5.f, LoopMode_Loop);
|
||||
self->jump = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Jumping.png", IVectorFrom(512)), 1.f, LoopMode_Stop);
|
||||
self->jab_a = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Jab_A.png", IVectorFrom(512)), 10.f, LoopMode_Stop);
|
||||
self->jab_b = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Jab_B.png", IVectorFrom(512)), 10.f, LoopMode_Stop);
|
||||
self->kick_a = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Kick_A.png", IVectorFrom(512)), 12.f, LoopMode_Stop);
|
||||
self->slash = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Slash.png", IVectorFrom(512)), 12.f, LoopMode_Stop);
|
||||
self->air_heavy = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Air_Heavy.png", IVectorFrom(512)), 10.f, LoopMode_Stop);
|
||||
self->slide = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Slide.png", IVectorFrom(512)), 1.f, LoopMode_Loop);
|
||||
self->idle = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Idle.png", IVectorFrom(512)), 1.5f, LoopMode_Loop, NULL, 0);
|
||||
self->walk = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Walk.png", IVectorFrom(512)), 5.f, LoopMode_Loop, NULL, 0);
|
||||
self->jump = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Jumping.png", IVectorFrom(512)), 1.f, LoopMode_Stop, NULL, 0);
|
||||
self->jab_a = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Jab_A.png", IVectorFrom(512)), 10.f, LoopMode_Stop, NULL, 0);
|
||||
self->jab_b = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Jab_B.png", IVectorFrom(512)), 10.f, LoopMode_Stop, NULL, 0);
|
||||
self->kick_a = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Kick_A.png", IVectorFrom(512)), 12.f, LoopMode_Stop, NULL, 0);
|
||||
self->slash = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Slash.png", IVectorFrom(512)), 12.f, LoopMode_Stop, NULL, 0);
|
||||
self->air_heavy = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Air_Heavy.png", IVectorFrom(512)), 10.f, LoopMode_Stop, NULL, 0);
|
||||
self->slide = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Slide.png", IVectorFrom(512)), 1.f, LoopMode_Loop, NULL, 0);
|
||||
|
||||
self->animationStateMachine = state_machine_init(self, PlayerIdle());
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef FIGHT_PLAYER_H
|
||||
#define FIGHT_PLAYER_H
|
||||
|
||||
#include "Hurtbox.h"
|
||||
#include "dictionary.h"
|
||||
#include "state_machine.h"
|
||||
#include "mirror.h"
|
||||
|
@ -56,9 +57,9 @@ typedef struct Player {
|
|||
AnimationSprite* slide;
|
||||
|
||||
StateMachine* animationStateMachine;
|
||||
Hurtbox *boxes;
|
||||
|
||||
AnimationSprite* currentAnimation;
|
||||
|
||||
float pushInputTimer;
|
||||
List inputLog;
|
||||
PlayerInputFrame nextInputFrame;
|
||||
|
|
|
@ -82,7 +82,7 @@ void PlayerHurtbox(Player* self, DamageEventData damage, Vector hitbox_size, Vec
|
|||
.offset = vaddf(offset, MakeVector(0.f, self->height)),
|
||||
.depth_extent = 0.15f,
|
||||
};
|
||||
HurtboxCast(&box, self->facing);
|
||||
HurtboxCast(&box, self->facing, NULL);
|
||||
}
|
||||
|
||||
void PlayerJabA_Enter(Player* self) {
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
#include "mirror.h"
|
||||
#include "physics_world.h"
|
||||
|
||||
START_REFLECT(Prop)
|
||||
REFLECT_TYPECLASS(Prop, Transformable)
|
||||
REFLECT_TYPECLASS(Prop, Drop)
|
||||
REFLECT_TYPECLASS(Prop, BehaviourEntity)
|
||||
END_REFLECT(Prop)
|
||||
START_REFLECT(Prop);
|
||||
REFLECT_TYPECLASS(Prop, Transformable);
|
||||
REFLECT_TYPECLASS(Prop, Drop);
|
||||
REFLECT_TYPECLASS(Prop, BehaviourEntity);
|
||||
END_REFLECT(Prop);
|
||||
|
||||
impl_Transformable_for(Prop,
|
||||
PropGetTransform
|
||||
|
|
Loading…
Reference in a new issue