Animations now can have a stationary option which tries to keep them 'in place' while growing, effectively removing the forward motion.

master
Zed A. Shaw 5 days ago
parent eb8fb82837
commit 8b414c13e6
  1. 14
      assets/bosses.json
  2. BIN
      assets/devils_fingers_sprite.png
  3. 8
      assets/enemies.json
  4. 10
      boss_fight_ui.cpp
  5. 1
      boss_fight_ui.hpp
  6. 6
      components.cpp
  7. 10
      components.hpp
  8. 2
      raycaster.cpp

@ -3,8 +3,8 @@
"components": [ "components": [
{"_type": "BossFight", "background": "boss_fight_background", "weapon_sound": "Sword_Hit_2"}, {"_type": "BossFight", "background": "boss_fight_background", "weapon_sound": "Sword_Hit_2"},
{"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false}, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false},
{"_type": "Animation", "easing": 3, "ease_rate": 0.2, "scale": 0.2, "simple": false, "frames": 2, "speed": 0.02, "scale": 0.2}, {"_type": "Animation", "easing": 3, "ease_rate": 0.2, "simple": false, "frames": 2, "speed": 0.02, "scale": 0.2},
{"_type": "Sprite", "name": "rat_king_boss", "width": 720, "height": 720, "scale": 0.8}, {"_type": "Sprite", "name": "rat_king_boss", "width": 720, "height": 720, "scale": 0.8, "stationary": false},
{"_type": "Sound", "attack": "Marmot_Scream_1", "death": "Creature_Death_1"} {"_type": "Sound", "attack": "Marmot_Scream_1", "death": "Creature_Death_1"}
] ]
}, },
@ -15,7 +15,15 @@
"weapon_sound": "Sword_Hit_2" "weapon_sound": "Sword_Hit_2"
}, },
{"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false}, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false},
{"_type": "Animation", "easing": 0, "ease_rate": 0.1, "scale": 0.2, "simple": true, "frames": 2, "speed": 0.02, "scale": 0.2}, {"_type": "Animation",
"easing": 1,
"ease_rate": 0.1,
"simple": false,
"frames": 2,
"speed": 0.02,
"scale": 0.1,
"stationary": true
},
{"_type": "Sprite", {"_type": "Sprite",
"name": "devils_fingers_sprite", "name": "devils_fingers_sprite",
"width": 720, "width": 720,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 KiB

After

Width:  |  Height:  |  Size: 665 KiB

@ -20,7 +20,7 @@
{"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 1, "dead": false}, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 1, "dead": false},
{"_type": "Motion", "dx": 0, "dy": 0, "random": false}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false},
{"_type": "EnemyConfig", "hearing_distance": 5}, {"_type": "EnemyConfig", "hearing_distance": 5},
{"_type": "Animation", "easing": 1, "ease_rate": 0.2, "scale": 0.1, "simple": true, "frames": 10, "speed": 0.3}, {"_type": "Animation", "easing": 1, "ease_rate": 0.2, "scale": 0.1, "simple": true, "frames": 10, "speed": 0.3, "stationary": false},
{"_type": "Sprite", "name": "armored_knight", "width": 256, "height": 256, "width": 256, "height": 256, "scale": 1.0}, {"_type": "Sprite", "name": "armored_knight", "width": 256, "height": 256, "width": 256, "height": 256, "scale": 1.0},
{"_type": "Sound", "attack": "Sword_Hit_2", "death": "Humanoid_Death_1"} {"_type": "Sound", "attack": "Sword_Hit_2", "death": "Humanoid_Death_1"}
] ]
@ -35,7 +35,7 @@
{"_type": "Motion", "dx": 0, "dy": 0, "random": true}, {"_type": "Motion", "dx": 0, "dy": 0, "random": true},
{"_type": "EnemyConfig", "hearing_distance": 5}, {"_type": "EnemyConfig", "hearing_distance": 5},
{"_type": "Sprite", "name": "axe_ranger", "width": 256, "height": 256, "scale": 1.0}, {"_type": "Sprite", "name": "axe_ranger", "width": 256, "height": 256, "scale": 1.0},
{"_type": "Animation", "easing": 3, "ease_rate": 0.5, "scale": 0.1, "simple": false, "frames": 2, "speed": 0.6}, {"_type": "Animation", "easing": 3, "ease_rate": 0.5, "scale": 0.1, "simple": false, "frames": 2, "speed": 0.6, "stationary": false},
{"_type": "Sound", "attack": "Sword_Hit_2", "death": "Ranger_1"} {"_type": "Sound", "attack": "Sword_Hit_2", "death": "Ranger_1"}
] ]
}, },
@ -48,7 +48,7 @@
{"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false}, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false},
{"_type": "Motion", "dx": 0, "dy": 0, "random": false}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false},
{"_type": "EnemyConfig", "hearing_distance": 10}, {"_type": "EnemyConfig", "hearing_distance": 10},
{"_type": "Animation", "easing": 3, "ease_rate": 0.5, "scale": 0.1, "simple": true, "frames": 10, "speed": 1.0}, {"_type": "Animation", "easing": 3, "ease_rate": 0.5, "scale": 0.1, "simple": true, "frames": 10, "speed": 1.0, "stationary": false},
{"_type": "Sprite", "name": "rat_with_sword", "width": 256, "height": 256, "scale": 1.0}, {"_type": "Sprite", "name": "rat_with_sword", "width": 256, "height": 256, "scale": 1.0},
{"_type": "Sound", "attack": "Small_Rat", "death": "Creature_Death_1"} {"_type": "Sound", "attack": "Small_Rat", "death": "Creature_Death_1"}
] ]
@ -62,7 +62,7 @@
{"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false}, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false},
{"_type": "Motion", "dx": 0, "dy": 0, "random": false}, {"_type": "Motion", "dx": 0, "dy": 0, "random": false},
{"_type": "EnemyConfig", "hearing_distance": 10}, {"_type": "EnemyConfig", "hearing_distance": 10},
{"_type": "Animation", "easing": 2, "ease_rate": 0.5, "scale": 0.1, "simple": true, "frames": 10, "speed": 1.0}, {"_type": "Animation", "easing": 2, "ease_rate": 0.5, "scale": 0.1, "simple": true, "frames": 10, "speed": 1.0, "stationary": false},
{"_type": "Sprite", "name": "hairy_spider", "width": 256, "height": 256, "scale": 1.0}, {"_type": "Sprite", "name": "hairy_spider", "width": 256, "height": 256, "scale": 1.0},
{"_type": "Sound", "attack": "Spider_1", "death": "Spider_2"} {"_type": "Sound", "attack": "Spider_1", "death": "Spider_2"}
] ]

