character: Add ability to specify a spritesheet's hitbox area

This commit is contained in:
Sebastian Krzyszkowiak 2022-07-17 19:36:56 +02:00
parent 99e49129be
commit 992d827daf
No known key found for this signature in database
GPG key ID: E8F235CF3BDBC3FF
2 changed files with 36 additions and 9 deletions

View file

@ -367,6 +367,11 @@ SYMBOL_EXPORT void RegisterSpritesheet(struct Game* game, struct Character* char
s->offsetX = strtolnull(al_get_config_value(config, "offset", "x"), 0); s->offsetX = strtolnull(al_get_config_value(config, "offset", "x"), 0);
s->offsetY = strtolnull(al_get_config_value(config, "offset", "y"), 0); s->offsetY = strtolnull(al_get_config_value(config, "offset", "y"), 0);
s->hitbox.x1 = strtodnull(al_get_config_value(config, "hitbox", "x1"), 0.0);
s->hitbox.y1 = strtodnull(al_get_config_value(config, "hitbox", "y1"), 0.0);
s->hitbox.x2 = strtodnull(al_get_config_value(config, "hitbox", "x2"), 0.0);
s->hitbox.y2 = strtodnull(al_get_config_value(config, "hitbox", "y2"), 0.0);
s->frames = calloc(s->frame_count, sizeof(struct SpritesheetFrame)); s->frames = calloc(s->frame_count, sizeof(struct SpritesheetFrame));
for (int i = 0; i < s->frame_count; i++) { for (int i = 0; i < s->frame_count; i++) {
@ -385,11 +390,10 @@ SYMBOL_EXPORT void RegisterSpritesheet(struct Game* game, struct Character* char
s->frames[i].flipX = strtolnull(al_get_config_value(config, framename, "flipX"), 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].flipY = strtolnull(al_get_config_value(config, framename, "flipY"), 0);
double r = 0, g = 0, b = 0, a = 0; double r = strtodnull(al_get_config_value(config, framename, "r"), 1.0);
r = strtodnull(al_get_config_value(config, framename, "r"), 1); double g = strtodnull(al_get_config_value(config, framename, "g"), 1.0);
g = strtodnull(al_get_config_value(config, framename, "g"), 1); double b = strtodnull(al_get_config_value(config, framename, "b"), 1.0);
b = strtodnull(al_get_config_value(config, framename, "b"), 1); double a = strtodnull(al_get_config_value(config, framename, "a"), 1.0);
a = strtodnull(al_get_config_value(config, framename, "a"), 1);
s->frames[i].tint = al_premul_rgba_f(r, g, b, a); s->frames[i].tint = al_premul_rgba_f(r, g, b, a);
s->frames[i].file = NULL; s->frames[i].file = NULL;
@ -790,6 +794,10 @@ SYMBOL_EXPORT ALLEGRO_COLOR GetCharacterTint(struct Game* game, struct Character
return al_map_rgba_f(r * r2, g * g2, b * b2, a * a2); return al_map_rgba_f(r * r2, g * g2, b * b2, a * a2);
} }
static bool HasValidHitbox(struct Spritesheet* spritesheet) {
return spritesheet->hitbox.x1 != 0.0 && spritesheet->hitbox.y1 != 0.0 && spritesheet->hitbox.x2 != 0.0 && spritesheet->hitbox.y2 != 0.0;
}
SYMBOL_EXPORT void DrawCharacter(struct Game* game, struct Character* character) { SYMBOL_EXPORT void DrawCharacter(struct Game* game, struct Character* character) {
if (IsCharacterHidden(game, character)) { if (IsCharacterHidden(game, character)) {
return; return;
@ -824,6 +832,12 @@ SYMBOL_EXPORT void DrawDebugCharacter(struct Game* game, struct Character* chara
al_draw_rectangle(0, 0, character->spritesheet->width, character->spritesheet->height, al_map_rgb(0, 255, 255), 5); al_draw_rectangle(0, 0, character->spritesheet->width, character->spritesheet->height, al_map_rgb(0, 255, 255), 5);
if (HasValidHitbox(character->spritesheet)) {
al_draw_rectangle(character->spritesheet->hitbox.x1 * character->spritesheet->width, character->spritesheet->hitbox.y1 * character->spritesheet->height,
character->spritesheet->hitbox.x2 * character->spritesheet->width, character->spritesheet->hitbox.y2 * character->spritesheet->height,
al_map_rgb(255, 255, 0), 3);
}
al_draw_filled_rectangle(character->spritesheet->width * character->spritesheet->pivotX - 5, al_draw_filled_rectangle(character->spritesheet->width * character->spritesheet->pivotX - 5,
character->spritesheet->height * character->spritesheet->pivotY - 5, character->spritesheet->height * character->spritesheet->pivotY - 5,
character->spritesheet->width * character->spritesheet->pivotX + 5, character->spritesheet->width * character->spritesheet->pivotX + 5,
@ -893,6 +907,14 @@ SYMBOL_EXPORT bool IsOnCharacter(struct Game* game, struct Character* character,
float x1 = MIN(0.0, character->spritesheet->offsetX) + MIN(0.0, character->frame->x), y1 = MIN(0.0, character->spritesheet->offsetY) + MIN(0.0, character->frame->y); float x1 = MIN(0.0, character->spritesheet->offsetX) + MIN(0.0, character->frame->x), y1 = MIN(0.0, character->spritesheet->offsetY) + MIN(0.0, character->frame->y);
float x2 = character->spritesheet->width, y2 = character->spritesheet->height; float x2 = character->spritesheet->width, y2 = character->spritesheet->height;
if (HasValidHitbox(character->spritesheet)) {
PrintConsole(game, "valid %f %d", character->spritesheet->hitbox.x1, isnan(character->spritesheet->hitbox.x1));
x1 = character->spritesheet->hitbox.x1 * character->spritesheet->width;
y1 = character->spritesheet->hitbox.y1 * character->spritesheet->height;
x2 = character->spritesheet->hitbox.x2 * character->spritesheet->width;
y2 = character->spritesheet->hitbox.y2 * character->spritesheet->height;
}
ALLEGRO_TRANSFORM transform = GetCharacterTransform(game, character); ALLEGRO_TRANSFORM transform = GetCharacterTransform(game, character);
al_transform_coordinates(&transform, &x1, &y1); al_transform_coordinates(&transform, &x1, &y1);
al_transform_coordinates(&transform, &x2, &y2); al_transform_coordinates(&transform, &x2, &y2);

View file

@ -70,8 +70,8 @@ struct Spritesheet {
char* predecessor; char* predecessor;
bool bidir; bool bidir;
bool reversed; bool reversed;
double pivotX; double pivotX; /*!< Pivot point's X, for scaling and rotating, relative of character's size. */
double pivotY; double pivotY; /*!< Pivot point's Y, for scaling and rotating, relative of character's size. */
int offsetX; int offsetX;
int offsetY; int offsetY;
bool flipX; bool flipX;
@ -83,6 +83,13 @@ struct Spritesheet {
SpritesheetStreamDestructor* stream_destructor; SpritesheetStreamDestructor* stream_destructor;
void* stream_data; void* stream_data;
struct {
double x1;
double y1;
double x2;
double y2;
} hitbox;
int width; int width;
int height; int height;
@ -112,8 +119,6 @@ struct 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. */
bool parent_tint; /*!< When true, the character tint is multiplied by its parent tint. */ bool parent_tint; /*!< When true, the character tint is multiplied by its parent tint. */
//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 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). */