Now have animated torches that are defined from json, and smoother animations in the arena.

This commit is contained in:
Zed A. Shaw 2025-10-21 00:21:46 -04:00
parent 387d1a5bf5
commit 7c11ffa2af
10 changed files with 111 additions and 73 deletions

View file

@ -38,12 +38,12 @@ namespace components {
float tick = twitching(); float tick = twitching();
if(stationary) { if(stationary) {
scale_out.x = std::lerp(scale, max_scale, tick); scale_out.x = std::lerp(scale_x, max_scale, tick);
scale_out.y = std::lerp(scale, max_scale, tick); scale_out.y = std::lerp(scale_y, max_scale, tick);
pos_out.y = pos_out.y - (pos_out.y * scale_out.y - pos_out.y); pos_out.y = pos_out.y - (pos_out.y * scale_out.y - pos_out.y);
} else { } else {
scale_out.x = std::lerp(scale_out.x * scale, scale_out.x * max_scale, tick); scale_out.x = std::lerp(scale_out.x * scale_x, scale_out.x * max_scale, tick);
scale_out.y = std::lerp(scale_out.y * scale, scale_out.y * max_scale, tick); scale_out.y = std::lerp(scale_out.y * scale_y, scale_out.y * max_scale, tick);
} }
if(!simple) { if(!simple) {
@ -51,8 +51,8 @@ namespace components {
} }
subframe += speed; subframe += speed;
current = int(subframe); current = looped ? int(subframe) % frames : int(subframe);
} else if(!looped) { } else if(toggled) {
playing = false; playing = false;
current = frames - 1; current = frames - 1;
subframe = float(frames - 1); subframe = float(frames - 1);
@ -61,8 +61,8 @@ namespace components {
rect_out.position.x += current * frame_width; rect_out.position.x += current * frame_width;
} }
} else { } else {
scale_out.x = scale; scale_out.x = scale_x;
scale_out.y = scale; scale_out.y = scale_y;
playing = false; playing = false;
current = 0; current = 0;
subframe = 0.0f; subframe = 0.0f;
@ -80,7 +80,7 @@ namespace animation {
bool apply(Animation& anim, sf::Sprite& sprite, sf::Vector2f pos) { bool apply(Animation& anim, sf::Sprite& sprite, sf::Vector2f pos) {
sf::IntRect rect{{0,0}, {anim.frame_width, anim.frame_height}}; sf::IntRect rect{{0,0}, {anim.frame_width, anim.frame_height}};
sf::Vector2f scale{anim.scale, anim.scale}; sf::Vector2f scale{anim.scale_x, anim.scale_y};
anim.step(scale, pos, rect); anim.step(scale, pos, rect);

View file

@ -3,154 +3,196 @@
"_type": "Animation", "_type": "Animation",
"easing": 0, "easing": 0,
"ease_rate": 0.5, "ease_rate": 0.5,
"scale": 1.0, "scale_x": 1.0,
"scale_y": 1.0,
"max_scale": 1.0, "max_scale": 1.0,
"simple": false, "simple": false,
"frames": 5, "frames": 5,
"speed": 0.1, "speed": 0.1,
"stationary": false "stationary": false,
"toggled": false,
"looped": false
}, },
"male_hand": { "male_hand": {
"_type": "Animation", "_type": "Animation",
"easing": 0, "easing": 0,
"ease_rate": 0.5, "ease_rate": 0.5,
"scale": 1.0, "scale_x": 1.0,
"scale_y": 1.0,
"max_scale": 1.0, "max_scale": 1.0,
"simple": false, "simple": false,
"frames": 3, "frames": 3,
"speed": 0.08, "speed": 0.08,
"stationary": false "stationary": false,
"toggled": false,
"looped": false
}, },
"female_hand": { "female_hand": {
"_type": "Animation", "_type": "Animation",
"easing": 0, "easing": 0,
"ease_rate": 0.5, "ease_rate": 0.5,
"scale": 1.0, "scale_x": 1.0,
"scale_y": 1.0,
"max_scale": 1.0, "max_scale": 1.0,
"simple": false, "simple": false,
"frames": 3, "frames": 3,
"speed": 0.08, "speed": 0.08,
"stationary": false "stationary": false,
"toggled": false,
"looped": false
}, },
"lightning_animation": { "lightning_animation": {
"_type": "Animation", "_type": "Animation",
"easing": 0, "easing": 0,
"ease_rate": 0.5, "ease_rate": 0.5,
"scale": 1.0, "scale_x": 1.0,
"scale_y": 1.0,
"max_scale": 1.0, "max_scale": 1.0,
"simple": false, "simple": false,
"frames": 5, "frames": 5,
"speed": 0.5, "speed": 0.5,
"stationary": false "stationary": false,
"toggled": false,
"looped": false
}, },
"ritual_crafting_area": { "ritual_crafting_area": {
"_type": "Animation", "_type": "Animation",
"easing": 0, "easing": 0,
"ease_rate": 0.5, "ease_rate": 0.5,
"scale": 1.0, "scale_x": 1.0,
"scale_y": 1.0,
"max_scale": 1.0, "max_scale": 1.0,
"simple": false, "simple": false,
"frames": 3, "frames": 3,
"speed": 0.2, "speed": 0.2,
"stationary": true "stationary": true,
"toggled": true,
"looped": false
}, },
"peasant_girl_rear_view": { "peasant_girl_rear_view": {
"_type": "Animation", "_type": "Animation",
"easing": 3, "easing": 3,
"ease_rate": 0.2, "ease_rate": 0.2,
"scale": 0.5, "scale_x": 0.5,
"scale_y": 0.5,
"max_scale": 0.5, "max_scale": 0.5,
"simple": true, "simple": true,
"frames": 1, "frames": 1,
"speed": 0.03, "speed": 0.03,
"stationary": true "stationary": true,
"toggled": false,
"looped": false
}, },
"gold_savior": { "gold_savior": {
"_type": "Animation", "_type": "Animation",
"easing": 1, "easing": 1,
"ease_rate": 0.2, "ease_rate": 0.2,
"scale": 1.1, "scale_x": 1.1,
"scale_y": 1.1,
"max_scale": 1.2, "max_scale": 1.2,
"simple": true, "simple": true,
"frames": 10, "frames": 10,
"speed": 0.3, "speed": 0.3,
"stationary": false "stationary": false,
"toggled": false,
"looped": false
}, },
"armored_knight" : { "armored_knight" : {
"_type": "Animation", "_type": "Animation",
"easing": 1, "easing": 1,
"ease_rate": 0.2, "ease_rate": 0.2,
"scale": 1.1, "scale_x": 1.1,
"scale_y": 1.1,
"max_scale": 1.2, "max_scale": 1.2,
"simple": true, "simple": true,
"frames": 10, "frames": 10,
"speed": 0.3, "speed": 0.3,
"stationary": false "stationary": false,
"toggled": false,
"looped": false
}, },
"axe_ranger": { "axe_ranger": {
"_type": "Animation", "_type": "Animation",
"easing": 3, "easing": 3,
"ease_rate": 0.5, "ease_rate": 0.5,
"scale": 1.1, "scale_x": 1.1,
"scale_y": 1.1,
"max_scale": 1.2, "max_scale": 1.2,
"simple": true, "simple": true,
"frames": 1, "frames": 1,
"speed": 0.6, "speed": 0.6,
"stationary": false "stationary": false,
"toggled": false,
"looped": false
}, },
"rat_with_sword": { "rat_with_sword": {
"_type": "Animation", "_type": "Animation",
"easing": 3, "easing": 3,
"ease_rate": 0.5, "ease_rate": 0.5,
"scale": 1.0, "scale_x": 1.0,
"scale_y": 1.0,
"max_scale": 0.9, "max_scale": 0.9,
"simple": true, "simple": true,
"frames": 1, "frames": 1,
"speed": 1.0, "speed": 1.0,
"stationary": false "stationary": false,
"toggled": false,
"looped": false
}, },
"hairy_spider": { "hairy_spider": {
"_type": "Animation", "_type": "Animation",
"easing": 2, "easing": 2,
"ease_rate": 0.5, "ease_rate": 0.5,
"scale": 0.9, "scale_x": 0.9,
"scale_y": 0.9,
"max_scale": 1.1, "max_scale": 1.1,
"simple": true, "simple": true,
"frames": 10, "frames": 10,
"speed": 1.0, "speed": 1.0,
"stationary": false "stationary": false,
"toggled": false,
"looped": false
}, },
"test_boss": { "test_boss": {
"_type": "Animation", "_type": "Animation",
"easing": 1, "easing": 1,
"ease_rate": 0.5, "ease_rate": 0.5,
"scale": 0.4, "scale_x": 0.4,
"scale_y": 0.4,
"max_scale": 0.4, "max_scale": 0.4,
"simple": true, "simple": true,
"frames": 1, "frames": 1,
"speed": 0.02, "speed": 0.02,
"stationary": true "stationary": true,
"toggled": false,
"looped": false
}, },
"rat_king_boss": { "rat_king_boss": {
"_type": "Animation", "_type": "Animation",
"easing": 4, "easing": 4,
"ease_rate": 0.9, "ease_rate": 0.9,
"scale": 0.6, "scale_x": 0.6,
"scale_y": 0.6,
"max_scale": 0.7, "max_scale": 0.7,
"simple": false, "simple": false,
"frames": 2, "frames": 2,
"speed": 0.02, "speed": 0.02,
"stationary": true "stationary": true,
"toggled": false,
"looped": false
}, },
"torch_fixture": { "torch_fixture": {
"_type": "Animation", "_type": "Animation",
"easing": 0, "easing": 0,
"ease_rate": 0.5, "ease_rate": 0.5,
"scale": 0.4, "scale_x": 0.5,
"scale_y": 0.5,
"max_scale": 0.4, "max_scale": 0.4,
"simple": true, "simple": false,
"frames": 1, "frames": 3,
"speed": 0.02, "speed": 0.2,
"stationary": true "stationary": true,
"toggled": false,
"looped": true
} }
} }

