diff --git a/assets/black_square.png b/assets/black_square.png new file mode 100644 index 00000000..b98dc91a Binary files /dev/null and b/assets/black_square.png differ diff --git a/assets/black_square.xcf b/assets/black_square.xcf new file mode 100644 index 00000000..85936f71 Binary files /dev/null and b/assets/black_square.xcf differ diff --git a/assets/black_squarexcf.png b/assets/black_squarexcf.png new file mode 100644 index 00000000..614e1ad4 Binary files /dev/null and b/assets/black_squarexcf.png differ diff --git a/assets/black_squarexcf.xcf b/assets/black_squarexcf.xcf new file mode 100644 index 00000000..66545838 Binary files /dev/null and b/assets/black_squarexcf.xcf differ diff --git a/client/gui/controllers/keyboardhandler.cpp b/client/gui/controllers/keyboardhandler.cpp index 1fa4ca34..a4b46161 100644 --- a/client/gui/controllers/keyboardhandler.cpp +++ b/client/gui/controllers/keyboardhandler.cpp @@ -57,6 +57,7 @@ void KeyboardHandler::handleEvent(const SDL_Event& event) { case SDLK_g: sound_manager.play("item_pick"); output_queue.push(Message(PickUpItemCommand())); + std::cout << "Picking up item" << std::endl; break; } } diff --git a/client/gui/map_view/CMakeLists.txt b/client/gui/map_view/CMakeLists.txt index 9b445692..4b68b852 100644 --- a/client/gui/map_view/CMakeLists.txt +++ b/client/gui/map_view/CMakeLists.txt @@ -5,6 +5,7 @@ target_sources(taller_client sdl_world.cpp sdl_player.cpp sdl_item.cpp + field_of_view.cpp sdl_bullet.cpp sdl_knife_slash.cpp sdl_world_item.cpp @@ -17,6 +18,7 @@ target_sources(taller_client sdl_tile.h sdl_world.h sdl_item.h + field_of_view.h sdl_bullet.h sdl_knife_slash.h sdl_world_item.h diff --git a/client/gui/map_view/field_of_view.cpp b/client/gui/map_view/field_of_view.cpp new file mode 100644 index 00000000..db70c006 --- /dev/null +++ b/client/gui/map_view/field_of_view.cpp @@ -0,0 +1,30 @@ +#include "field_of_view.h" + +#include + + +FieldOfView::FieldOfView(const SdlWindow& window, float range): + window(window), range(range), mask("../assets/black_square.png", window) {} + +bool FieldOfView::is_visible(const Vector2D& camera_pos, const Vector2D& target_pos) const { + float dx = target_pos.get_x() - camera_pos.get_x(); + float dy = target_pos.get_y() - camera_pos.get_y(); + float distance = std::sqrt(dx * dx + dy * dy); + + return distance <= range; +} + +void FieldOfView::render(int screen_width, int screen_height, float angle) { + + SDL_Point center_w = {screen_width / 2, screen_height / 2}; + + // Calculate diagonal to ensure full coverage during rotation + int diagonal = static_cast( + std::ceil(std::sqrt(screen_width * screen_width + screen_height * screen_height))); + + SDL_Rect dst_rect = {0, 0, 1000, 1000}; + SDL_Point center = {diagonal / 2, diagonal / 2}; + + mask.render(center_w.x - diagonal / 2, center_w.y - diagonal / 2, diagonal, diagonal, &dst_rect, + angle, ¢er, SDL_FLIP_NONE); +} diff --git a/client/gui/map_view/field_of_view.h b/client/gui/map_view/field_of_view.h new file mode 100644 index 00000000..954ee260 --- /dev/null +++ b/client/gui/map_view/field_of_view.h @@ -0,0 +1,18 @@ +#pragma once +#include "client/gui/window_elements/sdl_texture.h" +#include "client/gui/window_elements/sdl_window.h" +#include "common/map/tile.h" +#include "common/physics/physics_config.h" +#include "common/updates/player_update.h" + +class FieldOfView { +private: + const SdlWindow& window; + float range; + SdlTexture mask; + +public: + FieldOfView(const SdlWindow& window, float range); + bool is_visible(const Vector2D& camera_pos, const Vector2D& target_pos) const; + void render(int screen_width, int screen_height, float angle); +}; diff --git a/client/gui/map_view/sdl_camera.h b/client/gui/map_view/sdl_camera.h index 9ce5bd00..39d7d9d0 100644 --- a/client/gui/map_view/sdl_camera.h +++ b/client/gui/map_view/sdl_camera.h @@ -41,6 +41,8 @@ class SdlCamera { bool can_see(const T& obj) const; bool can_see(const Tile& obj) const; + + Vector2D get_position() const { return position; } }; template diff --git a/client/gui/map_view/sdl_world.cpp b/client/gui/map_view/sdl_world.cpp index d011c12b..0270353d 100644 --- a/client/gui/map_view/sdl_world.cpp +++ b/client/gui/map_view/sdl_world.cpp @@ -32,9 +32,12 @@ SdlWorld::SdlWorld(const SdlWindow& window, Map&& map, const GameUpdate& game_st player_name(player_name), camera(window.getWidth(), window.getHeight()), map(window, camera, std::move(map)), + field_of_view(window, 1000.0f), + background(BACKGROUND_PATH, window), player(SdlPlayer(window, camera)), items(window, game_state, camera) {} + void SdlWorld::handle_hit(HitResponse&& hit) { auto origin = game_state.get_players().at(hit.get_player_name()).get_pos(); @@ -48,7 +51,27 @@ void SdlWorld::handle_hit(HitResponse&& hit) { } } +void SdlWorld::renderBackground() { + + const Area& src = Area(0, 0, 500, 300); + const Area& dest = Area(0, 0, window.getWidth() + 100, window.getHeight()); + background.render(src, dest); +} + +float SdlWorld::get_rotation(const PlayerUpdate& player_state) { + auto aim_direction = player_state.get_aim_direction(); + float angle; + if (aim_direction != Vector2D(0, 0)) { + angle = std::atan2(aim_direction.get_y(), aim_direction.get_x()) * 180 / M_PI; + angle += 90.0f; + } else { + angle = 0.0f; + } + return angle; +} + void SdlWorld::render() { + renderBackground(); camera.center(game_state.get_players().at(player_name).get_pos()); map.render(); @@ -66,4 +89,8 @@ void SdlWorld::render() { std::remove_if(knife_slashes.begin(), knife_slashes.end(), [](const auto& knife_slash) { return knife_slash->is_finished(); }), knife_slashes.end()); + + + field_of_view.render(window.getWidth(), window.getHeight(), + get_rotation(game_state.get_players().at(player_name))); } diff --git a/client/gui/map_view/sdl_world.h b/client/gui/map_view/sdl_world.h index 5372f79b..a630c2c5 100644 --- a/client/gui/map_view/sdl_world.h +++ b/client/gui/map_view/sdl_world.h @@ -17,6 +17,7 @@ #include "common/responses.h" #include "common/updates/game_update.h" +#include "field_of_view.h" #include "sdl_bullet.h" #include "sdl_camera.h" #include "sdl_knife_slash.h" @@ -26,25 +27,26 @@ class SdlWorld { private: - static constexpr const char* BACKGROUND_PATH = "../assets/gfx/tiles/dust.bmp"; - + static constexpr const char* BACKGROUND_PATH = "../assets/gfx/listTeams/rectanguloxcf.xcf"; const SdlWindow& window; const GameUpdate& game_state; const std::string& player_name; SdlCamera camera; SdlMap map; + FieldOfView field_of_view; + SdlTexture background; // TODO all players are sharing the same walk animation SdlPlayer player; - std::vector> bullets; - std::vector> knife_slashes; + std::vector > bullets; + std::vector > knife_slashes; SdlWorldItem items; - // SdlTexture background; // TODO: Load a background texture - public: SdlWorld(const SdlWindow& window, Map&& map, const GameUpdate& game_state, const std::string& player_name); void render(); + void renderBackground(); void handle_hit(HitResponse&& hit); + float get_rotation(const PlayerUpdate& player_state); }; diff --git a/client/gui/window_elements/sdl_texture.cpp b/client/gui/window_elements/sdl_texture.cpp index bda332b6..8e68e6f9 100644 --- a/client/gui/window_elements/sdl_texture.cpp +++ b/client/gui/window_elements/sdl_texture.cpp @@ -56,3 +56,13 @@ void SdlTexture::render(int x, int y, SDL_Rect* clip, double angle, SDL_Point* c } void SdlTexture::render(int x, int y, double angle) { render(x, y, nullptr, angle); } + +void SdlTexture::render(int x, int y, int w, int h, SDL_Rect* clip, double angle, SDL_Point* center, + SDL_RendererFlip flip) { + SDL_Rect renderQuad = {x, y, w, h}; + + if (SDL_RenderCopyEx(this->renderer, this->texture, clip, &renderQuad, angle, center, flip) != + 0) { + std::cout << "Render failed: " << SDL_GetError() << std::endl; + } +} diff --git a/client/gui/window_elements/sdl_texture.h b/client/gui/window_elements/sdl_texture.h index e64790b5..05d87521 100644 --- a/client/gui/window_elements/sdl_texture.h +++ b/client/gui/window_elements/sdl_texture.h @@ -35,6 +35,9 @@ class SdlTexture { void render(int x, int y, SDL_Rect* clip = nullptr, double angle = 0, SDL_Point* center = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE); + void render(int x, int y, int w, int h, SDL_Rect* clip, double angle, SDL_Point* center, + SDL_RendererFlip flip); + SdlTexture(SdlTexture&&) = delete; SdlTexture& operator=(SdlTexture&&) = delete; diff --git a/client/sdl_display.cpp b/client/sdl_display.cpp index 72322113..ff50db9e 100644 --- a/client/sdl_display.cpp +++ b/client/sdl_display.cpp @@ -34,7 +34,7 @@ SDLDisplay::SDLDisplay(Queue& input_queue, Queue& output_queue sound_manager(), current_phase(PhaseType::WarmUp) { SCREEN_WIDTH = 1200; - SCREEN_HEIGHT = 600; + SCREEN_HEIGHT = 800; } void SDLDisplay::setup() { @@ -70,7 +70,7 @@ void SDLDisplay::setup() { /*SCREEN_WIDTH = displayMode.w; SCREEN_HEIGHT = displayMode.h - 150;*/ SCREEN_WIDTH = 1200; - SCREEN_HEIGHT = 600; + SCREEN_HEIGHT = 800; } void SDLDisplay::run() {