initial game

This commit is contained in:
programsnail 2024-07-22 21:22:52 +03:00
parent 4570d6e593
commit adabb50a9e
10 changed files with 200 additions and 132 deletions

View file

@ -1,12 +1,9 @@
#pragma once
#include <algorithm>
#include <cmath>
#include <vector>
#
#include "Engine.h"
#include "Utils.hpp"
#include "Vec.hpp"
enum class Color : uint32_t {
BLACK = 0x000000ff,
@ -25,99 +22,27 @@ constexpr Color CL_BG = Color::BLACK;
using Screen = uint32_t[SCREEN_HEIGHT][SCREEN_WIDTH];
class CanvasObject {
public:
struct Config {
Veci pos;
int size;
Color color = Color ::WHITE;
};
CanvasObject(Config config)
: pos_(config.pos), size_(config.size), color_(config.color),
shown_(false) {}
namespace canvas {
virtual void move_to(Veci) = 0;
virtual void show() = 0;
virtual void hide() = 0;
virtual ~CanvasObject() {
if (shown_) {
// hide(); // TODO
}
}
protected:
Veci pos_;
int size_;
Color color_;
bool shown_;
struct Object {
Veci pos;
Color color;
};
class StatelessCanvasObject : public CanvasObject {
public:
using CanvasObject::CanvasObject;
void move_to(Veci pos) override {
if (not shown_) {
return;
}
hide();
pos_ = pos;
show();
}
void show() override { fill(color_); }
void hide() override { fill(CL_BG); }
protected:
virtual void fill(Color color) = 0;
struct Square : public Object {
int side;
};
class Square : public StatelessCanvasObject {
public:
using StatelessCanvasObject::StatelessCanvasObject;
protected:
void fill(Color color) override {
for (int x = pos_.x; x < pos_.x + size_; ++x) {
std::fill(screen_at(x, pos_.y), screen_at(x, pos_.y + size_),
static_cast<uint32_t>(color));
}
}
struct Circle : public Object {
int radius;
};
class Circle : public StatelessCanvasObject {
public:
using StatelessCanvasObject::StatelessCanvasObject;
} // namespace canvas
protected:
void fill(Color color) override {
for (int x = -size_; x < size_; ++x) {
int size_y = std::sqrt(size_ * size_ - std::abs(x) * std::abs(x));
std::fill(screen_at(pos_.x + x, pos_.y - size_y),
screen_at(pos_.x + x, pos_.y + size_y),
static_cast<uint32_t>(color));
}
}
};
namespace paint {
class Worm : public CanvasObject {
Worm(CanvasObject::Config config, size_t max_track_size)
: CanvasObject(config), max_track_size_(max_track_size) {}
void square(const canvas::Square &s);
protected:
const size_t max_track_size_;
std::vector<Circle> track_;
};
void circle(const canvas::Circle &c);
// class Canvas {
// public:
// Canvas(Screen &screen) : screen_(screen) {}
// size_t insert(CanvasObject obj) {}
// void erase(size_t id) {}
// private:
// Screen &screen_;
// };
} // namespace paint

View file

@ -2,6 +2,7 @@
#include <deque>
#include "Canvas.hpp"
#include "Utils.hpp"
#include "Vec.hpp"
@ -13,17 +14,23 @@ class Map : public GameObject {
bool eaten = false;
};
static constexpr double GEN_INTERVAL = 1.0;
static constexpr size_t FOOD_EXISTS_GENS = 10;
static constexpr size_t GEN_FOOD_COUNT = 1000;
static constexpr int SIZE_X = 20000;
static constexpr int SIZE_Y = 20000;
public:
struct Config {
double gen_interval;
size_t food_exists_gens;
size_t gen_food_count;
Veci size;
int min_food_weight;
int max_food_weight;
Color food_color;
};
Map(Config config) : config_(config) {}
void act(float dt) override {
time_from_last_gen_ += dt;
if (time_from_last_gen_ > GEN_INTERVAL) {
time_from_last_gen_ -= GEN_INTERVAL;
if (time_from_last_gen_ > config_.gen_interval) {
time_from_last_gen_ -= config_.gen_interval;
generate();
}
}
@ -39,23 +46,36 @@ public:
return eaten_weight;
}
void draw() override {} // TODO
private:
void generate() {
++current_gen_;
while (food_.front().gen + FOOD_EXISTS_GENS < current_gen_) {
food_.pop_front();
}
for (size_t i = 0; i < GEN_FOOD_COUNT; ++i) {
food_.push_back({.gen = current_gen_,
.pos = {.x = rand() % SIZE_X, .y = rand() % SIZE_Y},
.weight = 1});
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) {
paint::circle(
{{.pos = food_pos, .color = config_.food_color}, food.weight * 3});
}
}
}
private:
void generate() {
++current_gen_;
while (food_.front().gen + config_.food_exists_gens < current_gen_) {
food_.pop_front();
}
for (size_t i = 0; i < config_.gen_food_count; ++i) {
food_.push_back({
.gen = current_gen_,
.pos = {.x = rand() % config_.size.x, .y = rand() % config_.size.y},
.weight = config_.min_food_weight +
rand() % std::abs(config_.max_food_weight -
config_.min_food_weight),
});
}
}
private:
Config config_;
double time_from_last_gen_ = 0;
size_t current_gen_ = 0;
std::deque<Food> food_ = {};

View file

@ -1,6 +1,8 @@
#pragma once
class Player {
public:
private:
#include "Vec.hpp"
struct Player {
Vecf pos;
Vecf direction;
};

View file

@ -0,0 +1,38 @@
#pragma once
#include <deque>
#include "Canvas.hpp"
namespace canvas {
struct WormObject : public Object {
size_t length;
int radius;
};
} // namespace canvas
class Worm : protected canvas::WormObject {
public:
Worm(canvas::WormObject obj) : WormObject(obj), track_{pos} {}
void add(Veci pos);
void draw(Veci offset = {}) const;
size_t get_length() { return length; }
void set_length(size_t length) { this->length = length; }
void inc_length(int inc) {
if (-inc > static_cast<int>(length)) {
length = 0;
} else {
length += inc;
}
}
protected:
std::deque<Veci> track_;
};

View file

@ -5,6 +5,8 @@
#include "Engine.h"
#include "Vec.hpp"
namespace utils {
namespace safe {
inline int lx(int x) { return std::max(0, x); }
@ -30,12 +32,18 @@ template <typename T> inline bool is_valid_pos(Vec<T> pos) {
inline Veci get_cursor() { return {.x = get_cursor_y(), .y = get_cursor_x()}; }
inline constexpr Veci get_center() {
return {.x = SCREEN_HEIGHT / 2, .y = SCREEN_WIDTH / 2};
}
} // namespace utils
//
class GameObject {
public:
virtual void act(float dt) = 0;
virtual void draw() = 0;
virtual void draw(Veci offset) = 0;
virtual ~GameObject() {}
};

View file

@ -3,13 +3,13 @@
#include <cmath>
template <typename T> struct Vec {
T x;
T y;
T x = {};
T y = {};
//
template <typename U> explicit operator Vec<U>() {
return Vec<U>{.x = x, .y = y};
return Vec<U>{.x = static_cast<U>(x), .y = static_cast<U>(y)};
}
//

9
include/World.hpp Normal file
View file

@ -0,0 +1,9 @@
#pragma once
#include "Vec.hpp"
struct World {
float game_time = {};
Veci prev_cursor = {};
Veci cursor = {};
};