11#include < array>
2+ #include < filesystem>
23#include < functional>
34#include < iostream>
45#include < random>
78#include < ftxui/component/captured_mouse.hpp> // for ftxui
89#include < ftxui/component/component.hpp> // for Slider
910#include < ftxui/component/screen_interactive.hpp> // for ScreenInteractive
11+ #include < lodepng.h>
1012#include < spdlog/spdlog.h>
1113
1214// This file will be generated automatically when you run the CMake
@@ -204,6 +206,36 @@ struct Bitmap : ftxui::Node
204206};
205207
206208
209+ Vector2D<Color> load_png (const std::filesystem::path &filename)
210+ {
211+ std::vector<unsigned char > image;// the raw pixels
212+ unsigned width{};
213+ unsigned height{};
214+
215+ // decode
216+ unsigned error = lodepng::decode (image, width, height, filename.string ());
217+
218+ // if there's an error, display it
219+ if (error != 0 ) { std::cout << " decoder error " << error << " : " << lodepng_error_text (error) << std::endl; }
220+
221+ // the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ...
222+ //
223+ Vector2D<Color> results{ Size{ static_cast <std::size_t >(width), static_cast <std::size_t >(height) } };
224+
225+ std::size_t position = 0 ;
226+ for (std::size_t y = 0 ; y < results.size ().height ; ++y) {
227+ for (std::size_t x = 0 ; x < results.size ().width ; ++x) {
228+ Color &c = results.at (Point{ x, y });
229+ c.R = image[position++];
230+ c.G = image[position++];
231+ c.B = image[position++];
232+ c.A = image[position++];
233+ }
234+ }
235+
236+ return results;
237+ }
238+
207239struct Location
208240{
209241 std::function<void ()> action;
@@ -307,18 +339,22 @@ void game_iteration_canvas()
307339 double fps = 0 ;
308340 auto start_time = std::chrono::steady_clock::now ();
309341
342+ const auto player_bitmap = load_png (" player.png" );
343+
310344 Character player;
311- player.draw = []([[maybe_unused]] Vector2D_Span<Color> &pixels,
345+ player.draw = [& ]([[maybe_unused]] Vector2D_Span<Color> &pixels,
312346 [[maybe_unused]] std::chrono::milliseconds game_clock,
313347 [[maybe_unused]] Point map_location) {
314348 // with with a fully saturated red at 50% alpha
315349 for (std::size_t x = 0 ; x < pixels.size ().width ; ++x) {
316350 for (std::size_t y = 0 ; y < pixels.size ().height ; ++y) {
317- pixels.at (Point{ x, y }) += Color{ 255 , 0 , 0 , 128 }; // NOLINT magic number
351+ pixels.at (Point{ x, y }) += player_bitmap. at (Point{ x, y });
318352 }
319353 }
320354 };
321355
356+ Point character_location{ 0 , 0 };
357+
322358 // to do, add total game time clock also, not just current elapsed time
323359 auto game_iteration = [&](const std::chrono::steady_clock::duration elapsed_time) {
324360 // in here we simulate however much game time has elapsed. Update animations,
@@ -339,7 +375,7 @@ void game_iteration_canvas()
339375 map);
340376
341377
342- auto player_span = Vector2D_Span<Color>(Point{ 20 , 25 } , Size{ 10 , 10 }, bm->pixels );// NOLINT Magic number
378+ auto player_span = Vector2D_Span<Color>(character_location , Size{ 10 , 10 }, bm->pixels );// NOLINT Magic number
343379
344380 player.draw (player_span, game_clock, player.map_location );
345381 };
@@ -350,6 +386,8 @@ void game_iteration_canvas()
350386
351387 auto last_time = std::chrono::steady_clock::now ();
352388
389+ std::string last_character;
390+
353391 auto make_layout = [&] {
354392 // This code actually processes the draw event
355393 const auto new_time = std::chrono::steady_clock::now ();
@@ -363,12 +401,28 @@ void game_iteration_canvas()
363401 return ftxui::hbox ({ bm | ftxui::border,
364402 ftxui::vbox ({ ftxui::text (" Frame: " + std::to_string (counter)),
365403 ftxui::text (" FPS: " + std::to_string (fps)),
404+ ftxui::text (" Character: " + last_character),
366405 small_bm | ftxui::border }) });
367406 };
368407
369408 auto container = ftxui::Container::Vertical ({});
409+ auto key_press = ftxui::CatchEvent (container, [&](const ftxui::Event &e) {
410+ if (e == ftxui::Event::ArrowUp) {
411+ --character_location.y ;
412+ } else if (e == ftxui::Event::ArrowDown) {
413+ ++character_location.y ;
414+ } else if (e == ftxui::Event::ArrowLeft) {
415+ --character_location.x ;
416+ } else if (e == ftxui::Event::ArrowRight) {
417+ ++character_location.x ;
418+ }
419+
420+
421+ return false ;
422+ });
423+
370424
371- auto renderer = ftxui::Renderer (container , make_layout);
425+ auto renderer = ftxui::Renderer (key_press , make_layout);
372426
373427 std::atomic<bool > refresh_ui_continue = true ;
374428
0 commit comments