@ -42,8 +42,10 @@ namespace gui {
auto bounds = $boss_image.sprite->getLocalBounds(); auto bounds = $boss_image.sprite->getLocalBounds();
auto bg_bounds = $boss_background.sprite->getLocalBounds(); auto bg_bounds = $boss_background.sprite->getLocalBounds();
float x_diff = bg_bounds.size.x / 2; float x_diff = bg_bounds.size.x / 2;
$boss_pos = {float(BOSS_VIEW_X) + x_diff, bounds.size.y / 2};
$boss_image.sprite->setOrigin({bounds.size.x / 2, bounds.size.y / 2}); $boss_image.sprite->setOrigin({bounds.size.x / 2, bounds.size.y / 2});
$boss_image.sprite->setPosition({float(BOSS_VIEW_X) + x_diff, bounds.size.y / 2}); $boss_image.sprite->setPosition($boss_pos);
} }
void BossFightUI::configure_background() { void BossFightUI::configure_background() {
@ -88,9 +90,13 @@ namespace gui {
void BossFightUI::bounce_boss(sf::RenderWindow& window) { void BossFightUI::bounce_boss(sf::RenderWindow& window) {
sf::IntRect frame_rect{{0,0},{$sprite_config.width,$sprite_config.height}}; sf::IntRect frame_rect{{0,0},{$sprite_config.width,$sprite_config.height}};
sf::Vector2f scale{$sprite_config.scale, $sprite_config.scale}; sf::Vector2f scale{$sprite_config.scale, $sprite_config.scale};
$animation.step(scale, frame_rect); sf::Vector2f pos{$boss_pos.x, $boss_pos.y};
$animation.step(scale, pos, frame_rect);
$boss_image.sprite->setScale(scale); $boss_image.sprite->setScale(scale);
if($animation.stationary) $boss_image.sprite->setPosition(pos);
if(!sound::playing($sounds.attack) && $animation.current == 1) { if(!sound::playing($sounds.attack) && $animation.current == 1) {
sound::play($sounds.attack); sound::play($sounds.attack);
} }

@ -19,6 +19,7 @@ namespace gui {
public: public:
sf::Clock $clock; sf::Clock $clock;
bool $boss_hit = false; bool $boss_hit = false;
sf::Vector2f $boss_pos;
components::Combat $combat; components::Combat $combat;
components::Sprite $sprite_config; components::Sprite $sprite_config;
components::Sound $sounds; components::Sound $sounds;

@ -54,12 +54,16 @@ namespace components {
} }
} }
void Animation::step(sf::Vector2f& scale_out, sf::IntRect& rect_out) { void Animation::step(sf::Vector2f& scale_out, sf::Vector2f& pos_out, sf::IntRect& rect_out) {
if(playing && current < frames) { if(playing && current < frames) {
float tick = twitching(); float tick = twitching();
scale_out.x = std::lerp(scale_out.x, scale_out.x + scale, tick); scale_out.x = std::lerp(scale_out.x, scale_out.x + scale, tick);
scale_out.y = std::lerp(scale_out.y, scale_out.y + scale, tick); scale_out.y = std::lerp(scale_out.y, scale_out.y + scale, tick);
if(stationary) {
pos_out.y = pos_out.y - (pos_out.y * scale_out.y - pos_out.y);
}
if(!simple) { if(!simple) {
rect_out.position.x += current * texture_width; rect_out.position.x += current * texture_width;
} }

@ -112,16 +112,17 @@ namespace components {
bool simple = true; bool simple = true;
int frames = 10; int frames = 10;
float speed = 0.3f; float speed = 0.3f;
ease::Style easing = ease::IN_OUT_BACK;
float ease_rate = 0.5f;
bool stationary = false;
int current = 0; int current = 0;
bool playing = false; bool playing = false;
float subframe = 0; float subframe = 0;
ease::Style easing = ease::IN_OUT_BACK;
float ease_rate = 0.5f;
int texture_width = TEXTURE_WIDTH; int texture_width = TEXTURE_WIDTH;
void play(); void play();
float twitching(); float twitching();
void step(sf::Vector2f& scale_out, sf::IntRect& rect_out); void step(sf::Vector2f& scale_out, sf::Vector2f& pos_out, sf::IntRect& rect_out);
}; };
template <typename T> struct NameOf; template <typename T> struct NameOf;
@ -138,7 +139,8 @@ namespace components {
ENROLL_COMPONENT(Motion, dx, dy, random); ENROLL_COMPONENT(Motion, dx, dy, random);
ENROLL_COMPONENT(Combat, hp, max_hp, damage, dead); ENROLL_COMPONENT(Combat, hp, max_hp, damage, dead);
ENROLL_COMPONENT(Device, config, events); ENROLL_COMPONENT(Device, config, events);
ENROLL_COMPONENT(Animation, scale, simple, frames, speed, easing, ease_rate); ENROLL_COMPONENT(Animation, scale, simple, frames,
speed, easing, ease_rate, stationary);
ENROLL_COMPONENT(Sound, attack, death); ENROLL_COMPONENT(Sound, attack, death);
using ReflFuncSignature = std::function<void(DinkyECS::World& world, DinkyECS::Entity ent, nlohmann::json &j)>; using ReflFuncSignature = std::function<void(DinkyECS::World& world, DinkyECS::Entity ent, nlohmann::json &j)>;

@ -158,7 +158,7 @@ void Raycaster::sprite_casting(sf::RenderTarget &target) {
if($level.world->has<components::Animation>(rec.second)) { if($level.world->has<components::Animation>(rec.second)) {
auto& animation = $level.world->get<components::Animation>(rec.second); auto& animation = $level.world->get<components::Animation>(rec.second);
if(animation.playing) animation.step(scale, in_texture); if(animation.playing) animation.step(scale, position, in_texture);
} }
sf_sprite->setOrigin(origin); sf_sprite->setOrigin(origin);

Loading…
Cancel
Save