diff --git a/include/Map.hpp b/include/Map.hpp index 899f67e..24d344e 100644 --- a/include/Map.hpp +++ b/include/Map.hpp @@ -49,8 +49,8 @@ public: void draw(Veci offset) override { for (const auto &food : food_) { - Veci food_pos = food.pos - offset; - if (utils::is_valid_pos(food_pos) and not food.eaten) { + Veci food_pos = utils::to_world_coord(food.pos - offset); + if (utils::is_on_screen(food_pos) and not food.eaten) { paint::circle({{ .pos = food_pos, .color = color::scale(config_.food_color, diff --git a/include/Params.hpp b/include/Params.hpp new file mode 100644 index 0000000..6926448 --- /dev/null +++ b/include/Params.hpp @@ -0,0 +1,5 @@ +#pragma once + +#include "Vec.hpp" + +constexpr Veci WORLD_SIZE = {.x = 10000, .y = 10000}; diff --git a/include/Utils.hpp b/include/Utils.hpp index 56bc6ff..da6229e 100644 --- a/include/Utils.hpp +++ b/include/Utils.hpp @@ -1,8 +1,10 @@ #pragma once #include +#include #include "Engine.h" +#include "Params.hpp" #include "Vec.hpp" namespace utils { @@ -21,21 +23,39 @@ inline int x(int x) { return safe::ux(safe::lx(x)); } inline int y(int y) { return safe::uy(safe::ly(y)); } } // namespace safe -inline uint32_t *screen_at(int x, int y) { - return &buffer[safe::x(x)][safe::y(y)]; +inline uint32_t *screen_at(Veci pos) { + return &buffer[safe::x(pos.x)][safe::y(pos.y)]; } -template inline bool is_valid_pos(Vec pos) { +template inline bool is_on_screen(Vec pos) { return pos.x >= 0 and pos.x < SCREEN_HEIGHT and pos.y >= 0 and pos.y < SCREEN_WIDTH; } inline Veci get_cursor() { return {.x = get_cursor_y(), .y = get_cursor_x()}; } -inline constexpr Veci get_center() { +inline constexpr Veci get_screen_center() { return {.x = SCREEN_HEIGHT / 2, .y = SCREEN_WIDTH / 2}; } +// + +template inline T to_inteval_from_zero_to(uint bound, T val) { + assert(bound != 0); + + bool was_negative = (val < 0); + val = std::abs(val); + val = val - int((int(val) / bound) * bound); + return was_negative ? bound - val : val; +} + +template inline Vec to_world_coord(Vec pos) { + return { + .x = to_inteval_from_zero_to(WORLD_SIZE.x, pos.x), + .y = to_inteval_from_zero_to(WORLD_SIZE.y, pos.y), + }; +} + } // namespace utils namespace color { diff --git a/src/Canvas.cpp b/src/Canvas.cpp index 021af25..8acfee1 100644 --- a/src/Canvas.cpp +++ b/src/Canvas.cpp @@ -8,15 +8,16 @@ namespace paint { void square(const canvas::Square &s) { for (int x = s.pos.x; x < s.pos.x + s.side; ++x) { - std::fill(screen_at(x, s.pos.y), screen_at(x, s.pos.y + s.side), s.color.v); + std::fill(screen_at({.x = x, .y = s.pos.y}), + screen_at({.x = x, .y = s.pos.y + s.side}), s.color.v); } } void circle(const canvas::Circle &c) { for (int x = -c.radius; x < c.radius; ++x) { int size_y = std::sqrt(c.radius * c.radius - std::abs(x) * std::abs(x)); - std::fill(screen_at(c.pos.x + x, c.pos.y - size_y), - screen_at(c.pos.x + x, c.pos.y + size_y), c.color.v); + std::fill(screen_at({.x = c.pos.x + x, .y = c.pos.y - size_y}), + screen_at({.x = c.pos.x + x, .y = c.pos.y + size_y}), c.color.v); } } diff --git a/src/Game.cpp b/src/Game.cpp index d3dfb33..c3a3956 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -6,6 +6,7 @@ // #include #include "Map.hpp" +#include "Params.hpp" #include "Player.hpp" #include "Snake.hpp" #include "Utils.hpp" @@ -43,8 +44,8 @@ World world; Map map{{ .gen_interval = 1.0, .food_exists_gens = 10, - .gen_food_count = 1000, - .size = {.x = 20000, .y = 20000}, + .gen_food_count = 100, // 1000, + .size = WORLD_SIZE, .min_food_weight = 1, .max_food_weight = 5, .food_color = {color::RED}, @@ -68,8 +69,8 @@ void act(float dt) { map.act(dt); world.cursor = utils::get_cursor(); - if (world.cursor != world.prev_cursor and utils::is_valid_pos(world.cursor)) { - Vecf diff(world.cursor - utils::get_center()); // - pos; + if (world.cursor != world.prev_cursor and utils::is_on_screen(world.cursor)) { + Vecf diff(world.cursor - utils::get_screen_center()); // - pos; if (diff.len() > MIN_CONTROL_DISTANCE) { player.direction = diff.norm(); @@ -87,7 +88,8 @@ void act(float dt) { snake.add(Veci(player.pos)); } - int eaten = map.eat(Veci(player.pos), 20); + int eaten = map.eat( + utils::to_world_coord(Veci(player.pos) + utils::get_screen_center()), 20); snake.inc_length(eaten); // TODO @@ -108,9 +110,9 @@ void draw() { // clear backbuffer memset(buffer, 0, SCREEN_HEIGHT * SCREEN_WIDTH * sizeof(uint32_t)); - Veci map_offset = Veci(/*player.pos*/ snake.get_pos()) - utils::get_center(); + Veci map_offset = Veci(snake.get_pos()); - snake.draw(map_offset); + snake.draw(map_offset - utils::get_screen_center()); map.draw(map_offset); }