feat: Grid af spawning
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
#include "dxd_math.hpp"
|
#include "dxd_math.hpp"
|
||||||
|
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
vec2 operator+(vec2 const &v)
|
vec2 operator+(vec2 const &v)
|
||||||
{
|
{
|
||||||
return { .x = v.x, .y = v.y };
|
return { .x = v.x, .y = v.y };
|
||||||
@@ -40,6 +42,16 @@ bool operator>(vec2 const &a, vec2 const &b)
|
|||||||
return a.x > b.x && a.y > b.y;
|
return a.x > b.x && a.y > b.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator<(vec2i const &a, vec2i const &b)
|
||||||
|
{
|
||||||
|
return a.x < b.x && a.y < b.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator>(vec2i const &a, vec2i const &b)
|
||||||
|
{
|
||||||
|
return a.x > b.x && a.y > b.y;
|
||||||
|
}
|
||||||
|
|
||||||
float dot(vec2 const &a, vec2 const &b)
|
float dot(vec2 const &a, vec2 const &b)
|
||||||
{
|
{
|
||||||
return a.x * b.x + a.y * b.y;
|
return a.x * b.x + a.y * b.y;
|
||||||
@@ -76,7 +88,7 @@ vec2 max2(vec2 const &a, vec2 const &b)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 polar_to_vec2(const float angle, const float len)
|
vec2 polar_to_vec2(float const angle, float const len)
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
.x = len * sinf(angle),
|
.x = len * sinf(angle),
|
||||||
@@ -84,11 +96,16 @@ vec2 polar_to_vec2(const float angle, const float len)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
float vec2_angle(const vec2 v)
|
float vec2_angle(vec2 const v)
|
||||||
{
|
{
|
||||||
return atan2f(v.x, v.y);
|
return atan2f(v.x, v.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec2 v2i_to_v2(vec2i const v)
|
||||||
|
{
|
||||||
|
return { (float)v.x, (float)v.y };
|
||||||
|
}
|
||||||
|
|
||||||
float normalize_angle(const float angle)
|
float normalize_angle(const float angle)
|
||||||
{
|
{
|
||||||
float a = angle;
|
float a = angle;
|
||||||
@@ -104,3 +121,28 @@ float normalize_angle_diff(const float diff)
|
|||||||
while (d < -M_PIf) d += 2*M_PIf;
|
while (d < -M_PIf) d += 2*M_PIf;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int rand_int(int const min, int const max)
|
||||||
|
{
|
||||||
|
return SDL_rand(max - min) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rand_float(float const min, float const max)
|
||||||
|
{
|
||||||
|
return SDL_randf() * (max - min) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rand_angle()
|
||||||
|
{
|
||||||
|
return rand_float(0, 2*M_PIf);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2i rand_v2i(vec2i const min, vec2i const max)
|
||||||
|
{
|
||||||
|
return { rand_int(min.x, max.x), rand_int(min.y, max.y) };
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 rand_v2(vec2 const min, vec2 const max)
|
||||||
|
{
|
||||||
|
return { rand_float(min.x, max.x), rand_float(min.y, max.y) };
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ static const vec2 vec2_min = { -FLT_MAX, -FLT_MAX };
|
|||||||
static const vec2i vec2i_zero = { 0, 0 };
|
static const vec2i vec2i_zero = { 0, 0 };
|
||||||
static const vec2i vec2i_one = { 1, 1 };
|
static const vec2i vec2i_one = { 1, 1 };
|
||||||
|
|
||||||
|
// vec2 operators
|
||||||
vec2 operator+(vec2 const &v);
|
vec2 operator+(vec2 const &v);
|
||||||
vec2 operator-(vec2 const &v);
|
vec2 operator-(vec2 const &v);
|
||||||
vec2 operator+(vec2 const &a, vec2 const &b);
|
vec2 operator+(vec2 const &a, vec2 const &b);
|
||||||
@@ -26,15 +27,30 @@ vec2 operator/(vec2 const &a, float const &b);
|
|||||||
bool operator<(vec2 const &a, vec2 const &b);
|
bool operator<(vec2 const &a, vec2 const &b);
|
||||||
bool operator>(vec2 const &a, vec2 const &b);
|
bool operator>(vec2 const &a, vec2 const &b);
|
||||||
|
|
||||||
|
// vec2i operators
|
||||||
|
bool operator<(vec2i const &a, vec2i const &b);
|
||||||
|
bool operator>(vec2i const &a, vec2i const &b);
|
||||||
|
|
||||||
|
// vec2 functions
|
||||||
float dot(vec2 const &a, vec2 const &b);
|
float dot(vec2 const &a, vec2 const &b);
|
||||||
float norm2(vec2 const &v);
|
float norm2(vec2 const &v);
|
||||||
float norm(vec2 const &v);
|
float norm(vec2 const &v);
|
||||||
vec2 normalize(vec2 const &v);
|
vec2 normalize(vec2 const &v);
|
||||||
vec2 min2(vec2 const &a, vec2 const &b);
|
vec2 min2(vec2 const &a, vec2 const &b);
|
||||||
vec2 max2(vec2 const &a, vec2 const &b);
|
vec2 max2(vec2 const &a, vec2 const &b);
|
||||||
|
vec2 polar_to_vec2(float const angle, float const len);
|
||||||
|
float vec2_angle(vec2 const v);
|
||||||
|
|
||||||
vec2 polar_to_vec2(const float angle, const float len);
|
// vec2i functions
|
||||||
float vec2_angle(const vec2 v);
|
vec2 v2i_to_v2(vec2i const v);
|
||||||
|
|
||||||
float normalize_angle(const float angle);
|
// Angle functions
|
||||||
float normalize_angle_diff(const float diff);
|
float normalize_angle(float const angle);
|
||||||
|
float normalize_angle_diff(float const diff);
|
||||||
|
|
||||||
|
// Random generation functions
|
||||||
|
int rand_int(int const min, int const max);
|
||||||
|
float rand_float(float const min, float const max);
|
||||||
|
float rand_angle();
|
||||||
|
vec2i rand_v2i(vec2i const min, vec2i const max);
|
||||||
|
vec2 rand_v2(vec2 const min, vec2 const max);
|
||||||
|
|||||||
12
src/main.cpp
12
src/main.cpp
@@ -45,7 +45,7 @@ int main(int argc, char *argv[])
|
|||||||
dxd::Renderer renderer = dxd::Renderer(sdl_renderer, width, height);
|
dxd::Renderer renderer = dxd::Renderer(sdl_renderer, width, height);
|
||||||
|
|
||||||
// World init
|
// World init
|
||||||
dxd::sim::World world = dxd::sim::World({ .x = 10, .y = 10 });
|
dxd::sim::World world = dxd::sim::World();
|
||||||
world.add_obj(new dxd::sim::AFSpawner());
|
world.add_obj(new dxd::sim::AFSpawner());
|
||||||
|
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
@@ -79,11 +79,17 @@ int main(int argc, char *argv[])
|
|||||||
world.draw(&renderer);
|
world.draw(&renderer);
|
||||||
world.tick(1.0f / 60.0f);
|
world.tick(1.0f / 60.0f);
|
||||||
|
|
||||||
// Usual test
|
// World axis
|
||||||
renderer.color(64, 64, 64, 255);
|
renderer.color(32, 32, 32, 255);
|
||||||
renderer.line(-vec2_unity * 2000, vec2_unity * 2000);
|
renderer.line(-vec2_unity * 2000, vec2_unity * 2000);
|
||||||
renderer.line(-vec2_unitx * 2000, vec2_unitx * 2000);
|
renderer.line(-vec2_unitx * 2000, vec2_unitx * 2000);
|
||||||
|
|
||||||
|
// Scale and position
|
||||||
|
vec2 center = renderer.get_camera_pos();
|
||||||
|
float zoom = 100.0f/renderer.get_zoom();
|
||||||
|
renderer.color(128, 128, 255, 255);
|
||||||
|
renderer.dbg_txt(0, 0, "(%0.1f, %0.1f) @%0.2f", center.x, center.y, zoom);
|
||||||
|
|
||||||
SDL_RenderPresent(sdl_renderer);
|
SDL_RenderPresent(sdl_renderer);
|
||||||
SDL_Delay(1000 / 60);
|
SDL_Delay(1000 / 60);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ public:
|
|||||||
_scale /= 1 + delta;
|
_scale /= 1 + delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec2 get_camera_pos()
|
||||||
|
{
|
||||||
|
return _center;
|
||||||
|
}
|
||||||
|
|
||||||
float get_zoom()
|
float get_zoom()
|
||||||
{
|
{
|
||||||
return 1.0f / _scale;
|
return 1.0f / _scale;
|
||||||
@@ -120,6 +125,16 @@ public:
|
|||||||
points[4] = points[0];
|
points[4] = points[0];
|
||||||
SDL_RenderLines(_sdl, points, 5);
|
SDL_RenderLines(_sdl, points, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dbg_txt(float x, float y, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
SDL_RenderDebugTextFormat(_sdl, x, y, fmt, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dxd
|
} // namespace dxd
|
||||||
|
|||||||
@@ -11,9 +11,22 @@ void dxd::sim::AFSpawner::tick(float timestep, World *world)
|
|||||||
|
|
||||||
_next_spawn = _MIN_SPAWN_DELAY + SDL_rand(_MAX_SPAWN_DELAY);
|
_next_spawn = _MIN_SPAWN_DELAY + SDL_rand(_MAX_SPAWN_DELAY);
|
||||||
|
|
||||||
//Pos should spawn in a grid, check if free, and offset random from grid coord to look natural
|
vec2i base_pos;
|
||||||
vec2 pos = {(SDL_randf()-.5f)*2*60.0f, (SDL_randf()-.5f)*2*60.0f};
|
//TODO: Set limiter
|
||||||
|
do
|
||||||
|
base_pos = rand_v2i({ -_GRID_BOUNDS, -_GRID_BOUNDS }, { _GRID_BOUNDS, _GRID_BOUNDS });
|
||||||
|
while (_airfields.find(base_pos) != _airfields.end());
|
||||||
|
|
||||||
|
vec2 off = rand_v2({ -_GRID_JITTER, -_GRID_JITTER }, { _GRID_JITTER, _GRID_JITTER });
|
||||||
|
vec2 pos = v2i_to_v2(base_pos) * _GRID_STRIDE + off;
|
||||||
|
|
||||||
Airfield *af = new Airfield(pos, _MIN_AF_TTL + SDL_rand(_MAX_AF_TTL), SDL_randf()*2*M_PIf);
|
Airfield *af = new Airfield(pos, _MIN_AF_TTL + SDL_rand(_MAX_AF_TTL), SDL_randf()*2*M_PIf);
|
||||||
world->add_obj(af);
|
world->add_obj(af);
|
||||||
_airfields.push_back(af);
|
_airfields.emplace(base_pos, af);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dxd::sim::AFSpawner::draw(Renderer *rend)
|
||||||
|
{
|
||||||
|
rend->color(0, 127, 0, 255);
|
||||||
|
rend->rect(vec2_zero, _SPAWN_BOUNDS*2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "../dxd_math.hpp"
|
#include "../dxd_math.hpp"
|
||||||
#include "world_object.hpp"
|
#include "world_object.hpp"
|
||||||
@@ -12,23 +13,29 @@ namespace dxd::sim
|
|||||||
class AFSpawner : public WorldObject
|
class AFSpawner : public WorldObject
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::vector<Airfield*> _airfields;
|
std::map<vec2i, Airfield*> _airfields;
|
||||||
int _next_spawn;
|
int _next_spawn;
|
||||||
|
|
||||||
|
const int _SPAWN_BOUNDS = 150;
|
||||||
|
const int _GRID_STRIDE = 4;
|
||||||
|
const int _GRID_MARGIN = 5;
|
||||||
|
const int _GRID_BOUNDS = (_SPAWN_BOUNDS - _GRID_MARGIN * 2) / _GRID_STRIDE;
|
||||||
|
const float _GRID_JITTER = (float)_GRID_STRIDE * 0.4f;
|
||||||
|
|
||||||
const int _MIN_SPAWN_DELAY = 450;
|
const int _MIN_SPAWN_DELAY = 450;
|
||||||
const int _MAX_SPAWN_DELAY = 3000;
|
const int _MAX_SPAWN_DELAY = 3000;
|
||||||
const int _MIN_AF_TTL = 1200;
|
const int _MIN_AF_TTL = 3000;
|
||||||
const int _MAX_AF_TTL = 6000;
|
const int _MAX_AF_TTL = 9000;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AFSpawner()
|
AFSpawner()
|
||||||
{
|
{
|
||||||
_airfields = std::vector<Airfield*>();
|
_airfields = std::map<vec2i, Airfield*>();
|
||||||
_next_spawn = 1;
|
_next_spawn = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tick(float timestep, World *world) override;
|
void tick(float timestep, World *world) override;
|
||||||
void draw(Renderer *rend) override { (void)rend; }
|
void draw(Renderer *rend) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dxd::sim
|
} // namespace dxd::sim
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ private:
|
|||||||
|
|
||||||
const int _TRAIL_DELAY = 60;
|
const int _TRAIL_DELAY = 60;
|
||||||
const int _TRAIL_DURATION = 420;
|
const int _TRAIL_DURATION = 420;
|
||||||
const float _MAX_TURN_RATE = 0.5f;
|
const float _MAX_TURN_RATE = 0.3f;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Aircraft(vec2 position, float direction, float speed, vec2 target)
|
Aircraft(vec2 position, float direction, float speed, vec2 target)
|
||||||
|
|||||||
@@ -14,12 +14,10 @@ void dxd::sim::Airfield::tick(float timestep, World *world)
|
|||||||
if (--_next_spawn == 0)
|
if (--_next_spawn == 0)
|
||||||
{
|
{
|
||||||
vec2 pos = _position + polar_to_vec2(_rw_heading, _WR_LENGTH+0.5);
|
vec2 pos = _position + polar_to_vec2(_rw_heading, _WR_LENGTH+0.5);
|
||||||
//vec2 tgt = _position + polar_to_vec2(SDL_randf()*2*M_PIf, 30);
|
vec2 tgt = _position + polar_to_vec2(SDL_randf()*2*M_PIf, 30);
|
||||||
vec2 tgt = _position + polar_to_vec2(0, 30);
|
Aircraft *af = new Aircraft(pos, _rw_heading, 2.0f, tgt);
|
||||||
Aircraft *af = new Aircraft(pos, _rw_heading, 5.0f, tgt);
|
|
||||||
world->add_obj(af);
|
world->add_obj(af);
|
||||||
//_next_spawn = _MIN_TAKEOFF_DELAY + SDL_rand(_MAX_TAKEOFF_DELAY - _MIN_TAKEOFF_DELAY);
|
_next_spawn = _MIN_TAKEOFF_DELAY + SDL_rand(_MAX_TAKEOFF_DELAY - _MIN_TAKEOFF_DELAY);
|
||||||
_next_spawn = 99999999;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,13 +13,12 @@ class WorldObject;
|
|||||||
class World
|
class World
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
vec2 _size;
|
|
||||||
std::vector<WorldObject*> _objs;
|
std::vector<WorldObject*> _objs;
|
||||||
std::vector<WorldObject*> _pending_removes;
|
std::vector<WorldObject*> _pending_removes;
|
||||||
std::vector<WorldObject*> _pending_adds;
|
std::vector<WorldObject*> _pending_adds;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
World(vec2 size) : _size(size)
|
World()
|
||||||
{
|
{
|
||||||
_objs = std::vector<WorldObject*>();
|
_objs = std::vector<WorldObject*>();
|
||||||
_pending_adds = std::vector<WorldObject*>();
|
_pending_adds = std::vector<WorldObject*>();
|
||||||
|
|||||||
Reference in New Issue
Block a user