mirror of
https://gitlab.com/dosowisko.net/libsuperderpy.git
synced 2025-03-04 17:21:27 +01:00
New spritesheets
This commit is contained in:
parent
e58fbdb560
commit
b31d093e8c
2 changed files with 261 additions and 75 deletions
284
src/character.c
284
src/character.c
|
@ -45,13 +45,11 @@ SYMBOL_EXPORT void SelectSpritesheet(struct Game* game, struct Character* charac
|
||||||
character->successor = NULL;
|
character->successor = NULL;
|
||||||
}
|
}
|
||||||
character->repeats = tmp->repeats;
|
character->repeats = tmp->repeats;
|
||||||
|
character->reversing = tmp->reversed;
|
||||||
character->pos = 0;
|
character->pos = 0;
|
||||||
if (character->bitmap) {
|
character->frame = &tmp->frames[character->pos];
|
||||||
al_reparent_bitmap(character->bitmap, tmp->bitmap, 0, 0, tmp->width / tmp->cols, tmp->height / tmp->rows);
|
//character->bitmap = tmp->frames[character->pos].bitmap;
|
||||||
} else {
|
PrintConsole(game, "SUCCESS: Spritesheet for %s activated: %s (%dx%d)", character->name, character->spritesheet->name, character->spritesheet->width, character->spritesheet->height);
|
||||||
character->bitmap = al_create_sub_bitmap(tmp->bitmap, 0, 0, tmp->width / tmp->cols, tmp->height / tmp->rows);
|
|
||||||
}
|
|
||||||
PrintConsole(game, "SUCCESS: Spritesheet for %s activated: %s (%dx%d)", character->name, character->spritesheet->name, al_get_bitmap_width(character->bitmap), al_get_bitmap_height(character->bitmap));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
|
@ -70,21 +68,47 @@ SYMBOL_EXPORT void LoadSpritesheets(struct Game* game, struct Character* charact
|
||||||
PrintConsole(game, "Loading spritesheets for character %s...", character->name);
|
PrintConsole(game, "Loading spritesheets for character %s...", character->name);
|
||||||
struct Spritesheet* tmp = character->spritesheets;
|
struct Spritesheet* tmp = character->spritesheets;
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if (!tmp->bitmap) {
|
if ((!tmp->bitmap) && (tmp->file)) {
|
||||||
char filename[255] = {0};
|
char filename[255] = {0};
|
||||||
snprintf(filename, 255, "sprites/%s/%s.png", character->name, tmp->name);
|
snprintf(filename, 255, "sprites/%s/%s", character->name, tmp->file);
|
||||||
tmp->bitmap = al_load_bitmap(GetDataFilePath(game, filename));
|
tmp->bitmap = al_load_bitmap(GetDataFilePath(game, filename));
|
||||||
tmp->width = al_get_bitmap_width(tmp->bitmap);
|
tmp->width = al_get_bitmap_width(tmp->bitmap) / tmp->cols;
|
||||||
tmp->height = al_get_bitmap_height(tmp->bitmap);
|
tmp->height = al_get_bitmap_height(tmp->bitmap) / tmp->rows;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < tmp->frameCount; i++) {
|
||||||
|
if ((!tmp->frames[i].bitmap) && (tmp->frames[i].file)) {
|
||||||
|
char filename[255] = {0};
|
||||||
|
snprintf(filename, 255, "sprites/%s/%s", character->name, tmp->frames[i].file);
|
||||||
|
tmp->frames[i].bitmap = al_load_bitmap(GetDataFilePath(game, filename));
|
||||||
|
int width = al_get_bitmap_width(tmp->frames[i].bitmap);
|
||||||
|
if (width > tmp->width) {
|
||||||
|
tmp->width = width;
|
||||||
|
}
|
||||||
|
int height = al_get_bitmap_height(tmp->frames[i].bitmap);
|
||||||
|
if (height > tmp->height) {
|
||||||
|
tmp->height = height;
|
||||||
|
}
|
||||||
|
} else if (!tmp->frames[i].bitmap) {
|
||||||
|
tmp->frames[i].bitmap = al_create_sub_bitmap(tmp->bitmap, tmp->frames[i].col * tmp->width, tmp->frames[i].row * tmp->height, tmp->width, tmp->height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((!character->spritesheet) && (character->spritesheets)) {
|
||||||
|
SelectSpritesheet(game, character, character->spritesheets->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SYMBOL_EXPORT void UnloadSpritesheets(struct Game* game, struct Character* character) {
|
SYMBOL_EXPORT void UnloadSpritesheets(struct Game* game, struct Character* character) {
|
||||||
PrintConsole(game, "Unloading spritesheets for character %s...", character->name);
|
PrintConsole(game, "Unloading spritesheets for character %s...", character->name);
|
||||||
struct Spritesheet* tmp = character->spritesheets;
|
struct Spritesheet* tmp = character->spritesheets;
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
|
for (int i = 0; i < tmp->frameCount; i++) {
|
||||||
|
if (tmp->frames[i].bitmap) {
|
||||||
|
al_destroy_bitmap(tmp->frames[i].bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (tmp->bitmap) {
|
if (tmp->bitmap) {
|
||||||
al_destroy_bitmap(tmp->bitmap);
|
al_destroy_bitmap(tmp->bitmap);
|
||||||
}
|
}
|
||||||
|
@ -93,6 +117,20 @@ SYMBOL_EXPORT void UnloadSpritesheets(struct Game* game, struct Character* chara
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long strtolnull(const char* _nptr, long val) {
|
||||||
|
if (_nptr == NULL) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
return strtol(_nptr, NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double strtodnull(const char* _nptr, double val) {
|
||||||
|
if (_nptr == NULL) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
return strtod(_nptr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
SYMBOL_EXPORT void RegisterSpritesheet(struct Game* game, struct Character* character, char* name) {
|
SYMBOL_EXPORT void RegisterSpritesheet(struct Game* game, struct Character* character, char* name) {
|
||||||
struct Spritesheet* s = character->spritesheets;
|
struct Spritesheet* s = character->spritesheets;
|
||||||
while (s) {
|
while (s) {
|
||||||
|
@ -109,24 +147,86 @@ SYMBOL_EXPORT void RegisterSpritesheet(struct Game* game, struct Character* char
|
||||||
s = malloc(sizeof(struct Spritesheet));
|
s = malloc(sizeof(struct Spritesheet));
|
||||||
s->name = strdup(name);
|
s->name = strdup(name);
|
||||||
s->bitmap = NULL;
|
s->bitmap = NULL;
|
||||||
s->rows = strtol(al_get_config_value(config, "", "rows"), NULL, 10);
|
s->frameCount = strtolnull(al_get_config_value(config, "animation", "frames"), 0);
|
||||||
s->cols = strtol(al_get_config_value(config, "", "cols"), NULL, 10);
|
s->rows = strtolnull(al_get_config_value(config, "animation", "rows"), 0);
|
||||||
s->blanks = strtol(al_get_config_value(config, "", "blanks"), NULL, 10);
|
s->cols = strtolnull(al_get_config_value(config, "animation", "cols"), 0);
|
||||||
s->delay = strtod(al_get_config_value(config, "", "delay"), NULL);
|
s->flipX = strtolnull(al_get_config_value(config, "animation", "flipX"), 0);
|
||||||
|
s->flipY = strtolnull(al_get_config_value(config, "animation", "flipY"), 0);
|
||||||
|
int blanks = strtolnull(al_get_config_value(config, "animation", "blanks"), 0);
|
||||||
|
if (s->frameCount == 0) {
|
||||||
|
s->frameCount = s->rows * s->cols - blanks;
|
||||||
|
} else {
|
||||||
|
s->rows = floor(sqrt(s->frameCount));
|
||||||
|
s->cols = ceil(s->frameCount / s->rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
s->bidir = strtolnull(al_get_config_value(config, "animation", "bidir"), 0);
|
||||||
|
s->reversed = strtolnull(al_get_config_value(config, "animation", "reversed"), 0);
|
||||||
|
|
||||||
|
s->duration = strtodnull(al_get_config_value(config, "animation", "duration"), 16.66);
|
||||||
|
|
||||||
s->width = 0;
|
s->width = 0;
|
||||||
s->height = 0;
|
s->height = 0;
|
||||||
const char* val = al_get_config_value(config, "", "repeats");
|
|
||||||
if (val) {
|
s->repeats = strtolnull(al_get_config_value(config, "animation", "repeats"), 0);
|
||||||
s->repeats = strtod(val, NULL);
|
|
||||||
} else {
|
|
||||||
s->repeats = 0;
|
|
||||||
}
|
|
||||||
s->successor = NULL;
|
s->successor = NULL;
|
||||||
const char* successor = al_get_config_value(config, "", "successor");
|
const char* successor = al_get_config_value(config, "animation", "successor");
|
||||||
if (successor) {
|
if (successor) {
|
||||||
s->successor = malloc(255 * sizeof(char));
|
int len = strlen(successor) + 1;
|
||||||
strncpy(s->successor, successor, 255);
|
s->successor = malloc(len * sizeof(char));
|
||||||
|
strncpy(s->successor, successor, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
s->file = NULL;
|
||||||
|
const char* file = al_get_config_value(config, "animation", "file");
|
||||||
|
if (file) {
|
||||||
|
int len = strlen(file) + 1;
|
||||||
|
s->file = malloc(len * sizeof(char));
|
||||||
|
strncpy(s->file, file, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s->pivotX = strtodnull(al_get_config_value(config, "pivot", "x"), 0.5);
|
||||||
|
s->pivotY = strtodnull(al_get_config_value(config, "pivot", "y"), 0.5);
|
||||||
|
|
||||||
|
s->frames = malloc(sizeof(struct SpritesheetFrame) * s->frameCount);
|
||||||
|
|
||||||
|
for (int i = 0; i < s->frameCount; i++) {
|
||||||
|
char framename[255];
|
||||||
|
snprintf(framename, 255, "frame%d", i);
|
||||||
|
s->frames[i].duration = strtodnull(al_get_config_value(config, framename, "duration"), s->duration);
|
||||||
|
|
||||||
|
s->frames[i].bitmap = NULL;
|
||||||
|
s->frames[i].x = strtolnull(al_get_config_value(config, framename, "x"), 0);
|
||||||
|
s->frames[i].y = strtolnull(al_get_config_value(config, framename, "y"), 0);
|
||||||
|
s->frames[i].flipX = strtolnull(al_get_config_value(config, framename, "flipX"), 0);
|
||||||
|
s->frames[i].flipY = strtolnull(al_get_config_value(config, framename, "flipY"), 0);
|
||||||
|
|
||||||
|
s->frames[i].file = NULL;
|
||||||
|
const char* file = al_get_config_value(config, framename, "file");
|
||||||
|
if (file) {
|
||||||
|
int len = strlen(file) + 1;
|
||||||
|
s->frames[i].file = malloc(len * sizeof(char));
|
||||||
|
strncpy(s->frames[i].file, file, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
s->frames[i].col = i % s->cols;
|
||||||
|
s->frames[i].row = i / s->rows;
|
||||||
|
|
||||||
|
const char* col_str = al_get_config_value(config, filename, "col");
|
||||||
|
if (col_str) {
|
||||||
|
s->frames[i].col = strtol(col_str, NULL, 10);
|
||||||
|
}
|
||||||
|
const char* row_str = al_get_config_value(config, filename, "row");
|
||||||
|
if (row_str) {
|
||||||
|
s->frames[i].row = strtol(row_str, NULL, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s->next = character->spritesheets;
|
s->next = character->spritesheets;
|
||||||
character->spritesheets = s;
|
character->spritesheets = s;
|
||||||
al_destroy_config(config);
|
al_destroy_config(config);
|
||||||
|
@ -136,17 +236,17 @@ SYMBOL_EXPORT struct Character* CreateCharacter(struct Game* game, char* name) {
|
||||||
PrintConsole(game, "Creating character %s...", name);
|
PrintConsole(game, "Creating character %s...", name);
|
||||||
struct Character* character = malloc(sizeof(struct Character));
|
struct Character* character = malloc(sizeof(struct Character));
|
||||||
character->name = strdup(name);
|
character->name = strdup(name);
|
||||||
character->bitmap = NULL;
|
character->frame = NULL;
|
||||||
character->spritesheet = NULL;
|
character->spritesheet = NULL;
|
||||||
character->spritesheets = NULL;
|
character->spritesheets = NULL;
|
||||||
character->pos = 0;
|
character->pos = 0;
|
||||||
character->pos_tmp = 0;
|
character->delta = 0.0;
|
||||||
character->successor = NULL;
|
character->successor = NULL;
|
||||||
character->x = -1;
|
character->x = -1;
|
||||||
character->y = -1;
|
character->y = -1;
|
||||||
character->tint = al_map_rgb(255, 255, 255);
|
character->tint = al_map_rgb(255, 255, 255);
|
||||||
character->pivotX = 0.5;
|
//character->pivotX = 0.5;
|
||||||
character->pivotY = 0.5;
|
//character->pivotY = 0.5;
|
||||||
character->scaleX = 1.0;
|
character->scaleX = 1.0;
|
||||||
character->scaleY = 1.0;
|
character->scaleY = 1.0;
|
||||||
character->angle = 0;
|
character->angle = 0;
|
||||||
|
@ -156,8 +256,12 @@ SYMBOL_EXPORT struct Character* CreateCharacter(struct Game* game, char* name) {
|
||||||
character->flipY = false;
|
character->flipY = false;
|
||||||
character->shared = false;
|
character->shared = false;
|
||||||
character->repeats = 0;
|
character->repeats = 0;
|
||||||
|
character->reversing = false;
|
||||||
character->parent = NULL;
|
character->parent = NULL;
|
||||||
|
character->hidden = false;
|
||||||
character->data = NULL;
|
character->data = NULL;
|
||||||
|
character->callback = NULL;
|
||||||
|
character->callbackData = NULL;
|
||||||
|
|
||||||
return character;
|
return character;
|
||||||
}
|
}
|
||||||
|
@ -169,20 +273,32 @@ SYMBOL_EXPORT void DestroyCharacter(struct Game* game, struct Character* charact
|
||||||
while (s) {
|
while (s) {
|
||||||
tmp = s;
|
tmp = s;
|
||||||
s = s->next;
|
s = s->next;
|
||||||
if (tmp->bitmap) {
|
|
||||||
al_destroy_bitmap(tmp->bitmap);
|
|
||||||
}
|
|
||||||
if (tmp->successor) {
|
if (tmp->successor) {
|
||||||
free(tmp->successor);
|
free(tmp->successor);
|
||||||
}
|
}
|
||||||
|
if (tmp->file) {
|
||||||
|
free(tmp->file);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < tmp->frameCount; i++) {
|
||||||
|
if (tmp->frames[i].bitmap) {
|
||||||
|
al_destroy_bitmap(tmp->frames[i].bitmap);
|
||||||
|
}
|
||||||
|
if (tmp->frames[i].file) {
|
||||||
|
free(tmp->frames[i].file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tmp->bitmap) {
|
||||||
|
al_destroy_bitmap(tmp->bitmap);
|
||||||
|
}
|
||||||
|
free(tmp->frames);
|
||||||
free(tmp->name);
|
free(tmp->name);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (character->bitmap) {
|
//if (character->bitmap) {
|
||||||
al_destroy_bitmap(character->bitmap);
|
// al_destroy_bitmap(character->bitmap);
|
||||||
}
|
//}
|
||||||
if (character->successor) {
|
if (character->successor) {
|
||||||
free(character->successor);
|
free(character->successor);
|
||||||
}
|
}
|
||||||
|
@ -191,26 +307,53 @@ SYMBOL_EXPORT void DestroyCharacter(struct Game* game, struct Character* charact
|
||||||
}
|
}
|
||||||
|
|
||||||
SYMBOL_EXPORT void AnimateCharacter(struct Game* game, struct Character* character, float delta, float speed_modifier) {
|
SYMBOL_EXPORT void AnimateCharacter(struct Game* game, struct Character* character, float delta, float speed_modifier) {
|
||||||
speed_modifier *= delta / (1 / 60.f); // TODO: proper delta handling
|
delta *= speed_modifier;
|
||||||
if (speed_modifier) {
|
character->delta += delta * 1000;
|
||||||
character->pos_tmp++;
|
|
||||||
if (character->pos_tmp >= character->spritesheet->delay / speed_modifier) {
|
while (character->delta >= character->spritesheet->duration) {
|
||||||
character->pos_tmp = 0;
|
bool reachedEnd = false;
|
||||||
|
character->delta -= character->spritesheet->duration;
|
||||||
|
if (character->reversing) {
|
||||||
|
character->pos--;
|
||||||
|
} else {
|
||||||
character->pos++;
|
character->pos++;
|
||||||
}
|
}
|
||||||
if (character->pos >= character->spritesheet->cols * character->spritesheet->rows - character->spritesheet->blanks) {
|
if (character->pos >= character->spritesheet->frameCount) {
|
||||||
character->pos = 0;
|
if (character->spritesheet->bidir) {
|
||||||
if (character->repeats) {
|
character->pos -= 2;
|
||||||
character->repeats--;
|
character->reversing = true;
|
||||||
} else if (character->successor) {
|
} else {
|
||||||
SelectSpritesheet(game, character, character->successor);
|
character->pos = 0;
|
||||||
|
reachedEnd = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (character->pos < 0) {
|
||||||
|
character->pos += 2;
|
||||||
|
character->reversing = false;
|
||||||
|
reachedEnd = true;
|
||||||
|
}
|
||||||
|
|
||||||
al_reparent_bitmap(character->bitmap, character->spritesheet->bitmap,
|
if (character->spritesheet->frameCount == 1) {
|
||||||
(character->pos % character->spritesheet->cols) * (character->spritesheet->width / character->spritesheet->cols), (character->pos / character->spritesheet->cols) * (character->spritesheet->height / character->spritesheet->rows),
|
character->pos = 0;
|
||||||
character->spritesheet->width / character->spritesheet->cols, character->spritesheet->height / character->spritesheet->rows);
|
}
|
||||||
|
|
||||||
|
if (reachedEnd) {
|
||||||
|
if (character->repeats) {
|
||||||
|
character->repeats--;
|
||||||
|
if (character->callback) {
|
||||||
|
character->callback(game, character, NULL, character->spritesheet->name, character->callbackData);
|
||||||
|
}
|
||||||
|
} else if (character->successor) {
|
||||||
|
char* old = character->spritesheet->name;
|
||||||
|
SelectSpritesheet(game, character, character->successor);
|
||||||
|
if (character->callback) {
|
||||||
|
character->callback(game, character, character->spritesheet->name, old, character->callbackData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
character->frame = &character->spritesheet->frames[character->pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
SYMBOL_EXPORT void MoveCharacter(struct Game* game, struct Character* character, float x, float y, float angle) {
|
SYMBOL_EXPORT void MoveCharacter(struct Game* game, struct Character* character, float x, float y, float angle) {
|
||||||
|
@ -233,19 +376,28 @@ SYMBOL_EXPORT void SetCharacterPosition(struct Game* game, struct Character* cha
|
||||||
SetCharacterPositionF(game, character, x / (float)GetCharacterConfineX(game, character), y / (float)GetCharacterConfineY(game, character), angle);
|
SetCharacterPositionF(game, character, x / (float)GetCharacterConfineX(game, character), y / (float)GetCharacterConfineY(game, character), angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
SYMBOL_EXPORT void SetCharacterPivotPoint(struct Game* game, struct Character* character, float x, float y) {
|
|
||||||
character->pivotX = x;
|
|
||||||
character->pivotY = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: coords are centered (pivot-related) or top left?
|
|
||||||
SYMBOL_EXPORT void DrawCharacter(struct Game* game, struct Character* character) {
|
SYMBOL_EXPORT void DrawCharacter(struct Game* game, struct Character* character) {
|
||||||
int w = al_get_bitmap_width(character->bitmap), h = al_get_bitmap_height(character->bitmap);
|
if (character->hidden) {
|
||||||
al_draw_tinted_scaled_rotated_bitmap(character->bitmap, character->tint,
|
return;
|
||||||
w * character->pivotX, h * character->pivotY,
|
}
|
||||||
GetCharacterX(game, character) + w * character->pivotX, GetCharacterY(game, character) + h * character->pivotY,
|
int w = character->spritesheet->width, h = character->spritesheet->height;
|
||||||
character->scaleX, character->scaleY, character->angle,
|
|
||||||
(character->flipX ? ALLEGRO_FLIP_HORIZONTAL : 0) | (character->flipY ? ALLEGRO_FLIP_VERTICAL : 0));
|
ALLEGRO_TRANSFORM current = *al_get_current_transform();
|
||||||
|
ALLEGRO_TRANSFORM transform;
|
||||||
|
// TODO: move to function, use in IsOnCharacter etc.
|
||||||
|
al_identity_transform(&transform);
|
||||||
|
al_scale_transform(&transform, ((character->flipX ^ character->spritesheet->flipX ^ character->frame->flipX) ? -1 : 1), ((character->flipY ^ character->spritesheet->flipY ^ character->frame->flipY) ? -1 : 1)); // flipping; FIXME: should it be here or later?
|
||||||
|
al_translate_transform(&transform, character->spritesheet->frames[character->pos].x, character->spritesheet->frames[character->pos].y); // spritesheet frame offset
|
||||||
|
al_translate_transform(&transform, -w * character->spritesheet->pivotX, -h * character->spritesheet->pivotY); // pivot
|
||||||
|
al_scale_transform(&transform, character->scaleX, character->scaleY);
|
||||||
|
al_rotate_transform(&transform, character->angle);
|
||||||
|
|
||||||
|
al_compose_transform(&transform, ¤t);
|
||||||
|
al_use_transform(&transform);
|
||||||
|
|
||||||
|
al_draw_tinted_bitmap(character->frame->bitmap, character->tint, GetCharacterX(game, character), GetCharacterY(game, character), 0);
|
||||||
|
|
||||||
|
al_use_transform(¤t);
|
||||||
}
|
}
|
||||||
|
|
||||||
SYMBOL_EXPORT void SetCharacterConfines(struct Game* game, struct Character* character, int x, int y) {
|
SYMBOL_EXPORT void SetCharacterConfines(struct Game* game, struct Character* character, int x, int y) {
|
||||||
|
@ -281,8 +433,11 @@ static void SortTwoFloats(float* v1, float* v2) {
|
||||||
|
|
||||||
SYMBOL_EXPORT bool IsOnCharacter(struct Game* game, struct Character* character, float x, float y, bool pixelperfect) {
|
SYMBOL_EXPORT bool IsOnCharacter(struct Game* game, struct Character* character, float x, float y, bool pixelperfect) {
|
||||||
// TODO: fucking rework
|
// TODO: fucking rework
|
||||||
|
if (character->hidden) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int w = al_get_bitmap_width(character->bitmap), h = al_get_bitmap_height(character->bitmap);
|
int w = character->spritesheet->width, h = character->spritesheet->height;
|
||||||
float x1 = GetCharacterX(game, character), y1 = GetCharacterY(game, character);
|
float x1 = GetCharacterX(game, character), y1 = GetCharacterY(game, character);
|
||||||
float x2 = x1 + w, y2 = y1 + h;
|
float x2 = x1 + w, y2 = y1 + h;
|
||||||
|
|
||||||
|
@ -311,9 +466,16 @@ SYMBOL_EXPORT bool IsOnCharacter(struct Game* game, struct Character* character,
|
||||||
if (test && pixelperfect) {
|
if (test && pixelperfect) {
|
||||||
x -= x1;
|
x -= x1;
|
||||||
y -= y1;
|
y -= y1;
|
||||||
ALLEGRO_COLOR color = al_get_pixel(character->bitmap, x, y);
|
ALLEGRO_COLOR color = al_get_pixel(character->frame->bitmap, x, y);
|
||||||
return (color.a > 0.0);
|
return (color.a > 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShowCharacter(struct Game* game, struct Character* character) {
|
||||||
|
character->hidden = false;
|
||||||
|
}
|
||||||
|
void HideCharacter(struct Game* game, struct Character* character) {
|
||||||
|
character->hidden = true;
|
||||||
|
}
|
||||||
|
|
|
@ -25,22 +25,41 @@
|
||||||
#include <allegro5/allegro.h>
|
#include <allegro5/allegro.h>
|
||||||
#include <allegro5/allegro_font.h>
|
#include <allegro5/allegro_font.h>
|
||||||
|
|
||||||
|
struct SpritesheetFrame {
|
||||||
|
char* file;
|
||||||
|
ALLEGRO_BITMAP* bitmap;
|
||||||
|
double duration;
|
||||||
|
int row;
|
||||||
|
int col;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
bool flipX;
|
||||||
|
bool flipY;
|
||||||
|
};
|
||||||
|
|
||||||
/*! \brief Structure representing one spritesheet for character animation. */
|
/*! \brief Structure representing one spritesheet for character animation. */
|
||||||
struct Spritesheet {
|
struct Spritesheet {
|
||||||
char* name; /*!< Name of the spritesheet (used in file paths). */
|
char* name; /*!< Name of the spritesheet (used in file paths). */
|
||||||
ALLEGRO_BITMAP* bitmap; /*!< Spritesheet bitmap. */
|
ALLEGRO_BITMAP* bitmap; /*!< Spritesheet bitmap. */
|
||||||
// TODO: bitmap file
|
int frameCount;
|
||||||
int rows; /*!< Number of rows in the spritesheet. */
|
int rows; /*!< Number of rows in the spritesheet. */
|
||||||
int cols; /*!< Number of columns in the spritesheet. */
|
int cols; /*!< Number of columns in the spritesheet. */
|
||||||
int blanks; /*!< Number of blank frames at the end of the spritesheet. */
|
double duration;
|
||||||
int width;
|
char* file;
|
||||||
int height;
|
|
||||||
int delay;
|
|
||||||
int repeats; /*!< Number of repeats to make before the spritesheet is changed to its successor. */
|
int repeats; /*!< Number of repeats to make before the spritesheet is changed to its successor. */
|
||||||
char* successor; /*!< Name of animation successor. If it's not blank, then animation will be played only once. */
|
char* successor; /*!< Name of animation successor. If it's not blank, then animation will be played only once. */
|
||||||
|
bool bidir;
|
||||||
|
bool reversed;
|
||||||
|
double pivotX;
|
||||||
|
double pivotY;
|
||||||
|
bool flipX;
|
||||||
|
bool flipY;
|
||||||
|
struct SpritesheetFrame* frames;
|
||||||
|
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
struct Spritesheet* next; /*!< Next spritesheet in the queue. */
|
struct Spritesheet* next; /*!< Next spritesheet in the queue. */
|
||||||
// TODO: loopmode
|
|
||||||
// TODO: playmode
|
|
||||||
|
|
||||||
// TODO: missing docs
|
// TODO: missing docs
|
||||||
};
|
};
|
||||||
|
@ -49,17 +68,18 @@ struct Spritesheet {
|
||||||
struct Character {
|
struct Character {
|
||||||
char* name; /*!< Name of the character (used in file paths). */
|
char* name; /*!< Name of the character (used in file paths). */
|
||||||
struct Character* parent; /*!< Parent character. NULL is no parent. */
|
struct Character* parent; /*!< Parent character. NULL is no parent. */
|
||||||
ALLEGRO_BITMAP* bitmap; /*!< Subbitmap with character's current frame. */
|
//ALLEGRO_BITMAP* bitmap; /*!< Subbitmap with character's current frame. */
|
||||||
|
struct SpritesheetFrame* frame; /*!< Current frame. */
|
||||||
struct Spritesheet* spritesheet; /*!< Current spritesheet used by character. */
|
struct Spritesheet* spritesheet; /*!< Current spritesheet used by character. */
|
||||||
struct Spritesheet* spritesheets; /*!< List of all spritesheets registered to character. */
|
struct Spritesheet* spritesheets; /*!< List of all spritesheets registered to character. */
|
||||||
int pos; /*!< Current spritesheet position. */
|
int pos; /*!< Current spritesheet position. */
|
||||||
int pos_tmp; /*!< A counter used internally to slow down spritesheet animation. */ // TODO: change to delta
|
double delta; /*!< A counter used internally to slow down spritesheet animation. */ // TODO: change to delta
|
||||||
char* successor; /*!< Name of the next spritesheet to be played when the current one finishes. */
|
char* successor; /*!< Name of the next spritesheet to be played when the current one finishes. */
|
||||||
float x; /*!< Horizontal position of character. */
|
float x; /*!< Horizontal position of character. */
|
||||||
float y; /*!< Vertical position of character. */
|
float y; /*!< Vertical position of character. */
|
||||||
ALLEGRO_COLOR tint; /*!< Color with which the character's pixels will be multiplied (tinted). White for no effect. */
|
ALLEGRO_COLOR tint; /*!< Color with which the character's pixels will be multiplied (tinted). White for no effect. */
|
||||||
float pivotX; /*!< Pivot point's X, for scaling and rotating, relative of character's size. */
|
//float pivotX; /*!< Pivot point's X, for scaling and rotating, relative of character's size. */
|
||||||
float pivotY; /*!< Pivot point's Y, for scaling and rotating, relative of character's size. */
|
//float pivotY; /*!< Pivot point's Y, for scaling and rotating, relative of character's size. */
|
||||||
float scaleX; /*!< Scale factor for X axis. */
|
float scaleX; /*!< Scale factor for X axis. */
|
||||||
float scaleY; /*!< Scale factor for Y axis. */
|
float scaleY; /*!< Scale factor for Y axis. */
|
||||||
float angle; /*!< Character's rotation angle (radians). */
|
float angle; /*!< Character's rotation angle (radians). */
|
||||||
|
@ -67,11 +87,13 @@ struct Character {
|
||||||
int confineY; /*!< Height of the canvas being drawn to, for correct position calculation; when -1, uses parent's confines or viewport size */
|
int confineY; /*!< Height of the canvas being drawn to, for correct position calculation; when -1, uses parent's confines or viewport size */
|
||||||
bool flipX; /*!< Flips the character's sprite vertically. */
|
bool flipX; /*!< Flips the character's sprite vertically. */
|
||||||
bool flipY; /*!< Flips the character's sprite horizontally. */
|
bool flipY; /*!< Flips the character's sprite horizontally. */
|
||||||
bool shared; /*!< Marks the list of spritesheets as shared, so it won't be freed together with the character. */
|
|
||||||
int repeats; /*!< Number of repeats left before the spritesheet is changed to its successor. */
|
int repeats; /*!< Number of repeats left before the spritesheet is changed to its successor. */
|
||||||
|
bool reversing;
|
||||||
|
bool hidden;
|
||||||
void* data; /*!< Additional, custom character data (HP etc.). */
|
void* data; /*!< Additional, custom character data (HP etc.). */
|
||||||
// TODO: add a callback for when the animation finishes
|
void (*callback)(struct Game*, struct Character*, char* newAnim, char* oldAnim, void*);
|
||||||
// TODO: playmode
|
void* callbackData;
|
||||||
|
bool shared; /*!< Marks the list of spritesheets as shared, so it won't be freed together with the character. */
|
||||||
|
|
||||||
// TODO: parents
|
// TODO: parents
|
||||||
};
|
};
|
||||||
|
@ -106,5 +128,7 @@ int GetCharacterConfineX(struct Game* game, struct Character* character);
|
||||||
int GetCharacterConfineY(struct Game* game, struct Character* character);
|
int GetCharacterConfineY(struct Game* game, struct Character* character);
|
||||||
|
|
||||||
bool IsOnCharacter(struct Game* game, struct Character* character, float x, float y, bool pixelperfect);
|
bool IsOnCharacter(struct Game* game, struct Character* character, float x, float y, bool pixelperfect);
|
||||||
|
void ShowCharacter(struct Game* game, struct Character* character);
|
||||||
|
void HideCharacter(struct Game* game, struct Character* character);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue