feat: Primitive airfield navigation
This commit is contained in:
@@ -2,17 +2,10 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
void dxd::sim::AFSpawner::tick(float timestep, World *world)
|
void dxd::sim::AFSpawner::spawn_airfield(World *world)
|
||||||
{
|
{
|
||||||
(void)timestep;
|
|
||||||
|
|
||||||
if (--_next_spawn != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_next_spawn = _MIN_SPAWN_DELAY + SDL_rand(_MAX_SPAWN_DELAY);
|
|
||||||
|
|
||||||
vec2i base_pos;
|
vec2i base_pos;
|
||||||
//TODO: Set limiter
|
//TODO: Iter limiter
|
||||||
do
|
do
|
||||||
base_pos = rand_v2i({ -_GRID_BOUNDS, -_GRID_BOUNDS }, { _GRID_BOUNDS, _GRID_BOUNDS });
|
base_pos = rand_v2i({ -_GRID_BOUNDS, -_GRID_BOUNDS }, { _GRID_BOUNDS, _GRID_BOUNDS });
|
||||||
while (_airfields.find(base_pos) != _airfields.end());
|
while (_airfields.find(base_pos) != _airfields.end());
|
||||||
@@ -20,13 +13,50 @@ void dxd::sim::AFSpawner::tick(float timestep, World *world)
|
|||||||
vec2 off = rand_v2({ -_GRID_JITTER, -_GRID_JITTER }, { _GRID_JITTER, _GRID_JITTER });
|
vec2 off = rand_v2({ -_GRID_JITTER, -_GRID_JITTER }, { _GRID_JITTER, _GRID_JITTER });
|
||||||
vec2 pos = v2i_to_v2(base_pos) * _GRID_STRIDE + off;
|
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(this, pos, _MIN_AF_TTL + SDL_rand(_MAX_AF_TTL), SDL_randf()*2*M_PIf);
|
||||||
world->add_obj(af);
|
world->add_obj(af);
|
||||||
_airfields.emplace(base_pos, af);
|
_airfields.emplace(base_pos, af);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dxd::sim::AFSpawner::tick(float timestep, World *world)
|
||||||
|
{
|
||||||
|
(void)timestep;
|
||||||
|
|
||||||
|
if (_next_spawn == -1) //Init
|
||||||
|
{
|
||||||
|
spawn_airfield(world);
|
||||||
|
spawn_airfield(world);
|
||||||
|
_next_spawn = _MIN_SPAWN_DELAY;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (--_next_spawn != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_next_spawn = _MIN_SPAWN_DELAY + SDL_rand(_MAX_SPAWN_DELAY);
|
||||||
|
|
||||||
|
spawn_airfield(world);
|
||||||
|
}
|
||||||
|
|
||||||
void dxd::sim::AFSpawner::draw(Renderer *rend)
|
void dxd::sim::AFSpawner::draw(Renderer *rend)
|
||||||
{
|
{
|
||||||
rend->color(0, 127, 0);
|
rend->color(0, 127, 0);
|
||||||
rend->rect(vec2_zero, _SPAWN_BOUNDS*2);
|
rend->rect(vec2_zero, _SPAWN_BOUNDS*2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dxd::sim::Airfield *dxd::sim::AFSpawner::get_random_airfield(Airfield *exclude)
|
||||||
|
{
|
||||||
|
int count = (int)_airfields.size();
|
||||||
|
Airfield *af = exclude;
|
||||||
|
|
||||||
|
//TODO: Iter limiter
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int sel = rand_int(0, count);
|
||||||
|
auto it = _airfields.begin();
|
||||||
|
for (; it != _airfields.end() && sel; ++it, --sel);
|
||||||
|
af = it->second;
|
||||||
|
} while(af == exclude);
|
||||||
|
|
||||||
|
return af;
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
namespace dxd::sim
|
namespace dxd::sim
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class Airfield;
|
||||||
|
|
||||||
class AFSpawner : public WorldObject
|
class AFSpawner : public WorldObject
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -27,15 +29,19 @@ private:
|
|||||||
const int _MIN_AF_TTL = 3000;
|
const int _MIN_AF_TTL = 3000;
|
||||||
const int _MAX_AF_TTL = 9000;
|
const int _MAX_AF_TTL = 9000;
|
||||||
|
|
||||||
|
void spawn_airfield(World *world);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AFSpawner()
|
AFSpawner()
|
||||||
{
|
{
|
||||||
_airfields = std::map<vec2i, 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 draw(Renderer *rend) override;
|
||||||
|
|
||||||
|
Airfield *get_random_airfield(Airfield *exclude);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dxd::sim
|
} // namespace dxd::sim
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ private:
|
|||||||
int _trail_cooldown;
|
int _trail_cooldown;
|
||||||
|
|
||||||
const int _TRAIL_DELAY = 120;
|
const int _TRAIL_DELAY = 120;
|
||||||
const int _TRAIL_DURATION = 420;
|
const int _TRAIL_DURATION = 600;
|
||||||
const float _MAX_TURN_RATE = 0.3f;
|
const float _MAX_TURN_RATE = 0.3f;
|
||||||
const float _SPD_TO_KTS = 60.0f;
|
const float _SPD_TO_KTS = 60.0f;
|
||||||
|
|
||||||
|
|||||||
@@ -8,15 +8,20 @@ void dxd::sim::Airfield::tick(float timestep, World *world)
|
|||||||
if (--_ttl == 0)
|
if (--_ttl == 0)
|
||||||
{
|
{
|
||||||
world->remove_obj(this);
|
world->remove_obj(this);
|
||||||
|
//TODO: Free space in af_spawner
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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, _RW_LENGTH+0.5);
|
||||||
vec2 tgt = _position + polar_to_vec2(SDL_randf()*2*M_PIf, 30);
|
|
||||||
Aircraft *af = new Aircraft(pos, _rw_heading, 2.0f, tgt);
|
Airfield *target = _parent->get_random_airfield(this);
|
||||||
|
vec2 tgt_pos = target->get_position();
|
||||||
|
|
||||||
|
Aircraft *af = new Aircraft(pos, _rw_heading, 2.0f, tgt_pos);
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,7 +33,7 @@ void dxd::sim::Airfield::draw(Renderer *rend)
|
|||||||
rend->diamond(_position, 5);
|
rend->diamond(_position, 5);
|
||||||
|
|
||||||
rend->color(64, 64, 255);
|
rend->color(64, 64, 255);
|
||||||
vec2 a = _position + polar_to_vec2(_rw_heading, +_WR_LENGTH);
|
vec2 a = _position + polar_to_vec2(_rw_heading, +_RW_LENGTH);
|
||||||
vec2 b = _position + polar_to_vec2(_rw_heading, -_WR_LENGTH);
|
vec2 b = _position + polar_to_vec2(_rw_heading, -_RW_LENGTH);
|
||||||
rend->line(a, b);
|
rend->line(a, b);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,29 +4,35 @@
|
|||||||
|
|
||||||
#include "../dxd_math.hpp"
|
#include "../dxd_math.hpp"
|
||||||
#include "world_object.hpp"
|
#include "world_object.hpp"
|
||||||
|
#include "af_spawner.hpp"
|
||||||
|
|
||||||
namespace dxd::sim
|
namespace dxd::sim
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class AFSpawner;
|
||||||
|
|
||||||
class Airfield : public WorldObject
|
class Airfield : public WorldObject
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
AFSpawner *_parent;
|
||||||
vec2 _position;
|
vec2 _position;
|
||||||
int _ttl;
|
int _ttl;
|
||||||
int _next_spawn;
|
int _next_spawn;
|
||||||
float _rw_heading;
|
float _rw_heading;
|
||||||
|
|
||||||
const int _MIN_TAKEOFF_DELAY = 240;
|
int const _MIN_TAKEOFF_DELAY = 600;
|
||||||
const int _MAX_TAKEOFF_DELAY = 600;
|
int const _MAX_TAKEOFF_DELAY = 3000;
|
||||||
const int _WR_LENGTH = 6;
|
int const _RW_LENGTH = 6;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Airfield(vec2 position, int ttl, float rw_heading)
|
Airfield(AFSpawner *parent, vec2 position, int ttl, float rw_heading)
|
||||||
: _position(position), _ttl(ttl), _rw_heading(rw_heading)
|
: _parent(parent), _position(position), _ttl(ttl), _rw_heading(rw_heading)
|
||||||
{
|
{
|
||||||
_next_spawn = _MIN_TAKEOFF_DELAY;
|
_next_spawn = _MIN_TAKEOFF_DELAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec2 get_position() { return _position; }
|
||||||
|
|
||||||
void tick(float timestep, World *world) override;
|
void tick(float timestep, World *world) override;
|
||||||
void draw(Renderer *rend) override;
|
void draw(Renderer *rend) override;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user