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": [],
|
"open": [],
|
||||||
"close": []
|
"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": {
|
"hands_sword_attack": {
|
||||||
"sheet": {
|
"sheet": {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,16 @@
|
||||||
"frame_width": 256,
|
"frame_width": 256,
|
||||||
"frame_height": 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":
|
"repair_kit":
|
||||||
{"path": "assets/items/repair_kit.png",
|
{"path": "assets/items/repair_kit.png",
|
||||||
"frame_width": 256,
|
"frame_width": 256,
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,36 @@
|
||||||
},
|
},
|
||||||
"STARTING": {
|
"STARTING": {
|
||||||
"layout": [
|
"layout": [
|
||||||
"[=text]"
|
"[_|*%(200, 200)ag_bot|_|*%(200,100)speech|_|_]",
|
||||||
|
"[_|_|_ |*%(200,100)buttons|_|_]"
|
||||||
],
|
],
|
||||||
"background": "starting_scene",
|
"background": "starting_scene",
|
||||||
"actors": [
|
"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": [
|
"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": {
|
"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& device_config = config.devices.json();
|
||||||
auto entity_data = device_config["STAIRS_DOWN"];
|
auto entity_data = device_config["STAIRS_DOWN"];
|
||||||
|
|
||||||
// auto at_end = $map.$dead_ends.back();
|
auto at_end = $map.$dead_ends.back();
|
||||||
configure_entity_in_map(world, entity_data, {
|
configure_entity_in_map(world, entity_data, at_end);
|
||||||
player_pos.location.x+1,
|
|
||||||
player_pos.location.y
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldBuilder::configure_starting_items(DinkyECS::World &world) {
|
void WorldBuilder::configure_starting_items(DinkyECS::World &world) {
|
||||||
|
|
|
||||||
|
|
@ -249,13 +249,12 @@ namespace animation {
|
||||||
sequence.INVARIANT();
|
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;
|
using nlohmann::json;
|
||||||
std::ifstream infile(file);
|
std::ifstream infile(file);
|
||||||
auto data = json::parse(infile);
|
auto data = json::parse(infile);
|
||||||
|
|
||||||
dbc::check(data.contains(anim_name),
|
if(!data.contains(anim_name)) return std::nullopt;
|
||||||
$F("{} animation config does not have animation {}", file, anim_name));
|
|
||||||
|
|
||||||
Animation anim;
|
Animation anim;
|
||||||
animation::from_json(data[anim_name], anim);
|
animation::from_json(data[anim_name], anim);
|
||||||
|
|
@ -269,6 +268,15 @@ namespace animation {
|
||||||
return anim;
|
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) {
|
void Sequence::INVARIANT(const std::source_location location) {
|
||||||
dbc::check(frames.size() == durations.size(),
|
dbc::check(frames.size() == durations.size(),
|
||||||
$F("frames.size={} doesn't match durations.size={}",
|
$F("frames.size={} doesn't match durations.size={}",
|
||||||
|
|
@ -297,8 +305,12 @@ namespace animation {
|
||||||
void configure(DinkyECS::World& world, DinkyECS::Entity entity) {
|
void configure(DinkyECS::World& world, DinkyECS::Entity entity) {
|
||||||
auto sprite = world.get_if<components::Sprite>(entity);
|
auto sprite = world.get_if<components::Sprite>(entity);
|
||||||
|
|
||||||
if(sprite != nullptr && has(sprite->name)) {
|
// sprite doesn't exist, abort
|
||||||
world.set<Animation>(entity, animation::load("assets/animation.json", sprite->name));
|
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);
|
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?
|
// 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);
|
bool has(const std::string& name);
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,13 @@ namespace scene {
|
||||||
bool flipped = config["flipped"];
|
bool flipped = config["flipped"];
|
||||||
|
|
||||||
// BUG: put the .json file to load as a default/optional arg
|
// BUG: put the .json file to load as a default/optional arg
|
||||||
auto anim = animation::load("./assets/animation.json", sprite_name);
|
auto anim = animation::maybe_load("./assets/animation.json", sprite_name);
|
||||||
anim.play();
|
|
||||||
|
|
||||||
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 cell = config["cell"];
|
||||||
std::string name = config["name"];
|
std::string name = config["name"];
|
||||||
|
|
@ -103,7 +106,7 @@ namespace scene {
|
||||||
|
|
||||||
for(auto& actor : $actors) {
|
for(auto& actor : $actors) {
|
||||||
view.draw(*actor.st.sprite, actor.effect.get());
|
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);
|
$camera.render(view);
|
||||||
|
|
@ -126,20 +129,25 @@ namespace scene {
|
||||||
|
|
||||||
void Engine::animate_actor(const std::string& actor, const std::string& form) {
|
void Engine::animate_actor(const std::string& actor, const std::string& form) {
|
||||||
auto& config = actor_config(actor);
|
auto& config = actor_config(actor);
|
||||||
config.anim.set_form(form);
|
|
||||||
|
|
||||||
if(!config.anim.playing) {
|
// no animation set, abort
|
||||||
config.anim.play();
|
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) {
|
inline void this_is_stupid_refactor(std::vector<Element>& elements) {
|
||||||
for(auto& element : elements) {
|
for(auto& element : elements) {
|
||||||
if(element.anim.playing) {
|
// skip any without animation
|
||||||
element.anim.update();
|
if(element.anim && element.anim->playing) {
|
||||||
element.anim.motion(*element.st.sprite, element.pos, element.scale);
|
element.anim->update();
|
||||||
element.anim.apply(*element.st.sprite);
|
element.anim->motion(*element.st.sprite, element.pos, element.scale);
|
||||||
if(element.effect != nullptr) element.anim.apply_effect(element.effect);
|
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) {
|
void Engine::set_end_cb(std::function<void()> cb) {
|
||||||
|
|
||||||
for(auto& actor : $actors) {
|
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;
|
seq.current = tr.toggled ? seq.frame_count - 1 : 0;
|
||||||
cb();
|
cb();
|
||||||
actor.effect = nullptr;
|
actor.effect = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ namespace scene {
|
||||||
struct Element {
|
struct Element {
|
||||||
std::string name;
|
std::string name;
|
||||||
textures::SpriteTexture st;
|
textures::SpriteTexture st;
|
||||||
animation::Animation anim;
|
std::optional<animation::Animation> anim;
|
||||||
std::string cell;
|
std::string cell;
|
||||||
sf::Vector2f scale{1.0f, 1.0f};
|
sf::Vector2f scale{1.0f, 1.0f};
|
||||||
sf::Vector2f pos{0.0f, 0.0f};
|
sf::Vector2f pos{0.0f, 0.0f};
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,5 @@ TEST_CASE("multiple targets can path", "[pathing]") {
|
||||||
|
|
||||||
if(found == PathingResult::FOUND) {
|
if(found == PathingResult::FOUND) {
|
||||||
fmt::println("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