Icons now work way better and don't have the the 'Rayview cuts icons' bug. It actually was a bug in the lel-guecs Sprite class that was using the TextureRect from the source sprite. Now its initialized with the framesize from the .json. This also uses the new guecs::Icon, but I have to fix that as it doesn't scale correctly. Closes #2.
This commit is contained in:
parent
b311713064
commit
ff7111b006
22 changed files with 81 additions and 64 deletions
|
@ -80,11 +80,6 @@
|
|||
"frame_width": 256,
|
||||
"frame_height": 256
|
||||
},
|
||||
"torch_horizontal_floor_ICON":
|
||||
{"path": "assets/icons/torch_crappy_ICON.png",
|
||||
"frame_width": 128,
|
||||
"frame_height": 128
|
||||
},
|
||||
"peasant_girl":
|
||||
{"path": "assets/sprites/peasant_girl_2.png",
|
||||
"frame_width": 256,
|
||||
|
@ -100,11 +95,6 @@
|
|||
"frame_width": 256,
|
||||
"frame_height": 256
|
||||
},
|
||||
"healing_potion_small_ICON":
|
||||
{"path": "assets/icons/healing_potion_small_ICON.png",
|
||||
"frame_width": 128,
|
||||
"frame_height": 128
|
||||
},
|
||||
"well_down":
|
||||
{"path": "assets/sprites/well_down.png",
|
||||
"frame_width": 256,
|
||||
|
|
12
assets/icons.json
Normal file
12
assets/icons.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"healing_potion_small":
|
||||
{"path": "assets/icons/healing_potion_small.png",
|
||||
"frame_width": 96,
|
||||
"frame_height": 96
|
||||
},
|
||||
"torch_horizontal_floor":
|
||||
{"path": "assets/icons/torch_horizontal_floor.png",
|
||||
"frame_width": 96,
|
||||
"frame_height": 96
|
||||
}
|
||||
}
|
BIN
assets/icons/healing_potion_small.png
Normal file
BIN
assets/icons/healing_potion_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.5 KiB |
BIN
assets/icons/torch_horizontal_floor.png
Normal file
BIN
assets/icons/torch_horizontal_floor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
13
backend.cpp
13
backend.cpp
|
@ -8,9 +8,14 @@
|
|||
namespace sfml {
|
||||
using namespace nlohmann;
|
||||
|
||||
guecs::SpriteTexture Backend::texture_get(const string& name) {
|
||||
auto sp = textures::get(name);
|
||||
return {sp.sprite, sp.texture};
|
||||
guecs::SpriteTexture Backend::get_sprite(const string& name) {
|
||||
auto sp = textures::get_sprite(name);
|
||||
return {sp.sprite, sp.texture, sp.frame_size};
|
||||
}
|
||||
|
||||
guecs::SpriteTexture Backend::get_icon(const string& name) {
|
||||
auto sp = textures::get_icon(name);
|
||||
return {sp.sprite, sp.texture, sp.frame_size};
|
||||
}
|
||||
|
||||
Backend::Backend() {
|
||||
|
@ -27,7 +32,7 @@ namespace sfml {
|
|||
sound::stop(name);
|
||||
}
|
||||
|
||||
std::shared_ptr<sf::Shader> Backend::shader_get(const std::string& name) {
|
||||
std::shared_ptr<sf::Shader> Backend::get_shader(const std::string& name) {
|
||||
return shaders::get(name);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,10 +9,11 @@ namespace sfml {
|
|||
public:
|
||||
|
||||
Backend();
|
||||
guecs::SpriteTexture texture_get(const string& name);
|
||||
guecs::SpriteTexture get_sprite(const string& name);
|
||||
guecs::SpriteTexture get_icon(const string& name);
|
||||
void sound_play(const string& name);
|
||||
void sound_stop(const string& name);
|
||||
std::shared_ptr<sf::Shader> shader_get(const std::string& name);
|
||||
std::shared_ptr<sf::Shader> get_shader(const std::string& name);
|
||||
bool shader_updated();
|
||||
guecs::Theme theme();
|
||||
};
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace gui {
|
|||
$animation = $world->get<components::Animation>($boss_id);
|
||||
$animation.frame_width = $sprite_config.width;
|
||||
|
||||
$boss_image = textures::get($sprite_config.name);
|
||||
$boss_image = textures::get_sprite($sprite_config.name);
|
||||
sf::IntRect frame_rect{{0,0},{$sprite_config.width,$sprite_config.height}};
|
||||
$boss_image.sprite->setTextureRect(frame_rect);
|
||||
$boss_image.sprite->setScale({$sprite_config.scale, $sprite_config.scale});
|
||||
|
@ -52,13 +52,13 @@ namespace gui {
|
|||
void BossFightUI::configure_background() {
|
||||
auto& boss = $world->get<components::BossFight>($boss_id);
|
||||
|
||||
$boss_background = textures::get(boss.background);
|
||||
$boss_background = textures::get_sprite(boss.background);
|
||||
$boss_background.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y});
|
||||
$status.set<Background>($status.MAIN, {$status.$parser});
|
||||
|
||||
if(boss.stage) {
|
||||
$boss_has_stage = true;
|
||||
$boss_stage = textures::get(*boss.stage);
|
||||
$boss_stage = textures::get_sprite(*boss.stage);
|
||||
$boss_stage.sprite->setPosition({BOSS_VIEW_X, BOSS_VIEW_Y});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -347,7 +347,6 @@ namespace gui {
|
|||
if(!sound::playing("ambient_1")) sound::play("ambient_1", true);
|
||||
$debug_ui.debug();
|
||||
shaders::reload();
|
||||
$map_ui.save_map($main_ui.$compass_dir);
|
||||
break;
|
||||
case KEY::O:
|
||||
autowalking = true;
|
||||
|
|
|
@ -21,11 +21,9 @@ namespace guecs {
|
|||
}
|
||||
|
||||
void GrabSource::setSprite(guecs::UI& gui, guecs::Entity gui_id) {
|
||||
dbc::check(gui.has<guecs::Sprite>(gui_id), "GrabSource given sprite gui_id that doesn't exist");
|
||||
dbc::check(gui.has<guecs::Icon>(gui_id), "GrabSource given sprite gui_id that doesn't exist");
|
||||
|
||||
fmt::println("> Grabsource Set sprite entity {}", world_entity);
|
||||
|
||||
auto& sp = gui.get<guecs::Sprite>(gui_id);
|
||||
auto& sp = gui.get<guecs::Icon>(gui_id);
|
||||
sprite = sp.sprite;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace gui {
|
|||
dbc::check($level.world->has<components::Sprite>(item),
|
||||
"item in inventory UI doesn't exist in world. New level?");
|
||||
auto& sprite = $level.world->get<components::Sprite>(item);
|
||||
$gui.set_init<guecs::Sprite>(id, {fmt::format("{}_ICON", sprite.name)});
|
||||
$gui.set_init<guecs::Icon>(id, {sprite.name});
|
||||
|
||||
guecs::GrabSource grabber{
|
||||
item, [&, id]() { return remove_slot(id); }};
|
||||
|
@ -84,7 +84,7 @@ namespace gui {
|
|||
} else {
|
||||
// BUG: fix remove so it's safe to call on empty
|
||||
if($gui.has<guecs::GrabSource>(id)) {
|
||||
$gui.remove<guecs::Sprite>(id);
|
||||
$gui.remove<guecs::Icon>(id);
|
||||
$gui.remove<guecs::GrabSource>(id);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,15 +49,6 @@ namespace gui {
|
|||
$gui.init();
|
||||
}
|
||||
|
||||
void MapViewUI::save_map(int compass_dir) {
|
||||
(void)compass_dir;
|
||||
// confirm we get two different maps
|
||||
auto out_img = $map_render->getTexture().copyToImage();
|
||||
bool worked = out_img.saveToFile("tmp/map_render.png");
|
||||
dbc::check(worked, "failed to render map");
|
||||
}
|
||||
|
||||
|
||||
void MapViewUI::render(sf::RenderWindow &window, int compass_dir) {
|
||||
$gui.render(window);
|
||||
System::draw_map($level, $map_tiles, $entity_map);
|
||||
|
|
|
@ -24,6 +24,5 @@ namespace gui {
|
|||
void update_level(GameLevel &level);
|
||||
void log(std::wstring msg);
|
||||
void update();
|
||||
void save_map(int compass_dir);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace gui {
|
|||
}
|
||||
|
||||
void UI::START(Event) {
|
||||
$ritual_ui = textures::get("ritual_crafting_area");
|
||||
$ritual_ui = textures::get_sprite("ritual_crafting_area");
|
||||
$ritual_ui.sprite->setPosition($gui.get_position());
|
||||
$ritual_ui.sprite->setTextureRect($ritual_closed_rect);
|
||||
$ritual_anim = animation::load("ritual_blanket");
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace gui {
|
|||
auto gui_id = $gui.entity(slot);
|
||||
|
||||
auto& sprite = $level.world->get<components::Sprite>(world_entity);
|
||||
$gui.set_init<guecs::Sprite>(gui_id, {fmt::format("{}_ICON", sprite.name)});
|
||||
$gui.set_init<guecs::Icon>(gui_id, {sprite.name});
|
||||
guecs::GrabSource grabber{ world_entity,
|
||||
[&, gui_id]() { return remove_slot(gui_id); }};
|
||||
grabber.setSprite($gui, gui_id);
|
||||
|
@ -136,7 +136,7 @@ namespace gui {
|
|||
inventory.remove(world_entity);
|
||||
|
||||
$gui.remove<guecs::GrabSource>(slot_id);
|
||||
$gui.remove<guecs::Sprite>(slot_id);
|
||||
$gui.remove<guecs::Icon>(slot_id);
|
||||
}
|
||||
|
||||
void StatusUI::swap(guecs::Entity gui_a, guecs::Entity gui_b) {
|
||||
|
|
|
@ -423,7 +423,7 @@ void Raycaster::draw(sf::RenderTarget& target) {
|
|||
}
|
||||
|
||||
void Raycaster::update_sprite(DinkyECS::Entity ent, components::Sprite& sprite) {
|
||||
auto sprite_txt = textures::get(sprite.name);
|
||||
auto sprite_txt = textures::get_sprite(sprite.name);
|
||||
$sprites.insert_or_assign(ent, sprite_txt);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ TEST_CASE("animation utility API", "[animation]") {
|
|||
textures::init();
|
||||
animation::init();
|
||||
|
||||
auto blanket = textures::get("ritual_crafting_area");
|
||||
auto blanket = textures::get_sprite("ritual_crafting_area");
|
||||
auto anim = animation::load("ritual_blanket");
|
||||
|
||||
anim.play();
|
||||
|
|
|
@ -11,7 +11,7 @@ TEST_CASE("test texture management", "[textures]") {
|
|||
components::init();
|
||||
textures::init();
|
||||
|
||||
auto spider = textures::get("hairy_spider");
|
||||
auto spider = textures::get_sprite("hairy_spider");
|
||||
REQUIRE(spider.sprite != nullptr);
|
||||
REQUIRE(spider.texture != nullptr);
|
||||
REQUIRE(spider.frame_size.x == TEXTURE_WIDTH);
|
||||
|
|
56
textures.cpp
56
textures.cpp
|
@ -7,33 +7,43 @@
|
|||
#include <memory>
|
||||
|
||||
namespace textures {
|
||||
using std::shared_ptr, std::make_shared;
|
||||
using std::shared_ptr, std::make_shared, nlohmann::json, std::string;
|
||||
|
||||
static TextureManager TMGR;
|
||||
static bool initialized = false;
|
||||
|
||||
void load_sprites() {
|
||||
Config assets("assets/config.json");
|
||||
|
||||
for(auto& [name, settings] : assets["sprites"].items()) {
|
||||
void load_sprite_textures(SpriteTextureMap &mapping, json &config, bool smooth) {
|
||||
for(auto& [name, settings] : config.items()) {
|
||||
auto texture = make_shared<sf::Texture>(settings["path"]);
|
||||
|
||||
texture->setSmooth(assets["graphics"]["smooth_textures"]);
|
||||
texture->setSmooth(smooth);
|
||||
auto sprite = make_shared<sf::Sprite>(*texture);
|
||||
|
||||
int width = settings["frame_width"];
|
||||
int height = settings["frame_height"];
|
||||
dbc::check(width % 2 == 0,
|
||||
fmt::format("sprite {} has invalid frame size", name));
|
||||
fmt::format("sprite {} has invalid frame size {}", name, width));
|
||||
|
||||
sf::Vector2i frame_size{width, height};
|
||||
|
||||
sprite->setTextureRect({{0,0}, frame_size});
|
||||
|
||||
TMGR.sprite_textures.try_emplace(name, sprite, texture, frame_size);
|
||||
dbc::check(!mapping.contains(name),
|
||||
fmt::format("duplicate sprite/icon name {}", (string)name));
|
||||
mapping.try_emplace(name, sprite, texture, frame_size);
|
||||
}
|
||||
}
|
||||
|
||||
void load_sprites() {
|
||||
Config sprites("assets/config.json");
|
||||
bool smooth = sprites["graphics"]["smooth_textures"];
|
||||
|
||||
load_sprite_textures(TMGR.sprite_textures, sprites["sprites"], smooth);
|
||||
|
||||
Config icons("assets/icons.json");
|
||||
load_sprite_textures(TMGR.icon_textures, icons.json(), smooth);
|
||||
}
|
||||
|
||||
inline void resize_shit(size_t size) {
|
||||
TMGR.surfaces.resize(size);
|
||||
TMGR.ceilings.resize(size);
|
||||
|
@ -49,12 +59,12 @@ namespace textures {
|
|||
|
||||
for(auto &el : tiles.items()) {
|
||||
auto &config = el.value();
|
||||
const std::string& texture_fname = config["texture"];
|
||||
const string& texture_fname = config["texture"];
|
||||
size_t surface_i = config["id"];
|
||||
|
||||
dbc::check(!TMGR.name_to_id.contains(el.key()),
|
||||
fmt::format("duplicate key in textures {}",
|
||||
(std::string)el.key()));
|
||||
(string)el.key()));
|
||||
|
||||
TMGR.name_to_id.insert_or_assign(el.key(), surface_i);
|
||||
|
||||
|
@ -68,9 +78,9 @@ namespace textures {
|
|||
|
||||
// NOTE: ceilings defaults to 0 which is floor texture so only need to update
|
||||
if(config.contains("ceiling")) {
|
||||
const std::string& name = config["ceiling"];
|
||||
const string& name = config["ceiling"];
|
||||
|
||||
dbc::check(tiles.contains(name), fmt::format("invalid ceiling name {} in tile config {}", name, (std::string)el.key()));
|
||||
dbc::check(tiles.contains(name), fmt::format("invalid ceiling name {} in tile config {}", name, (string)el.key()));
|
||||
|
||||
auto& ceiling = tiles[name];
|
||||
TMGR.ceilings[surface_i] = ceiling["id"];
|
||||
|
@ -80,7 +90,7 @@ namespace textures {
|
|||
|
||||
void load_map_tiles() {
|
||||
Config config("./assets/map_tiles.json");
|
||||
nlohmann::json& tiles = config.json();
|
||||
json& tiles = config.json();
|
||||
|
||||
for(auto tile : tiles) {
|
||||
sf::Vector2i coords{tile["x"], tile["y"]};
|
||||
|
@ -107,12 +117,12 @@ namespace textures {
|
|||
}
|
||||
}
|
||||
|
||||
SpriteTexture get(const std::string& name) {
|
||||
SpriteTexture& get(const string& name, SpriteTextureMap& mapping) {
|
||||
dbc::check(initialized, "you forgot to call textures::init()");
|
||||
dbc::check(TMGR.sprite_textures.contains(name),
|
||||
fmt::format("!!!!! texture pack does not contain {} sprite", name));
|
||||
dbc::check(mapping.contains(name),
|
||||
fmt::format("!!!!! textures do not contain {} sprite", name));
|
||||
|
||||
auto result = TMGR.sprite_textures.at(name);
|
||||
auto& result = mapping.at(name);
|
||||
|
||||
dbc::check(result.sprite != nullptr,
|
||||
fmt::format("bad sprite from textures::get named {}", name));
|
||||
|
@ -122,7 +132,15 @@ namespace textures {
|
|||
return result;
|
||||
}
|
||||
|
||||
sf::Image load_image(const std::string& filename) {
|
||||
SpriteTexture get_sprite(const string& name) {
|
||||
return get(name, TMGR.sprite_textures);
|
||||
}
|
||||
|
||||
SpriteTexture get_icon(const string& name) {
|
||||
return get(name, TMGR.icon_textures);
|
||||
}
|
||||
|
||||
sf::Image load_image(const string& filename) {
|
||||
sf::Image texture;
|
||||
bool good = texture.loadFromFile(filename);
|
||||
dbc::check(good, fmt::format("failed to load {}", filename));
|
||||
|
@ -150,7 +168,7 @@ namespace textures {
|
|||
return (const uint32_t *)TMGR.surfaces[ceiling_num].getPixelsPtr();
|
||||
}
|
||||
|
||||
size_t get_id(const std::string& name) {
|
||||
size_t get_id(const string& name) {
|
||||
dbc::check(TMGR.name_to_id.contains(name),
|
||||
fmt::format("there is no texture named {} in tiles.json", name));
|
||||
return TMGR.name_to_id.at(name);
|
||||
|
|
|
@ -15,12 +15,15 @@ namespace textures {
|
|||
sf::Vector2i frame_size;
|
||||
};
|
||||
|
||||
using SpriteTextureMap = std::unordered_map<std::string, SpriteTexture>;
|
||||
|
||||
struct TextureManager {
|
||||
std::vector<sf::Image> surfaces;
|
||||
std::vector<size_t> ceilings;
|
||||
std::vector<wchar_t> map_tile_set;
|
||||
std::vector<int> ambient_light;
|
||||
std::unordered_map<std::string, SpriteTexture> sprite_textures;
|
||||
SpriteTextureMap sprite_textures;
|
||||
SpriteTextureMap icon_textures;
|
||||
std::unordered_map<std::string, size_t> name_to_id;
|
||||
std::unordered_map<wchar_t, sf::Sprite> map_sprites;
|
||||
sf::Texture map_sprite_sheet{"./assets/map_tiles.png"};
|
||||
|
@ -28,7 +31,8 @@ namespace textures {
|
|||
|
||||
void init();
|
||||
|
||||
SpriteTexture get(const std::string& name);
|
||||
SpriteTexture get_sprite(const std::string& name);
|
||||
SpriteTexture get_icon(const std::string& name);
|
||||
|
||||
sf::Image load_image(const std::string& filename);
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ int main(int argc, char *argv[]) {
|
|||
window.setVerticalSyncEnabled(true);
|
||||
|
||||
if(load_sprite) {
|
||||
sprite_texture = textures::get(sprite_name);
|
||||
sprite_texture = textures::get_sprite(sprite_name);
|
||||
sprite_texture.sprite->setPosition({0,0});
|
||||
auto bounds = sprite_texture.sprite->getLocalBounds();
|
||||
sf::Vector2f scale{u_resolution.x / bounds.size.x,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue