fp: Draw a shadow on terry/perry

This commit is contained in:
doyle 2023-10-22 17:24:40 +11:00
parent 3d79e8647e
commit e0681e6f70
9 changed files with 111 additions and 19 deletions

BIN
Data/Textures/atlas.png (Stored with Git LFS)

Binary file not shown.

BIN
Data/Textures/atlas.txt (Stored with Git LFS)

Binary file not shown.

BIN
Data/Textures/atlas/shadow_long_circle.png (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

View File

@ -2342,6 +2342,22 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
} }
} }
if (entity->flags & FP_GameEntityFlag_HasShadow) {
TELY_AssetSpriteAnimation *anim = TELY_Asset_GetSpriteAnimation(&game->atlas_sprite_sheet, g_anim_names.shadow_tight_circle);
Dqn_Rect tex_rect = game->atlas_sprite_sheet.rects.data[anim->index];
Dqn_Rect shadow_rect = {};
shadow_rect.size = tex_rect.size * .5f;
shadow_rect.pos = Dqn_V2_InitNx2(world_hit_box.pos.x - (shadow_rect.size.w * .5f) + (shadow_rect.size.w * .2f), world_hit_box.pos.y + world_hit_box.size.h);
TELY_Render_TextureColourV4(renderer,
game->atlas_sprite_sheet.tex_handle,
tex_rect,
shadow_rect,
Dqn_V2_Zero /*rotate origin*/,
0.f /*rotation*/,
TELY_Colour_V4Alpha(TELY_COLOUR_WHITE_V4, .8f));
}
// NOTE: Render entity sprites ============================================================= // NOTE: Render entity sprites =============================================================
if (entity->action.sprite.anim) { if (entity->action.sprite.anim) {
FP_GameEntityAction const *action = &entity->action; FP_GameEntityAction const *action = &entity->action;
@ -2384,7 +2400,7 @@ void FP_Render(FP_Game *game, TELY_Platform *platform, TELY_Renderer *renderer,
Dqn_Rect dest_rect = {}; Dqn_Rect dest_rect = {};
dest_rect.size = src_rect.size * size_scale; dest_rect.size = src_rect.size * size_scale;
dest_rect.pos = world_pos - (dest_rect.size * .5f); dest_rect.pos = world_pos - (dest_rect.size * .5f) + render_data.offset;
if (sprite.flip & TELY_AssetFlip_X) if (sprite.flip & TELY_AssetFlip_X)
dest_rect.size.w *= -1.f; // NOTE: Flip the texture horizontally dest_rect.size.w *= -1.f; // NOTE: Flip the texture horizontally

View File

@ -22,6 +22,8 @@ static Dqn_f32 FP_Entity_CalcSpriteScaleForDesiredHeight(FP_Game *game, FP_Meter
static FP_EntityRenderData FP_Entity_GetRenderData(FP_Game *game, FP_EntityType type, uint32_t raw_state, FP_GameDirection direction) static FP_EntityRenderData FP_Entity_GetRenderData(FP_Game *game, FP_EntityType type, uint32_t raw_state, FP_GameDirection direction)
{ {
FP_EntityRenderData result = {}; FP_EntityRenderData result = {};
result.sheet = &game->atlas_sprite_sheet;
switch (type) { switch (type) {
case FP_EntityType_Nil: { case FP_EntityType_Nil: {
} break; } break;
@ -39,10 +41,43 @@ static FP_EntityRenderData FP_Entity_GetRenderData(FP_Game *game, FP_EntityType
case FP_EntityTerryState_Attack: { case FP_EntityTerryState_Attack: {
switch (direction) { switch (direction) {
case FP_GameDirection_Up: result.anim_name = g_anim_names.terry_attack_up; result.height.meters *= 1.5f; break; case FP_GameDirection_Up: {
case FP_GameDirection_Down: result.anim_name = g_anim_names.terry_attack_down; result.height.meters *= 1.6f; break; result.anim_name = g_anim_names.terry_attack_up;
case FP_GameDirection_Left: result.anim_name = g_anim_names.terry_attack_side; result.height.meters *= 1.5f; break; result.height.meters *= 1.5f;
case FP_GameDirection_Right: result.anim_name = g_anim_names.terry_attack_side; result.height.meters *= 1.5f; result.flip = TELY_AssetFlip_X; break;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .2f);
} break;
case FP_GameDirection_Down: {
result.anim_name = g_anim_names.terry_attack_down;
result.height.meters *= 1.6f;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .2f);
} break;
case FP_GameDirection_Left: {
result.anim_name = g_anim_names.terry_attack_side;
result.height.meters *= 1.5f;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .2f);
} break;
case FP_GameDirection_Right: {
result.anim_name = g_anim_names.terry_attack_side;
result.height.meters *= 1.5f;
result.flip = TELY_AssetFlip_X;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .2f);
} break;
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break; case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
} }
} break; } break;
@ -69,7 +104,13 @@ static FP_EntityRenderData FP_Entity_GetRenderData(FP_Game *game, FP_EntityType
case FP_EntityTerryState_Run: { case FP_EntityTerryState_Run: {
switch (direction) { switch (direction) {
case FP_GameDirection_Up: result.anim_name = g_anim_names.terry_walk_up; break; case FP_GameDirection_Up: {
result.anim_name = g_anim_names.terry_walk_up;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
result.offset = Dqn_V2_InitNx2(tex_rect.size.w * .3f, 0.f);
} break;
case FP_GameDirection_Down: result.anim_name = g_anim_names.terry_walk_down; break; case FP_GameDirection_Down: result.anim_name = g_anim_names.terry_walk_down; break;
case FP_GameDirection_Left: result.anim_name = g_anim_names.terry_walk_left; break; case FP_GameDirection_Left: result.anim_name = g_anim_names.terry_walk_left; break;
case FP_GameDirection_Right: result.anim_name = g_anim_names.terry_walk_right; break; case FP_GameDirection_Right: result.anim_name = g_anim_names.terry_walk_right; break;
@ -93,10 +134,43 @@ static FP_EntityRenderData FP_Entity_GetRenderData(FP_Game *game, FP_EntityType
case FP_EntityTerryState_Attack: { case FP_EntityTerryState_Attack: {
switch (direction) { switch (direction) {
case FP_GameDirection_Up: result.anim_name = g_anim_names.perry_attack_up; result.height.meters *= 1.5f; break; case FP_GameDirection_Up: {
case FP_GameDirection_Down: result.anim_name = g_anim_names.perry_attack_down; result.height.meters *= 1.6f; break; result.anim_name = g_anim_names.perry_attack_up;
case FP_GameDirection_Left: result.anim_name = g_anim_names.perry_attack_side; result.height.meters *= 1.5f; break; result.height.meters *= 1.5f;
case FP_GameDirection_Right: result.anim_name = g_anim_names.perry_attack_side; result.height.meters *= 1.5f; result.flip = TELY_AssetFlip_X; break;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .1f);
} break;
case FP_GameDirection_Down: {
result.anim_name = g_anim_names.perry_attack_down;
result.height.meters *= 1.6f;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .1f);
} break;
case FP_GameDirection_Left: {
result.anim_name = g_anim_names.perry_attack_side;
result.height.meters *= 1.5f;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .1f);
} break;
case FP_GameDirection_Right: {
result.anim_name = g_anim_names.perry_attack_side;
result.height.meters *= 1.5f;
result.flip = TELY_AssetFlip_X;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
Dqn_Rect tex_rect = result.sheet->rects.data[sprite_anim->index];
result.offset = Dqn_V2_InitNx2(0, -tex_rect.size.h * .1f);
} break;
case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break; case FP_GameDirection_Count: DQN_INVALID_CODE_PATH; break;
} }
} break; } break;
@ -332,7 +406,6 @@ static FP_EntityRenderData FP_Entity_GetRenderData(FP_Game *game, FP_EntityType
case FP_EntityType_Count: DQN_INVALID_CODE_PATH; break; case FP_EntityType_Count: DQN_INVALID_CODE_PATH; break;
} }
result.sheet = &game->atlas_sprite_sheet;
TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name); TELY_AssetSpriteAnimation *sprite_anim = TELY_Asset_GetSpriteAnimation(result.sheet, result.anim_name);
if (sprite_anim) { if (sprite_anim) {
result.sheet_rect = result.sheet->rects.data[sprite_anim->index]; result.sheet_rect = result.sheet->rects.data[sprite_anim->index];

View File

@ -148,6 +148,7 @@ struct FP_EntityRenderData
Dqn_Rect sheet_rect; Dqn_Rect sheet_rect;
Dqn_V2 render_size; Dqn_V2 render_size;
TELY_AssetAnimatedSprite sprite; TELY_AssetAnimatedSprite sprite;
Dqn_V2 offset;
}; };
Dqn_usize const FP_TERRY_MOBILE_DATA_PER_RANGE_ATTACK = DQN_KILOBYTES(5); Dqn_usize const FP_TERRY_MOBILE_DATA_PER_RANGE_ATTACK = DQN_KILOBYTES(5);

View File

@ -190,6 +190,7 @@ static FP_GameEntityHandle FP_Entity_CreateTerryInternal(FP_Game *game, Dqn_V2 p
entity->flags |= FP_GameEntityFlag_Attackable; entity->flags |= FP_GameEntityFlag_Attackable;
entity->flags |= FP_GameEntityFlag_CameraTracking; entity->flags |= FP_GameEntityFlag_CameraTracking;
entity->flags |= FP_GameEntityFlag_RecoversHP; entity->flags |= FP_GameEntityFlag_RecoversHP;
entity->flags |= FP_GameEntityFlag_HasShadow;
entity->terry_mobile_data_plan_cap = DQN_KILOBYTES(6); entity->terry_mobile_data_plan_cap = DQN_KILOBYTES(6);
entity->terry_mobile_data_plan = entity->terry_mobile_data_plan_cap; entity->terry_mobile_data_plan = entity->terry_mobile_data_plan_cap;
entity->faction = FP_GameEntityFaction_Friendly; entity->faction = FP_GameEntityFaction_Friendly;

View File

@ -24,6 +24,7 @@ enum FP_GameEntityFlag
FP_GameEntityFlag_Foe = 1 << 16, FP_GameEntityFlag_Foe = 1 << 16,
FP_GameEntityFlag_NoClip = 1 << 17, FP_GameEntityFlag_NoClip = 1 << 17,
FP_GameEntityFlag_RecoversHP = 1 << 18, FP_GameEntityFlag_RecoversHP = 1 << 18,
FP_GameEntityFlag_HasShadow = 1 << 19,
}; };
enum FP_GameShapeType enum FP_GameShapeType