feat: Approaches and referenced airfields

This commit is contained in:
2026-04-28 14:42:02 +01:00
parent d1ff0e6a15
commit 668d8b47be
8 changed files with 47 additions and 9 deletions

View File

@@ -42,6 +42,11 @@ 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==(vec2 const &a, vec2 const &b)
{
return a.x == b.x && a.y == b.y;
}
bool operator<(vec2i const &a, vec2i const &b) bool operator<(vec2i const &a, vec2i const &b)
{ {
return a.x < b.x && a.y < b.y; return a.x < b.x && a.y < b.y;

View File

@@ -26,6 +26,7 @@ vec2 operator*(vec2 const &a, float const &b);
vec2 operator/(vec2 const &a, float const &b); 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);
bool operator==(vec2 const &a, vec2 const &b);
// vec2i operators // vec2i operators
bool operator<(vec2i const &a, vec2i const &b); bool operator<(vec2i const &a, vec2i const &b);

View File

@@ -56,6 +56,8 @@ dxd::sim::Airfield *dxd::sim::AFSpawner::get_random_airfield(Airfield *exclude)
auto it = _airfields.begin(); auto it = _airfields.begin();
for (; it != _airfields.end() && sel; ++it, --sel); for (; it != _airfields.end() && sel; ++it, --sel);
af = it->second; af = it->second;
if (!af->is_active())
af = exclude;
} while(af == exclude); } while(af == exclude);
return af; return af;

View File

@@ -19,7 +19,7 @@ private:
int _next_spawn; int _next_spawn;
const int _SPAWN_BOUNDS = 150; const int _SPAWN_BOUNDS = 150;
const int _GRID_STRIDE = 4; const int _GRID_STRIDE = 10;
const int _GRID_MARGIN = 5; const int _GRID_MARGIN = 5;
const int _GRID_BOUNDS = (_SPAWN_BOUNDS - _GRID_MARGIN * 2) / _GRID_STRIDE; const int _GRID_BOUNDS = (_SPAWN_BOUNDS - _GRID_MARGIN * 2) / _GRID_STRIDE;
const float _GRID_JITTER = (float)_GRID_STRIDE * 0.4f; const float _GRID_JITTER = (float)_GRID_STRIDE * 0.4f;

View File

@@ -3,7 +3,17 @@
void dxd::sim::Aircraft::tick(float timestep, World *world) void dxd::sim::Aircraft::tick(float timestep, World *world)
{ {
(void)world; // Refactor into own function
float target_dist = norm2(_target - _position);
if (target_dist < _TARGET_REACHED_DIST2)
{
if (_target == _destination->get_position())
{
_destination->arrived_at();
world->remove_obj(this);
}
_target = _destination->get_position();
}
float target_angle = vec2_angle(_target - _position); float target_angle = vec2_angle(_target - _position);
float target_deviation = target_angle - _direction; float target_deviation = target_angle - _direction;

View File

@@ -2,6 +2,7 @@
#include "../dxd_math.hpp" #include "../dxd_math.hpp"
#include "world_object.hpp" #include "world_object.hpp"
#include "airfield.hpp"
namespace dxd::sim namespace dxd::sim
{ {
@@ -12,6 +13,7 @@ private:
vec2 _position; vec2 _position;
float _direction; float _direction;
float _speed; float _speed;
Airfield *_destination;
vec2 _target; vec2 _target;
int _trail_cooldown; int _trail_cooldown;
@@ -19,12 +21,16 @@ private:
const int _TRAIL_DURATION = 600; 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;
const float _TARGET_REACHED_DIST = 0.5f;
const float _TARGET_REACHED_DIST2 = _TARGET_REACHED_DIST*_TARGET_REACHED_DIST;
public: public:
Aircraft(vec2 position, float direction, float speed, vec2 target) Aircraft(vec2 position, float direction, float speed, Airfield *destination)
: _position(position), _direction(direction), _speed(speed), _target(target) : _position(position), _direction(direction), _speed(speed), _destination(destination)
{ {
_trail_cooldown = _TRAIL_DELAY; _trail_cooldown = _TRAIL_DELAY;
_target = destination->get_approach_point();
destination->going_to();
} }
void tick(float timestep, World *world) override; void tick(float timestep, World *world) override;

View File

@@ -5,10 +5,13 @@ void dxd::sim::Airfield::tick(float timestep, World *world)
{ {
(void)timestep; (void)timestep;
if (--_ttl == 0) if (--_ttl <= 0)
{ {
world->remove_obj(this); if (_pending_arrivals == 0)
//TODO: Free space in af_spawner {
world->remove_obj(this);
//TODO: Free space in af_spawner
}
return; return;
} }
@@ -17,9 +20,8 @@ void dxd::sim::Airfield::tick(float timestep, World *world)
vec2 pos = _position + polar_to_vec2(_rw_heading, _RW_LENGTH+0.5); vec2 pos = _position + polar_to_vec2(_rw_heading, _RW_LENGTH+0.5);
Airfield *target = _parent->get_random_airfield(this); Airfield *target = _parent->get_random_airfield(this);
vec2 tgt_pos = target->get_position();
Aircraft *af = new Aircraft(pos, _rw_heading, 2.0f, tgt_pos); Aircraft *af = new Aircraft(pos, _rw_heading, 2.0f, target);
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);
@@ -37,3 +39,8 @@ void dxd::sim::Airfield::draw(Renderer *rend)
vec2 b = _position + polar_to_vec2(_rw_heading, -_RW_LENGTH); vec2 b = _position + polar_to_vec2(_rw_heading, -_RW_LENGTH);
rend->line(a, b); rend->line(a, b);
} }
vec2 dxd::sim::Airfield::get_approach_point()
{
return _position - polar_to_vec2(_rw_heading, _RW_LENGTH + _APPROACH_DIST);
}

View File

@@ -20,9 +20,12 @@ private:
int _next_spawn; int _next_spawn;
float _rw_heading; float _rw_heading;
int _pending_arrivals;
int const _MIN_TAKEOFF_DELAY = 600; int const _MIN_TAKEOFF_DELAY = 600;
int const _MAX_TAKEOFF_DELAY = 3000; int const _MAX_TAKEOFF_DELAY = 3000;
int const _RW_LENGTH = 6; int const _RW_LENGTH = 6;
float const _APPROACH_DIST = 20.0f;
public: public:
Airfield(AFSpawner *parent, vec2 position, int ttl, float rw_heading) Airfield(AFSpawner *parent, vec2 position, int ttl, float rw_heading)
@@ -32,6 +35,10 @@ public:
} }
vec2 get_position() { return _position; } vec2 get_position() { return _position; }
vec2 get_approach_point();
void going_to() { ++_pending_arrivals; }
void arrived_at() { --_pending_arrivals; }
bool is_active() { return _ttl > 0; }
void tick(float timestep, World *world) override; void tick(float timestep, World *world) override;
void draw(Renderer *rend) override; void draw(Renderer *rend) override;