View file

@ -18,8 +18,8 @@
"sprite": "rat_king_boss" "sprite": "rat_king_boss"
}, },
"fixtures": [ "fixtures": [
{"name": "torch_fixture", "scale_x": 0.5, "scale_y": 0.5, "cell": "torch1", "x": 66, "y": -10}, {"name": "torch_fixture", "scale_x": 0.5, "scale_y": 0.5, "cell": "torch1", "x": 66, "y": -50},
{"name": "torch_fixture", "scale_x": -0.5, "scale_y": 0.5, "cell": "torch2", "x": 130, "y": -10} {"name": "torch_fixture", "scale_x": -0.5, "scale_y": 0.5, "cell": "torch2", "x": 132, "y": -30}
] ]
}, },
{"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false}, {"_type": "Combat", "hp": 20, "max_hp": 20, "damage": 20, "dead": false},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Before After
Before After

View file

@ -128,7 +128,8 @@ namespace boss {
} }
void Fight::render(sf::RenderWindow& window) { void Fight::render(sf::RenderWindow& window) {
$ui.play_animations(window); window.clear();
$ui.play_animations();
$ui.render(window); $ui.render(window);
} }
} }

View file

@ -35,10 +35,14 @@ namespace boss {
auto st = textures::get_sprite(name); auto st = textures::get_sprite(name);
// clone the sprite so it can be positioned // clone the sprite so it can be positioned
st.sprite = std::make_shared<sf::Sprite>(*st.texture); st.sprite = std::make_shared<sf::Sprite>(*st.texture);
auto anim = animation::load(name);
float scale_x = fixture["scale_x"]; float scale_x = fixture["scale_x"];
float scale_y = fixture["scale_y"]; float scale_y = fixture["scale_y"];
auto anim = animation::load(name);
anim.scale_x = scale_x;
anim.scale_y = scale_y;
anim.play();
std::string cell = fixture["cell"]; std::string cell = fixture["cell"];
float x = fixture["x"]; float x = fixture["x"];
float y = fixture["y"]; float y = fixture["y"];
@ -72,6 +76,7 @@ namespace boss {
for(auto& fixture : $fixtures) { for(auto& fixture : $fixtures) {
position_sprite(fixture.st, fixture.cell, position_sprite(fixture.st, fixture.cell,
fixture.scale_x, fixture.scale_y, false, fixture.x, fixture.y); fixture.scale_x, fixture.scale_y, false, fixture.x, fixture.y);
fixture.pos = fixture.st.sprite->getPosition();
} }
$arena.init(); $arena.init();
@ -147,27 +152,14 @@ namespace boss {
position_sprite($player_sprite, cell_name, scale, scale, $scene.player["mid_cell"]); position_sprite($player_sprite, cell_name, scale, scale, $scene.player["mid_cell"]);
} }
void UI::play_animations(sf::RenderWindow& window) { void UI::play_animations() {
if($boss_anim.playing) { for(auto& fixture : $fixtures) {
using namespace std::chrono_literals; if(fixture.anim.playing) {
auto& sound = $world->get<components::Sound>($boss_id); animation::apply(fixture.anim, *fixture.st.sprite, fixture.pos);
animation::apply($boss_anim, *$boss_sprite.sprite, $boss_pos);
if($boss_anim.current == 1 && !sound::playing(sound.attack)) {
sound::play(sound.attack);
} }
}
// https://www.construct.net/en/blogs/ashleys-blog-2/using-lerp-delta-time-924 if($boss_anim.playing) {
// frame start
render(window);
window.display();
// frame end
// deltaTime = end - start
// lerp(a, b, 1 - f ^ deltaTime)
// std::this_thread::sleep_for(16ms);
} else {
animation::apply($boss_anim, *$boss_sprite.sprite, $boss_pos); animation::apply($boss_anim, *$boss_sprite.sprite, $boss_pos);
} }
} }

