From 931d9493d2e6930564fd1af6c34e1d4b9d57eb81 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Mon, 26 May 2025 13:59:26 -0400 Subject: [PATCH] The raycaster can now pair a floor with a ceiling tile and to demonstrate this I have a blue light that shines on to a stone floor. I also played with just pixelating a regular image rather than painting it and honestly it looks better in a lot of ways. --- assets/ceiling_moss_brick_blue_light-256.png | Bin 0 -> 20676 bytes assets/enemies.json | 2 +- assets/large_stone_floor-256.png | Bin 0 -> 25106 bytes assets/tiles.json | 17 ++++++++- raycaster.cpp | 12 +++---- raycaster.hpp | 2 -- systems.cpp | 2 +- tests/textures.cpp | 6 ---- textures.cpp | 35 +++++++++++-------- textures.hpp | 11 +++--- worldbuilder.cpp | 2 +- 11 files changed, 50 insertions(+), 39 deletions(-) create mode 100644 assets/ceiling_moss_brick_blue_light-256.png create mode 100644 assets/large_stone_floor-256.png diff --git a/assets/ceiling_moss_brick_blue_light-256.png b/assets/ceiling_moss_brick_blue_light-256.png new file mode 100644 index 0000000000000000000000000000000000000000..34617aca2d7aed96040e98f592f56c88eaeb264e GIT binary patch literal 20676 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Ⓢ_4h?+#bFJH-AO39~PoZ*<%lUqppB`Bu>#cek_Z= zX{w=oY+xxPc5k*;obMD8^-SPm`U_&K@{5brTg0W8s+*l7p7KR_So)*Aa!Of%z9i~WuQ#OAExk|Gy95q z!6b_rc-!fC-93F5l9%Ek#De%%^en%o0+jHNF0}$``qb?#<<(|lyubNAo$!!K&Pd{f z7{9A*!HcHZH62QDj78agz=J!r0d#??7=yUuB1<(4g1W-29ml$80Cf_)A4M<>a{?Yf z2ezKLs*`TnNcgXeOj^-#j$sXwydqw7s$~x9Z*5B*vVY${@{qQsRAM#PE9d|OWMbO8 zzF<=6qlGv%4A&)=Gp^_A@qvHluQw6{9$5nq6oV{TC!JVddTD+XpQeq_QcqL&IPRxp z@73US(L?e9d}4ZSI@Lx6R~zqmHMZf@EtUKV5qVDB?^jxkY&0g#+Iiln@Vwn{ z4ysTfX05*M6VJ;WW`-NnRFQk9f70#X%Jm0hpQD7Ns3VRC(sj}OIvHa>Wja=X*DXLQ z<6!|XM&)-Whtpkl^cR4`qF)_K)6pD3LV(3ngl)lj+DH4?e;6TbBPh}h@%Ns!5Wl(4N77u+l-feNFtzf-Ya~M+f(fr3F7e{PBn;_Qcy!64Dp%U}8|O+t6mtc|hn3u!;U?5Nq9iUPbP# zh{wpOtp|Tjo2=J~&yOXmhGBRTeR-20@?_&FsZ8Fh2@58@3f5W&gV*XI;3~mLv?7fD z_$}YEughvLutn-E^g)hPbjZLJmg(mrXOlVxHp2y*KiKW5M))qq6*?ewnC>sAOD$Qr zIKRs%)=*o-!Vd=X4FG({*sP+wxPjfcYW7LBGYsS?S9Ks$_|cm%*Blg^iWb=hsm>Xb z{*#W$C*W$U;efDK`mF+c3+WmUlUpwZx_g)hoAY)P40Ui@^2NsLOfF|&4VP5E-euh) zl7}weQ1>;;XK-r}EFSZq^qosur8b$KCQ)8GtEvSDqy}lo#VgB?8rIqVJ+1BOdsXc; zs_RF`+3XG?gwv{+V~nL!6cAlIF`LFl(aL9=?HdB~fI36{wDlSB$Z48HQ@XLVSf3sE z!Bm#|&GY#e_B(U!MqOGJoy)+xcQ?N0wt;7te?jYArys1veRcHq2fq{`PlY(=g;dZQJlFQBPF)F=82H;4L+wpV2@XlF1t zdd1>D-}V5UW5uoIJR>&>B!=jQalizJ8)sr9jC-s&5My*4j3byvp3>Pfe{`z{OirTG)bswABhUIh-8{8HEX`Mh0++fBKz6VH1V)`cVL zRJidRKN$$IZJB}Z!}(sOEKbGAtJ(_u4L5ghl<6}%^J+Y9iZ{y~8AsDAzbFD$4&$X# zI@!HIW?dduc___|%dCa_nybMgFL>-Vfrbz6O}RF{HuX5^z~k9G(=CeB^{ut5kgJg| z(C{e5cb33Ld#0~wgZxi!oT|llBx|Gz=GqFy1mqb6UQ~5{Ba{T8<|6|1WNR~M;r@d6 zMKq?`P%|2-=BFwVPFft#E5uvSKQtGLv~Uo9EAq2f@yH*|Accen`&iBtmv>GCl5q&` zJoL@y@E0|UAbjAGbNDkY9KO5o&Vn;x2OAs` z!A-YFvyKKAo0v5F%z7UM3%__Pq-JD}oC*Hj%!6@QFVs=3F$;pC%ENg7P=!kw7t(Uf z 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 YAMILnY(>g5Qvd(}07*qoM6N<$g5wHv*8l(j literal 0 HcmV?d00001 diff --git a/assets/tiles.json b/assets/tiles.json index d710353..6e4188c 100644 --- a/assets/tiles.json +++ b/assets/tiles.json @@ -3,6 +3,7 @@ "texture": "assets/floor_tile_test-256.png", "collision": false, "display": 10398, + "ceiling": "ceiling_plain", "id": 0 }, "wall_plain": { @@ -23,7 +24,7 @@ "display": 35, "id": 3 }, - "plain_ceiling": { + "ceiling_plain": { "texture": "assets/ceiling_test-256.png", "collision": false, "display": 35, @@ -33,6 +34,20 @@ "texture": "assets/lava_floor-256.png", "collision": false, "display": 35, + "ceiling": "ceiling_plain", "id": 5 + }, + "large_stone_floor": { + "texture": "assets/large_stone_floor-256.png", + "collision": false, + "display": 35, + "ceiling": "ceiling_moss_brick_blue_light", + "id": 6 + }, + "ceiling_moss_brick_blue_light": { + "texture": "assets/ceiling_moss_brick_blue_light-256.png", + "collision": false, + "display": 35, + "id": 7 } } diff --git a/raycaster.cpp b/raycaster.cpp index fd20488..38c5d3c 100644 --- a/raycaster.cpp +++ b/raycaster.cpp @@ -66,8 +66,6 @@ Raycaster::Raycaster(int width, int height) : $view_sprite.setPosition({0, 0}); $pixels = make_unique($width * $height); $view_texture.setSmooth(false); - $floor_texture = textures::get_floor(); - $ceiling_texture = textures::get_ceiling(); } void Raycaster::set_position(int x, int y) { @@ -329,6 +327,8 @@ void Raycaster::draw_ceiling_floor() { constexpr static const int texture_height = TEXTURE_HEIGHT; auto &lights = $level.lights->lighting(); size_t surface_i = 0; + const uint32_t *floor_texture = textures::get_surface(surface_i); + const uint32_t *ceiling_texture = textures::get_ceiling(surface_i); for(int y = $height / 2 + 1; y < $height; ++y) { // rayDir for leftmost ray (x=0) and rightmost (x = w) @@ -388,18 +388,18 @@ void Raycaster::draw_ceiling_floor() { if(new_surface_i != surface_i) { surface_i = new_surface_i; - $floor_texture = textures::get_surface(surface_i); - $ceiling_texture = textures::get_surface(surface_i); + floor_texture = textures::get_surface(surface_i); + ceiling_texture = textures::get_ceiling(surface_i); } // NOTE: use map_x/y to get the floor, ceiling texture. // FLOOR - color = $floor_texture[texture_width * ty + tx]; + color = floor_texture[texture_width * ty + tx]; $pixels[pixcoord(x, y)] = lighting_calc(color, row_distance, light_level); // CEILING - color = $ceiling_texture[texture_width * ty + tx]; + color = ceiling_texture[texture_width * ty + tx]; $pixels[pixcoord(x, $height - y - 1)] = lighting_calc(color, row_distance, light_level); } } diff --git a/raycaster.hpp b/raycaster.hpp index ca990b5..0817ca0 100644 --- a/raycaster.hpp +++ b/raycaster.hpp @@ -25,8 +25,6 @@ struct Raycaster { double $plane_y = 0.66; sf::Texture $view_texture; sf::Sprite $view_sprite; - const uint32_t *$floor_texture = nullptr; - const uint32_t *$ceiling_texture = nullptr; DinkyECS::Entity aiming_at = 0; std::unique_ptr $pixels = nullptr; diff --git a/systems.cpp b/systems.cpp index 79b1a3a..84615be 100644 --- a/systems.cpp +++ b/systems.cpp @@ -390,7 +390,7 @@ std::wstring System::draw_map(GameLevel level, size_t view_x, size_t view_y, int auto player_pos = world.get(level.player).location; Point cam_orig = map.center_camera(player_pos, view_x, view_y); auto &tiles = map.tiles(); - auto &tile_set = textures::get_tile_set(); + auto &tile_set = textures::get_map_tile_set(); // make a grid of chars to work with auto grid = shiterator::make(view_x+1, view_y+1); diff --git a/tests/textures.cpp b/tests/textures.cpp index 55c03c8..8e80161 100644 --- a/tests/textures.cpp +++ b/tests/textures.cpp @@ -17,12 +17,6 @@ TEST_CASE("test texture management", "[textures]") { auto img_ptr = textures::get_surface(0); REQUIRE(img_ptr != nullptr); - auto floor_ptr = textures::get_floor(); - REQUIRE(floor_ptr != nullptr); - - auto ceiling_ptr = textures::get_ceiling(); - REQUIRE(ceiling_ptr != nullptr); - LevelManager levels; GameLevel level = levels.current(); auto& tiles = level.map->tiles(); diff --git a/textures.cpp b/textures.cpp index 6037faf..6be20d7 100644 --- a/textures.cpp +++ b/textures.cpp @@ -27,16 +27,15 @@ namespace textures { TMGR.sprite_textures.try_emplace(name, sprite, texture); } - - TMGR.floor = load_image(assets["sprites"]["floor"]["path"]); - TMGR.ceiling = load_image(assets["sprites"]["ceiling"]["path"]); } void load_tiles() { Config assets("assets/tiles.json"); auto &tiles = assets.json(); + TMGR.surfaces.resize(tiles.size()); - TMGR.tile_set.resize(tiles.size()); + TMGR.ceilings.resize(tiles.size()); + TMGR.map_tile_set.resize(tiles.size()); for(auto &el : tiles.items()) { auto &config = el.value(); @@ -45,11 +44,22 @@ namespace textures { if(surface_i >= tiles.size()) { TMGR.surfaces.resize(surface_i + 1); - TMGR.tile_set.resize(surface_i + 1); + TMGR.ceilings.resize(surface_i + 1); + TMGR.map_tile_set.resize(surface_i + 1); } - TMGR.tile_set[surface_i] = config["display"]; + TMGR.map_tile_set[surface_i] = config["display"]; TMGR.surfaces[surface_i] = load_image(texture_fname); + + // NOTE: ceilings defaults to 0 which is floor texture so only need to update + if(config.contains("ceiling")) { + const std::string& name = config["ceiling"]; + + dbc::check(tiles.contains(name), fmt::format("invalid ceiling name {} in tile config {}", name, (std::string)el.key())); + + auto& ceiling = tiles[name]; + TMGR.ceilings[surface_i] = ceiling["id"]; + } } } @@ -83,19 +93,16 @@ namespace textures { return texture; } - std::vector& get_tile_set() { - return TMGR.tile_set; + std::vector& get_map_tile_set() { + return TMGR.map_tile_set; } const uint32_t* get_surface(size_t num) { return (const uint32_t *)TMGR.surfaces[num].getPixelsPtr(); } - const uint32_t* get_floor() { - return (const uint32_t *)TMGR.floor.getPixelsPtr(); - } - - const uint32_t* get_ceiling() { - return (const uint32_t *)TMGR.ceiling.getPixelsPtr(); + const uint32_t* get_ceiling(size_t num) { + size_t ceiling_num = TMGR.ceilings[num]; + return (const uint32_t *)TMGR.surfaces[ceiling_num].getPixelsPtr(); } }; diff --git a/textures.hpp b/textures.hpp index ff4a36b..2e64ad3 100644 --- a/textures.hpp +++ b/textures.hpp @@ -16,10 +16,9 @@ namespace textures { struct TextureManager { std::vector surfaces; - std::vector tile_set; + std::vector ceilings; + std::vector map_tile_set; std::unordered_map sprite_textures; - sf::Image floor; - sf::Image ceiling; }; void init(); @@ -28,11 +27,9 @@ namespace textures { sf::Image load_image(const std::string& filename); - std::vector& get_tile_set(); + std::vector& get_map_tile_set(); const uint32_t* get_surface(size_t num); - const uint32_t* get_floor(); - - const uint32_t* get_ceiling(); + const uint32_t* get_ceiling(size_t num); } diff --git a/worldbuilder.cpp b/worldbuilder.cpp index bca2b66..cdcf5c2 100644 --- a/worldbuilder.cpp +++ b/worldbuilder.cpp @@ -18,7 +18,7 @@ void WorldBuilder::stylize_rooms() { if(tiles[it.y][it.x] == 1) { tiles[it.y][it.x] = 2; } else if(tiles[it.y][it.x] == 0) { - tiles[it.y][it.x] = 5; + tiles[it.y][it.x] = 6; } } }