Compare commits
No commits in common. "208743c2f14a1bb4460fa302f83dff54f83fcec1" and "c93989539053d0d746985d9e727c48a403e4cb5c" have entirely different histories.
208743c2f1
...
c939895390
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -12,5 +12,3 @@ Makefile
|
||||||
.vs
|
.vs
|
||||||
.idea
|
.idea
|
||||||
*.sln
|
*.sln
|
||||||
.kdev4
|
|
||||||
fencer.kdev4
|
|
||||||
|
|
|
@ -1,63 +1,47 @@
|
||||||
#include "animation_sprite.h"
|
#include "animation_sprite.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "program.h"
|
#include "program.h"
|
||||||
#include "list.h"
|
|
||||||
|
|
||||||
struct AnimationSprite {
|
struct AnimationSprite {
|
||||||
Spritesheet *sheet;
|
Spritesheet* sheet;
|
||||||
Sprite *sprite_target;
|
Sprite* sprite_target;
|
||||||
|
|
||||||
AnimationSpriteLoopMode loop_mode;
|
AnimationSpriteLoopMode loop_mode;
|
||||||
|
|
||||||
float frame_interval;
|
float frame_interval;
|
||||||
float start_time;
|
float start_time;
|
||||||
|
|
||||||
size_t event_index;
|
|
||||||
List events;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
AnimationSprite *animation_sprite_new(Sprite *target_sprite, Spritesheet *sheet,
|
AnimationSprite* animation_sprite_new(Sprite* target_sprite, Spritesheet* sheet, float framerate, AnimationSpriteLoopMode loop_mode) {
|
||||||
float framerate, AnimationSpriteLoopMode loop_mode,
|
AnimationSprite* self = malloc(sizeof(AnimationSprite));
|
||||||
AnimationEvent *events, size_t event_count) {
|
|
||||||
AnimationSprite *self = malloc(sizeof(AnimationSprite));
|
|
||||||
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate memory for AnimationSprite");
|
ASSERT_RETURN(self != NULL, NULL, "Failed to allocate memory for AnimationSprite");
|
||||||
*self = (AnimationSprite){
|
*self = (AnimationSprite){
|
||||||
.sheet = sheet,
|
.sheet = sheet,
|
||||||
.frame_interval = 1.0f / framerate,
|
.frame_interval = 1.0f / framerate,
|
||||||
.loop_mode = loop_mode,
|
.loop_mode = loop_mode,
|
||||||
.start_time = game_time(),
|
.start_time = game_time(),
|
||||||
.sprite_target = target_sprite,
|
.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;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
void animation_sprite_destroy(AnimationSprite *self) {
|
void animation_sprite_destroy(AnimationSprite* self) {
|
||||||
spritesheet_destroy(self->sheet);
|
spritesheet_destroy(self->sheet);
|
||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void animation_sprite_reset(AnimationSprite *self) {
|
void animation_sprite_play_from(AnimationSprite* self, float normalized_time) {
|
||||||
self->start_time = game_time();
|
|
||||||
}
|
|
||||||
|
|
||||||
void animation_sprite_play_from(AnimationSprite *self, float normalized_time) {
|
|
||||||
self->start_time = game_time() - normalized_time * animation_sprite_get_length(self);
|
self->start_time = game_time() - normalized_time * animation_sprite_get_length(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void animation_sprite_draw(AnimationSprite *self, Transform *transform) {
|
void animation_sprite_draw(AnimationSprite* self, Transform* transform) {
|
||||||
const size_t frame_count = spritesheet_get_tile_count(self->sheet);
|
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);
|
size_t frame = (size_t)(time / self->frame_interval);
|
||||||
|
|
||||||
switch(self->loop_mode) {
|
switch(self->loop_mode) {
|
||||||
case LoopMode_Stop:
|
|
||||||
if(frame >= frame_count)
|
|
||||||
frame = frame_count - 1;
|
|
||||||
case LoopMode_Hide:
|
case LoopMode_Hide:
|
||||||
if(frame >= frame_count)
|
if(frame >= frame_count)
|
||||||
return;
|
return;
|
||||||
|
@ -71,6 +55,9 @@ void animation_sprite_draw(AnimationSprite *self, Transform *transform) {
|
||||||
if(frame >= frame_count)
|
if(frame >= frame_count)
|
||||||
frame = frame_count - (frame - frame_count);
|
frame = frame_count - (frame - frame_count);
|
||||||
return;
|
return;
|
||||||
|
case LoopMode_Stop:
|
||||||
|
if(frame >= frame_count)
|
||||||
|
frame = frame_count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite_set_spritesheet(self->sprite_target, self->sheet);
|
sprite_set_spritesheet(self->sprite_target, self->sheet);
|
||||||
|
@ -78,37 +65,26 @@ void animation_sprite_draw(AnimationSprite *self, Transform *transform) {
|
||||||
sprite_draw(self->sprite_target, *transform);
|
sprite_draw(self->sprite_target, *transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
void animation_sprite_update_events(AnimationSprite *self) {
|
float animation_sprite_get_length(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float animation_sprite_get_length(AnimationSprite *self) {
|
|
||||||
return (float)spritesheet_get_tile_count(self->sheet) * self->frame_interval;
|
return (float)spritesheet_get_tile_count(self->sheet) * self->frame_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void animation_sprite_set_framerate(AnimationSprite *self, float framerate) {
|
void animation_sprite_set_framerate(AnimationSprite* self, float framerate) {
|
||||||
self->frame_interval = 1.0f / framerate;
|
self->frame_interval = 1.0f / framerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
float animation_sprite_get_framerate(const AnimationSprite *self) {
|
float animation_sprite_get_framerate(const AnimationSprite* self) {
|
||||||
return 1.0f / self->frame_interval;
|
return 1.0f / self->frame_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sprite *animation_sprite_get_sprite(AnimationSprite *self) {
|
Sprite* animation_sprite_get_sprite(AnimationSprite* self) {
|
||||||
return self->sprite_target;
|
return self->sprite_target;
|
||||||
}
|
}
|
||||||
|
|
||||||
float animation_sprite_get_time(AnimationSprite *self) {
|
float animation_sprite_get_time(AnimationSprite* self) {
|
||||||
return game_time() - self->start_time;
|
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);
|
return animation_sprite_get_time(self) / animation_sprite_get_length(self);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef _fencer_animation_sprite_h
|
#ifndef _fencer_animation_sprite_h
|
||||||
#define _fencer_animation_sprite_h
|
#define _fencer_animation_sprite_h
|
||||||
|
|
||||||
#include "drop.h"
|
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "spritesheet.h"
|
#include "spritesheet.h"
|
||||||
|
|
||||||
|
@ -12,31 +11,19 @@ typedef enum AnimationSpriteLoopMode {
|
||||||
LoopMode_PingPong,
|
LoopMode_PingPong,
|
||||||
} AnimationSpriteLoopMode;
|
} AnimationSpriteLoopMode;
|
||||||
|
|
||||||
typedef void (*AnimationEventFn)(void *object, void *arg);
|
|
||||||
|
|
||||||
typedef struct AnimationEvent {
|
|
||||||
float time;
|
|
||||||
void *target;
|
|
||||||
Drop arg;
|
|
||||||
AnimationEventFn fn;
|
|
||||||
} AnimationEvent;
|
|
||||||
|
|
||||||
typedef struct AnimationSprite AnimationSprite;
|
typedef struct AnimationSprite AnimationSprite;
|
||||||
|
|
||||||
extern AnimationSprite *animation_sprite_new(Sprite *target_sprite, Spritesheet *sheet, float framerate, AnimationSpriteLoopMode loop_mode, AnimationEvent *events, size_t event_count);
|
extern AnimationSprite* animation_sprite_new(Sprite* target_sprite, Spritesheet* sheet, float framerate, AnimationSpriteLoopMode loop_mode);
|
||||||
extern void animation_sprite_destroy(AnimationSprite *self);
|
extern void animation_sprite_destroy(AnimationSprite* self);
|
||||||
|
|
||||||
extern void animation_sprite_reset(AnimationSprite *self);
|
extern void animation_sprite_play_from(AnimationSprite* self, float normalized_time);
|
||||||
extern void animation_sprite_play_from(AnimationSprite *self, float normalized_time);
|
extern void animation_sprite_draw(AnimationSprite* self, Transform* transform);
|
||||||
extern void animation_sprite_draw(AnimationSprite *self, Transform *transform);
|
|
||||||
|
|
||||||
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_length(AnimationSprite *self);
|
extern float animation_sprite_get_framerate(const AnimationSprite* self);
|
||||||
extern void animation_sprite_set_framerate(AnimationSprite *self, float framerate);
|
extern Sprite* animation_sprite_get_sprite(AnimationSprite* self);
|
||||||
extern float animation_sprite_get_framerate(const AnimationSprite *self);
|
extern float animation_sprite_get_time(AnimationSprite* self);
|
||||||
extern Sprite *animation_sprite_get_sprite(AnimationSprite *self);
|
extern float animation_sprite_get_time_normalized(AnimationSprite* self);
|
||||||
extern float animation_sprite_get_time(AnimationSprite *self);
|
|
||||||
extern float animation_sprite_get_time_normalized(AnimationSprite *self);
|
|
||||||
|
|
||||||
#endif // !_fencer_animation_sprite_h
|
#endif // !_fencer_animation_sprite_h
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "variant.h"
|
#include "variant.h"
|
||||||
#include "ctype.h"
|
#include "ctype.h"
|
||||||
|
|
||||||
static Dictionary internal_deserializers = {
|
static Dictionary internal_spawn_functions = {
|
||||||
.list = { .data = NULL, .len = 0, .cap = 0, .element_size = 0 },
|
.list = { .data = NULL, .len = 0, .cap = 0, .element_size = 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 == ','; }
|
static int ends_parameter(int c) { return c == '}' || c == ','; }
|
||||||
|
|
||||||
int level_init() {
|
int level_init() {
|
||||||
internal_deserializers = dictionary_from_type(DeserializeFn);
|
internal_spawn_functions = dictionary_from_type(LevelSpawnFn);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int level_clean() {
|
int level_clean() {
|
||||||
dictionary_empty(&internal_deserializers);
|
dictionary_empty(&internal_spawn_functions);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int level_register_spawner(const char* object_tag, DeserializeFn spawn_function) {
|
int level_register_spawner(const char* object_tag, LevelSpawnFn spawn_function) {
|
||||||
dictionary_set_value(DeserializeFn, &internal_deserializers, object_tag, spawn_function);
|
dictionary_set_value(LevelSpawnFn, &internal_spawn_functions, object_tag, spawn_function);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
void spawn_object(DeserializeFn spawner, Dictionary* args) {
|
void spawn_object(LevelSpawnFn spawner, Dictionary* args) {
|
||||||
BehaviourEntity entity = spawner(args);
|
BehaviourEntity entity = spawner(args);
|
||||||
game_world_add_entity(entity);
|
game_world_add_entity(entity);
|
||||||
if(TC_MIRRORS(entity, PhysicsEntity))
|
if(TC_MIRRORS(entity, PhysicsEntity))
|
||||||
|
@ -140,7 +140,7 @@ int level_parse_file(FILE* fp) {
|
||||||
char buffer[length];
|
char buffer[length];
|
||||||
char* obj_tag = NULL;
|
char* obj_tag = NULL;
|
||||||
Dictionary args = dictionary_new(sizeof(Variant));
|
Dictionary args = dictionary_new(sizeof(Variant));
|
||||||
DeserializeFn spawner = NULL;
|
LevelSpawnFn spawner = NULL;
|
||||||
do {
|
do {
|
||||||
// read the next line of the level file
|
// read the next line of the level file
|
||||||
length = get_until(fp, buffer, sizeof(buffer)-1, is_open_bracket);
|
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';
|
obj_tag[length - start] = '\0';
|
||||||
strncpy(obj_tag, buffer + start, length - start);
|
strncpy(obj_tag, buffer + start, length - start);
|
||||||
// find the spawn function
|
// find the spawn function
|
||||||
if(dictionary_try_get(&internal_deserializers, obj_tag, &spawner)) {
|
if(dictionary_try_get(&internal_spawn_functions, obj_tag, &spawner)) {
|
||||||
// load arguments from file and spawn object
|
// load arguments from file and spawn object
|
||||||
load_args(fp, &args, buffer, sizeof(buffer));
|
load_args(fp, &args, buffer, sizeof(buffer));
|
||||||
spawn_object(spawner, &args);
|
spawn_object(spawner, &args);
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
#include "behaviour_entity.h"
|
#include "behaviour_entity.h"
|
||||||
#include "dictionary.h"
|
#include "dictionary.h"
|
||||||
|
|
||||||
typedef BehaviourEntity(*DeserializeFn)(Dictionary* args);
|
typedef BehaviourEntity(*LevelSpawnFn)(Dictionary* args);
|
||||||
|
|
||||||
extern int level_init();
|
extern int level_init();
|
||||||
extern int level_clean();
|
extern int level_clean();
|
||||||
|
|
||||||
extern int level_register_spawner(const char* object_tag, DeserializeFn spawn_function);
|
extern int level_register_spawner(const char* object_tag, LevelSpawnFn spawn_function);
|
||||||
|
|
||||||
extern int level_parse_file(FILE* level);
|
extern int level_parse_file(FILE* level);
|
||||||
extern int level_load_file(const char* path);
|
extern int level_load_file(const char* path);
|
||||||
|
|
176
core/src/list.c
Normal file
176
core/src/list.c
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
#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 f84e3a3a27d626405173bd84055c299969cf7033
|
Subproject commit 253cc0cb0c40524ae27b940e57d197a5c38c58d4
|
|
@ -8,13 +8,13 @@
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "variant.h"
|
#include "variant.h"
|
||||||
|
|
||||||
START_REFLECT(Enemy);
|
START_REFLECT(Enemy)
|
||||||
REFLECT_TYPECLASS(Enemy, Transformable);
|
REFLECT_TYPECLASS(Enemy, Transformable)
|
||||||
REFLECT_TYPECLASS(Enemy, Drop);
|
REFLECT_TYPECLASS(Enemy, Drop)
|
||||||
REFLECT_TYPECLASS(Enemy, PhysicsEntity);
|
REFLECT_TYPECLASS(Enemy, PhysicsEntity)
|
||||||
REFLECT_TYPECLASS(Enemy, BehaviourEntity);
|
REFLECT_TYPECLASS(Enemy, BehaviourEntity)
|
||||||
REFLECT_TYPECLASS(Enemy, Damagable);
|
REFLECT_TYPECLASS(Enemy, Damagable)
|
||||||
END_REFLECT(Enemy);
|
END_REFLECT(Enemy)
|
||||||
|
|
||||||
impl_Transformable_for(Enemy,
|
impl_Transformable_for(Enemy,
|
||||||
EnemyGetTransform
|
EnemyGetTransform
|
||||||
|
@ -75,9 +75,9 @@ Enemy* MakeEnemy() {
|
||||||
sprite_set_origin(self->sprite, MakeVector(0.45f, 0.925f));
|
sprite_set_origin(self->sprite, MakeVector(0.45f, 0.925f));
|
||||||
|
|
||||||
// load and configure animations
|
// load and configure animations
|
||||||
self->idleAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Idle.png", IVectorFrom(512)), 1.5f, LoopMode_Loop, NULL, 0);
|
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, NULL, 0);
|
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, NULL, 0);
|
self->hurtAnim = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Hurt.png", IVectorFrom(512)), 5.f, LoopMode_Stop);
|
||||||
self->behaviour = state_machine_init(self, EnemyIdle());
|
self->behaviour = state_machine_init(self, EnemyIdle());
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|
|
@ -18,7 +18,7 @@ void Internal_HurtboxDealDamage(const Hurtbox* self, List* colliders, float min_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int HurtboxCast(Hurtbox* self, float facing_dir, List *out) {
|
int HurtboxCast(Hurtbox* self, float facing_dir) {
|
||||||
const IPhysicsEntity* physics_entity = mirror_get_typeclass(self->owner.data, self->owner.mirror, "PhysicsEntity");
|
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");
|
const ITransformable* transformable = mirror_get_typeclass(self->owner.data, self->owner.mirror, "Transformable");
|
||||||
|
|
||||||
|
@ -32,9 +32,5 @@ int HurtboxCast(Hurtbox* self, float facing_dir, List *out) {
|
||||||
const Vector offset = vaddf(transform->position, MakeVector(facing_dir * self->offset.x, self->offset.y));
|
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);
|
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);
|
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;
|
return found.len;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,6 @@ typedef struct Hurtbox {
|
||||||
float depth_extent;
|
float depth_extent;
|
||||||
} Hurtbox;
|
} Hurtbox;
|
||||||
|
|
||||||
extern int HurtboxCast(Hurtbox* self, float facing_dir, List *out);
|
int HurtboxCast(Hurtbox* self, float facing_dir);
|
||||||
|
|
||||||
#endif // !FIGHT_HURTBOX_H
|
#endif // !FIGHT_HURTBOX_H
|
||||||
|
|
|
@ -12,12 +12,12 @@
|
||||||
const Vector PLAYER_SPEED = { 1.0f, 0.50f };
|
const Vector PLAYER_SPEED = { 1.0f, 0.50f };
|
||||||
static const float PLAYER_INPUT_RATE = 1.f/15.f;
|
static const float PLAYER_INPUT_RATE = 1.f/15.f;
|
||||||
|
|
||||||
START_REFLECT(Player);
|
START_REFLECT(Player)
|
||||||
REFLECT_TYPECLASS(Player, Drop);
|
REFLECT_TYPECLASS(Player, Drop)
|
||||||
REFLECT_TYPECLASS(Player, PhysicsEntity);
|
REFLECT_TYPECLASS(Player, PhysicsEntity)
|
||||||
REFLECT_TYPECLASS(Player, BehaviourEntity);
|
REFLECT_TYPECLASS(Player, BehaviourEntity)
|
||||||
REFLECT_TYPECLASS(Player, Transformable);
|
REFLECT_TYPECLASS(Player, Transformable)
|
||||||
END_REFLECT(Player);
|
END_REFLECT(Player)
|
||||||
|
|
||||||
impl_Drop_for(Player,
|
impl_Drop_for(Player,
|
||||||
DestroyPlayer
|
DestroyPlayer
|
||||||
|
@ -93,7 +93,6 @@ Player* MakePlayer() {
|
||||||
.slide = NULL,
|
.slide = NULL,
|
||||||
|
|
||||||
.animationStateMachine = NULL,
|
.animationStateMachine = NULL,
|
||||||
.boxes = malloc(sizeof(Hurtbox) * 3),
|
|
||||||
|
|
||||||
.pushInputTimer = 0.f,
|
.pushInputTimer = 0.f,
|
||||||
.inputLog = list_from_type(PlayerInputFrame),
|
.inputLog = list_from_type(PlayerInputFrame),
|
||||||
|
@ -118,15 +117,15 @@ Player* MakePlayer() {
|
||||||
sprite_set_origin(self->sprite, MakeVector(0.45f, 0.925f));
|
sprite_set_origin(self->sprite, MakeVector(0.45f, 0.925f));
|
||||||
|
|
||||||
// load and configure animations
|
// load and configure animations
|
||||||
self->idle = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Idle.png", IVectorFrom(512)), 1.5f, LoopMode_Loop, NULL, 0);
|
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, NULL, 0);
|
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, NULL, 0);
|
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, NULL, 0);
|
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, NULL, 0);
|
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, NULL, 0);
|
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, NULL, 0);
|
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, NULL, 0);
|
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, NULL, 0);
|
self->slide = animation_sprite_new(self->sprite, spritesheet_load("assets/Player_Slide.png", IVectorFrom(512)), 1.f, LoopMode_Loop);
|
||||||
|
|
||||||
self->animationStateMachine = state_machine_init(self, PlayerIdle());
|
self->animationStateMachine = state_machine_init(self, PlayerIdle());
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef FIGHT_PLAYER_H
|
#ifndef FIGHT_PLAYER_H
|
||||||
#define FIGHT_PLAYER_H
|
#define FIGHT_PLAYER_H
|
||||||
|
|
||||||
#include "Hurtbox.h"
|
|
||||||
#include "dictionary.h"
|
#include "dictionary.h"
|
||||||
#include "state_machine.h"
|
#include "state_machine.h"
|
||||||
#include "mirror.h"
|
#include "mirror.h"
|
||||||
|
@ -57,9 +56,9 @@ typedef struct Player {
|
||||||
AnimationSprite* slide;
|
AnimationSprite* slide;
|
||||||
|
|
||||||
StateMachine* animationStateMachine;
|
StateMachine* animationStateMachine;
|
||||||
Hurtbox *boxes;
|
|
||||||
|
|
||||||
AnimationSprite* currentAnimation;
|
AnimationSprite* currentAnimation;
|
||||||
|
|
||||||
float pushInputTimer;
|
float pushInputTimer;
|
||||||
List inputLog;
|
List inputLog;
|
||||||
PlayerInputFrame nextInputFrame;
|
PlayerInputFrame nextInputFrame;
|
||||||
|
|
|
@ -82,7 +82,7 @@ void PlayerHurtbox(Player* self, DamageEventData damage, Vector hitbox_size, Vec
|
||||||
.offset = vaddf(offset, MakeVector(0.f, self->height)),
|
.offset = vaddf(offset, MakeVector(0.f, self->height)),
|
||||||
.depth_extent = 0.15f,
|
.depth_extent = 0.15f,
|
||||||
};
|
};
|
||||||
HurtboxCast(&box, self->facing, NULL);
|
HurtboxCast(&box, self->facing);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerJabA_Enter(Player* self) {
|
void PlayerJabA_Enter(Player* self) {
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
#include "mirror.h"
|
#include "mirror.h"
|
||||||
#include "physics_world.h"
|
#include "physics_world.h"
|
||||||
|
|
||||||
START_REFLECT(Prop);
|
START_REFLECT(Prop)
|
||||||
REFLECT_TYPECLASS(Prop, Transformable);
|
REFLECT_TYPECLASS(Prop, Transformable)
|
||||||
REFLECT_TYPECLASS(Prop, Drop);
|
REFLECT_TYPECLASS(Prop, Drop)
|
||||||
REFLECT_TYPECLASS(Prop, BehaviourEntity);
|
REFLECT_TYPECLASS(Prop, BehaviourEntity)
|
||||||
END_REFLECT(Prop);
|
END_REFLECT(Prop)
|
||||||
|
|
||||||
impl_Transformable_for(Prop,
|
impl_Transformable_for(Prop,
|
||||||
PropGetTransform
|
PropGetTransform
|
||||||
|
|
Loading…
Reference in a new issue