View file

@ -16,6 +16,7 @@ struct AnimatedFixture {
float x; float x;
float y; float y;
bool at_mid=false; bool at_mid=false;
sf::Vector2f pos{0,0};
}; };
namespace boss { namespace boss {
@ -47,6 +48,6 @@ namespace boss {
void status(const std::wstring& msg); void status(const std::wstring& msg);
void move_boss(const std::string& cell_name); void move_boss(const std::string& cell_name);
void move_player(const std::string& cell_name); void move_player(const std::string& cell_name);
void play_animations(sf::RenderWindow& window); void play_animations();
}; };
} }

View file

@ -117,7 +117,8 @@ namespace components {
}; };
struct Animation { struct Animation {
float scale = 1.0f; float scale_x = 1.0f;
float scale_y = 1.0f;
float max_scale = 1.0f; float max_scale = 1.0f;
bool simple = true; bool simple = true;
int frames = 10; int frames = 10;
@ -125,10 +126,12 @@ namespace components {
ease::Style easing = ease::IN_OUT_BACK; ease::Style easing = ease::IN_OUT_BACK;
float ease_rate = 0.5f; float ease_rate = 0.5f;
bool stationary = false; bool stationary = false;
bool toggled = false;
bool looped = false;
int current = 0; int current = 0;
bool playing = false; bool playing = false;
float subframe = 0.0f; float subframe = 0.0f;
bool looped = false;
// BUG: this is weirdly not used in most animations but also named wrong should be frame_width // BUG: this is weirdly not used in most animations but also named wrong should be frame_width
int frame_width = -1; int frame_width = -1;
int frame_height = -1; int frame_height = -1;
@ -159,8 +162,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, max_scale, simple, frames, ENROLL_COMPONENT(Animation, scale_x, scale_y, max_scale, simple, frames,
speed, easing, ease_rate, stationary); speed, easing, ease_rate, stationary, toggled, looped);
ENROLL_COMPONENT(Sound, attack, death); ENROLL_COMPONENT(Sound, attack, death);
ENROLL_COMPONENT(Collision, has); ENROLL_COMPONENT(Collision, has);

View file

@ -28,10 +28,10 @@ function Build-Images {
# Build-Images -Source "Textures" -pixel_count 12 # Build-Images -Source "Textures" -pixel_count 12
# Build-Images -Source "Sprites" -pixel_count 6 # Build-Images -Source "Sprites" -pixel_count 6
# Build-Images -Source "Items" -pixel_count 2 # Build-Images -Source "Items" -pixel_count 2
# Build-Images -Source "Animations" -pixel_count 6 Build-Images -Source "Animations" -pixel_count 24
# Build-Images -Source "Hands" -pixel_count 6 # Build-Images -Source "Hands" -pixel_count 6
# Build-Images -Source "Boss2" -pixel_count 4 # Build-Images -Source "Boss2" -pixel_count 4
Build-Images -Source "Fixtures" -pixel_count 24 # Build-Images -Source "Fixtures" -pixel_count 24
#magick montage -tile 3x1 -geometry +0+0 -background transparent .\assets\hands\female_hand_*.png .\assets\hands\female_hand.png #magick montage -tile 3x1 -geometry +0+0 -background transparent .\assets\hands\female_hand_*.png .\assets\hands\female_hand.png

View file

@ -36,7 +36,7 @@ int main(int, char*[]) {
gui::routing::Router router; gui::routing::Router router;
sound::mute(true); sound::mute(false);
sound::play("ambient_1", true); sound::play("ambient_1", true);
GameDB::create_level(); GameDB::create_level();
@ -71,7 +71,6 @@ int main(int, char*[]) {
} }
} }
window.clear();
main->render(window); main->render(window);
window.display(); window.display();
} }