spritesheets: support for predecessors and reversed animations

This commit is contained in:
Sebastian Krzyszkowiak 2018-03-21 02:05:22 +01:00
parent f097ddc54a
commit d88162cab4
2 changed files with 59 additions and 11 deletions

View file

@ -28,6 +28,11 @@
SYMBOL_EXPORT void SelectSpritesheet(struct Game* game, struct Character* character, char* name) { SYMBOL_EXPORT void SelectSpritesheet(struct Game* game, struct Character* character, char* name) {
struct Spritesheet* tmp = character->spritesheets; struct Spritesheet* tmp = character->spritesheets;
bool reversed = false;
if (name[0] == '-') {
reversed = true;
name++;
}
PrintConsole(game, "Selecting spritesheet for %s: %s", character->name, name); PrintConsole(game, "Selecting spritesheet for %s: %s", character->name, name);
if (!tmp) { if (!tmp) {
PrintConsole(game, "ERROR: No spritesheets registered for %s!", character->name); PrintConsole(game, "ERROR: No spritesheets registered for %s!", character->name);
@ -44,9 +49,18 @@ SYMBOL_EXPORT void SelectSpritesheet(struct Game* game, struct Character* charac
} else { } else {
character->successor = NULL; character->successor = NULL;
} }
if (character->predecessor) {
free(character->predecessor);
}
if (tmp->predecessor) {
character->predecessor = strdup(tmp->predecessor);
} else {
character->predecessor = NULL;
}
character->repeats = tmp->repeats; character->repeats = tmp->repeats;
character->reversing = tmp->reversed; character->pos = reversed ? (tmp->frameCount - 1) : 0;
character->pos = 0; character->reversed = reversed;
character->reversing = tmp->reversed ^ reversed;
character->frame = &tmp->frames[character->pos]; character->frame = &tmp->frames[character->pos];
//character->bitmap = tmp->frames[character->pos].bitmap; //character->bitmap = tmp->frames[character->pos].bitmap;
PrintConsole(game, "SUCCESS: Spritesheet for %s activated: %s (%dx%d)", character->name, character->spritesheet->name, character->spritesheet->width, character->spritesheet->height); PrintConsole(game, "SUCCESS: Spritesheet for %s activated: %s (%dx%d)", character->name, character->spritesheet->name, character->spritesheet->width, character->spritesheet->height);
@ -178,6 +192,14 @@ SYMBOL_EXPORT void RegisterSpritesheet(struct Game* game, struct Character* char
strncpy(s->successor, successor, len); strncpy(s->successor, successor, len);
} }
s->predecessor = NULL;
const char* predecessor = al_get_config_value(config, "animation", "predecessor");
if (predecessor) {
int len = strlen(predecessor) + 1;
s->predecessor = malloc(len * sizeof(char));
strncpy(s->predecessor, predecessor, len);
}
{ {
s->file = NULL; s->file = NULL;
const char* file = al_get_config_value(config, "animation", "file"); const char* file = al_get_config_value(config, "animation", "file");
@ -242,6 +264,7 @@ SYMBOL_EXPORT struct Character* CreateCharacter(struct Game* game, char* name) {
character->pos = 0; character->pos = 0;
character->delta = 0.0; character->delta = 0.0;
character->successor = NULL; character->successor = NULL;
character->predecessor = 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);
@ -276,6 +299,9 @@ SYMBOL_EXPORT void DestroyCharacter(struct Game* game, struct Character* charact
if (tmp->successor) { if (tmp->successor) {
free(tmp->successor); free(tmp->successor);
} }
if (tmp->predecessor) {
free(tmp->predecessor);
}
if (tmp->file) { if (tmp->file) {
free(tmp->file); free(tmp->file);
} }
@ -322,15 +348,25 @@ SYMBOL_EXPORT void AnimateCharacter(struct Game* game, struct Character* charact
if (character->spritesheet->bidir) { if (character->spritesheet->bidir) {
character->pos -= 2; character->pos -= 2;
character->reversing = true; character->reversing = true;
if (character->reversed) {
reachedEnd = true;
}
} else { } else {
character->pos = 0; character->pos = 0;
reachedEnd = true; reachedEnd = true;
} }
} }
if (character->pos < 0) { if (character->pos < 0) {
character->pos += 2; if (character->spritesheet->bidir) {
character->reversing = false; character->pos += 2;
reachedEnd = true; character->reversing = false;
if (!character->reversed) {
reachedEnd = true;
}
} else {
character->pos = character->spritesheet->frameCount - 1;
reachedEnd = true;
}
} }
if (character->spritesheet->frameCount == 1) { if (character->spritesheet->frameCount == 1) {
@ -343,11 +379,20 @@ SYMBOL_EXPORT void AnimateCharacter(struct Game* game, struct Character* charact
if (character->callback) { if (character->callback) {
character->callback(game, character, NULL, character->spritesheet->name, character->callbackData); character->callback(game, character, NULL, character->spritesheet->name, character->callbackData);
} }
} else if (character->successor) { } else {
char* old = character->spritesheet->name; if ((!character->reversed) && (character->successor)) {
SelectSpritesheet(game, character, character->successor); char* old = character->spritesheet->name;
if (character->callback) { SelectSpritesheet(game, character, character->successor);
character->callback(game, character, character->spritesheet->name, old, character->callbackData); if (character->callback) {
character->callback(game, character, character->spritesheet->name, old, character->callbackData);
}
}
if ((character->reversed) && (character->predecessor)) {
char* old = character->spritesheet->name;
SelectSpritesheet(game, character, character->predecessor);
if (character->callback) {
character->callback(game, character, character->spritesheet->name, old, character->callbackData);
}
} }
} }
} }

View file

@ -48,6 +48,7 @@ struct Spritesheet {
char* file; char* file;
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. */
char* predecessor;
bool bidir; bool bidir;
bool reversed; bool reversed;
double pivotX; double pivotX;
@ -75,6 +76,7 @@ struct Character {
int pos; /*!< Current spritesheet position. */ int pos; /*!< Current spritesheet position. */
double delta; /*!< 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. */
char* predecessor; /*!< Name of the next spritesheet to be played when the current one finishes when in reverse mode. */
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. */
@ -88,7 +90,8 @@ struct Character {
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. */
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 reversing; /*!< Whether the animation is currently played backwards. */
bool reversed; /*!< Whether the current animation has been requested as reversed. */
bool hidden; bool hidden;
void* data; /*!< Additional, custom character data (HP etc.). */ void* data; /*!< Additional, custom character data (HP etc.). */
void (*callback)(struct Game*, struct Character*, char* newAnim, char* oldAnim, void*); void (*callback)(struct Game*, struct Character*, char* newAnim, char* oldAnim, void*);