Improved start screen and made the animation optional in scenes since they aren't needed always.
This commit is contained in:
parent
903fad871f
commit
532366091b
13 changed files with 114 additions and 27 deletions
|
|
@ -97,6 +97,39 @@
|
|||
"open": [],
|
||||
"close": []
|
||||
}
|
||||
},
|
||||
"ag_bot": {
|
||||
"sheet": {
|
||||
"frames": 1,
|
||||
"frame_width": 846,
|
||||
"frame_height": 1022
|
||||
},
|
||||
"sequences": {
|
||||
"idle": {"frames": [0], "durations": [50] }
|
||||
},
|
||||
"transforms": {
|
||||
"basic": {
|
||||
"min_x": 1.0,
|
||||
"min_y": 1.0,
|
||||
"max_x": 1.0,
|
||||
"max_y": 1.0,
|
||||
"flipped": false,
|
||||
"scaled": true,
|
||||
"toggled": false,
|
||||
"looped": false,
|
||||
"relative": false,
|
||||
"easing": "none",
|
||||
"motion": "move_none"
|
||||
}
|
||||
},
|
||||
"forms": {
|
||||
"idle": ["idle", "basic"]
|
||||
},
|
||||
"sounds": {
|
||||
"idle": [],
|
||||
"open": [],
|
||||
"close": []
|
||||
}
|
||||
},
|
||||
"hands_sword_attack": {
|
||||
"sheet": {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,16 @@
|
|||
"frame_width": 256,
|
||||
"frame_height": 256
|
||||
},
|
||||
"ag_bot":
|
||||
{"path": "assets/sprites/ag_bot.png",
|
||||
"frame_width": 846,
|
||||
"frame_height": 1022
|
||||
},
|
||||
"ag_bot_speech":
|
||||
{"path": "assets/sprites/ag_bot_speech.png",
|
||||
"frame_width": 424,
|
||||
"frame_height": 358
|
||||
},
|
||||
"repair_kit":
|
||||
{"path": "assets/items/repair_kit.png",
|
||||
"frame_width": 256,
|
||||
|
|
|
|||
|
|
@ -21,12 +21,36 @@
|
|||
},
|
||||
"STARTING": {
|
||||
"layout": [
|
||||
"[=text]"
|
||||
"[_|*%(200, 200)ag_bot|_|*%(200,100)speech|_|_]",
|
||||
"[_|_|_ |*%(200,100)buttons|_|_]"
|
||||
],
|
||||
"background": "starting_scene",
|
||||
"actors": [
|
||||
{
|
||||
"name": "ag_bot",
|
||||
"sprite": "ag_bot",
|
||||
"cell": "ag_bot",
|
||||
"scale_x": 0.65,
|
||||
"scale_y": 0.65,
|
||||
"x": -40,
|
||||
"y": 70,
|
||||
"at_mid": false,
|
||||
"flipped": false
|
||||
}
|
||||
],
|
||||
"fixtures": [
|
||||
{
|
||||
"name": "ag_bot_speech",
|
||||
"sprite": "ag_bot_speech",
|
||||
"scale_x": 1.0,
|
||||
"scale_y": 1.0,
|
||||
"flipped": false,
|
||||
"cell": "speech",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"at_mid": false,
|
||||
"flipped": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"WIN": {
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 623 B |
BIN
assets/sprites/ag_bot.png
Normal file
BIN
assets/sprites/ag_bot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
BIN
assets/sprites/ag_bot_speech.png
Normal file
BIN
assets/sprites/ag_bot_speech.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.2 KiB |
|
|
@ -196,11 +196,8 @@ void WorldBuilder::place_stairs(DinkyECS::World& world, GameConfig& config) {
|
|||
auto& device_config = config.devices.json();
|
||||
auto entity_data = device_config["STAIRS_DOWN"];
|
||||
|
||||
// auto at_end = $map.$dead_ends.back();
|
||||
configure_entity_in_map(world, entity_data, {
|
||||
player_pos.location.x+1,
|
||||
player_pos.location.y
|
||||
});
|
||||
auto at_end = $map.$dead_ends.back();
|
||||
configure_entity_in_map(world, entity_data, at_end);
|
||||
}
|
||||
|
||||
void WorldBuilder::configure_starting_items(DinkyECS::World &world) {
|
||||
|
|
|
|||
|
|
@ -249,13 +249,12 @@ namespace animation {
|
|||
sequence.INVARIANT();
|
||||
}
|
||||
|
||||
Animation load(const std::string &file, const std::string &anim_name) {
|
||||
std::optional<Animation> maybe_load(const std::string &file, const std::string &anim_name) {
|
||||
using nlohmann::json;
|
||||
std::ifstream infile(file);
|
||||
auto data = json::parse(infile);
|
||||
|
||||
dbc::check(data.contains(anim_name),
|
||||
$F("{} animation config does not have animation {}", file, anim_name));
|
||||
if(!data.contains(anim_name)) return std::nullopt;
|
||||
|
||||
Animation anim;
|
||||
animation::from_json(data[anim_name], anim);
|
||||
|
|
@ -269,6 +268,15 @@ namespace animation {
|
|||
return anim;
|
||||
}
|
||||
|
||||
Animation load(const std::string &file, const std::string &anim_name) {
|
||||
auto anim = maybe_load(file, anim_name);
|
||||
|
||||
dbc::check(anim != std::nullopt,
|
||||
$F("FAILED to load animation {} from file {}", anim_name, file));
|
||||
|
||||
return *anim;
|
||||
}
|
||||
|
||||
void Sequence::INVARIANT(const std::source_location location) {
|
||||
dbc::check(frames.size() == durations.size(),
|
||||
$F("frames.size={} doesn't match durations.size={}",
|
||||
|
|
@ -297,8 +305,12 @@ namespace animation {
|
|||
void configure(DinkyECS::World& world, DinkyECS::Entity entity) {
|
||||
auto sprite = world.get_if<components::Sprite>(entity);
|
||||
|
||||
if(sprite != nullptr && has(sprite->name)) {
|
||||
world.set<Animation>(entity, animation::load("assets/animation.json", sprite->name));
|
||||
// sprite doesn't exist, abort
|
||||
if(sprite == nullptr) return;
|
||||
|
||||
// lazy load any animations
|
||||
if(auto anim = animation::maybe_load("assets/animation.json", sprite->name)) {
|
||||
world.set<Animation>(entity, *anim);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ namespace animation {
|
|||
};
|
||||
|
||||
Animation load(const std::string &file, const std::string &anim_name);
|
||||
std::optional<Animation> maybe_load(const std::string &file, const std::string &anim_name);
|
||||
|
||||
// BUG: brought over from animation to finish the refactor, but these may not be needed or maybe they go in system.cpp?
|
||||
bool has(const std::string& name);
|
||||
|
|
|
|||
|
|
@ -18,10 +18,13 @@ namespace scene {
|
|||
bool flipped = config["flipped"];
|
||||
|
||||
// BUG: put the .json file to load as a default/optional arg
|
||||
auto anim = animation::load("./assets/animation.json", sprite_name);
|
||||
anim.play();
|
||||
auto anim = animation::maybe_load("./assets/animation.json", sprite_name);
|
||||
|
||||
anim.transform.flipped = flipped;
|
||||
if(anim) {
|
||||
// only start it if there's an animation set
|
||||
anim->play();
|
||||
anim->transform.flipped = flipped;
|
||||
}
|
||||
|
||||
std::string cell = config["cell"];
|
||||
std::string name = config["name"];
|
||||
|
|
@ -103,7 +106,7 @@ namespace scene {
|
|||
|
||||
for(auto& actor : $actors) {
|
||||
view.draw(*actor.st.sprite, actor.effect.get());
|
||||
if(actor.anim.playing) view.draw(actor.text);
|
||||
if(actor.anim && actor.anim->playing) view.draw(actor.text);
|
||||
}
|
||||
|
||||
$camera.render(view);
|
||||
|
|
@ -126,20 +129,25 @@ namespace scene {
|
|||
|
||||
void Engine::animate_actor(const std::string& actor, const std::string& form) {
|
||||
auto& config = actor_config(actor);
|
||||
config.anim.set_form(form);
|
||||
|
||||
if(!config.anim.playing) {
|
||||
config.anim.play();
|
||||
// no animation set, abort
|
||||
if(!config.anim) return;
|
||||
|
||||
config.anim->set_form(form);
|
||||
|
||||
if(!config.anim->playing) {
|
||||
config.anim->play();
|
||||
}
|
||||
}
|
||||
|
||||
inline void this_is_stupid_refactor(std::vector<Element>& elements) {
|
||||
for(auto& element : elements) {
|
||||
if(element.anim.playing) {
|
||||
element.anim.update();
|
||||
element.anim.motion(*element.st.sprite, element.pos, element.scale);
|
||||
element.anim.apply(*element.st.sprite);
|
||||
if(element.effect != nullptr) element.anim.apply_effect(element.effect);
|
||||
// skip any without animation
|
||||
if(element.anim && element.anim->playing) {
|
||||
element.anim->update();
|
||||
element.anim->motion(*element.st.sprite, element.pos, element.scale);
|
||||
element.anim->apply(*element.st.sprite);
|
||||
if(element.effect != nullptr) element.anim->apply_effect(element.effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -178,8 +186,12 @@ namespace scene {
|
|||
}
|
||||
|
||||
void Engine::set_end_cb(std::function<void()> cb) {
|
||||
|
||||
for(auto& actor : $actors) {
|
||||
actor.anim.onLoop = [&,cb](auto& seq, auto& tr) -> bool {
|
||||
// no animation set so no point doing a end cb
|
||||
if(!actor.anim) continue;
|
||||
|
||||
actor.anim->onLoop = [&,cb](auto& seq, auto& tr) -> bool {
|
||||
seq.current = tr.toggled ? seq.frame_count - 1 : 0;
|
||||
cb();
|
||||
actor.effect = nullptr;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace scene {
|
|||
struct Element {
|
||||
std::string name;
|
||||
textures::SpriteTexture st;
|
||||
animation::Animation anim;
|
||||
std::optional<animation::Animation> anim;
|
||||
std::string cell;
|
||||
sf::Vector2f scale{1.0f, 1.0f};
|
||||
sf::Vector2f pos{0.0f, 0.0f};
|
||||
|
|
|
|||
|
|
@ -47,7 +47,5 @@ TEST_CASE("multiple targets can path", "[pathing]") {
|
|||
|
||||
if(found == PathingResult::FOUND) {
|
||||
fmt::println("FOUND!");
|
||||
} else if(found == PathingResult::FAIL && !diag) {
|
||||
REQUIRE(found != PathingResult::FAIL);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue