AISystem
The AISystem is responsible for controlling the behavior of non-player entities (enemies). Currently, it implements a "Kamikaze" tracking behavior where entities actively seek and move towards the nearest player.
Required Components
Entities processed by this system must have the following components:
1. AI: Holds internal state and timers.
2. Transform: To know where the enemy is.
3. Velocity: To apply movement towards the player.
Note: The system also queries for
Playableentities to determine the target (The Player).
Logic & Algorithm
The system runs on every frame (onUpdate) and performs the following steps:
-
Target Acquisition:
- Iterates through all entities to find the first entity possessing a
Playabletag and aTransform. - Current limitation: Targets the first player found in the memory array.
- Iterates through all entities to find the first entity possessing a
-
Vector Calculation:
- Calculates the difference vector between the Enemy and the Player.
- Computes the Inverse Square Root of the distance (
safeInvSqrt) to normalize the vector efficiently.
-
Velocity Application:
- Applies a constant
KAMIKAZE_SPEEDalong the normalized vector. - Adjusts the velocity using the global
ScaleFactorto ensure consistent speed across different window resolutions.
- Applies a constant
Code reference
src/game/src/systems/AISystem.cpp
void AISystem::onUpdate(float dt) {
auto& positions = _engine.getComponents<Transform>();
auto& velocities = _engine.getComponents<Velocity>();
auto& ais = _engine.getComponents<AI>();
auto& playables = _engine.getComponents<Playable>();
float scaleFactor = _engine.getScaleFactor();
size_t playerId = findFirstPlayableWithTransform(playables, positions);
if (playerId == npos) return;
const Transform& playerPos = positions[playerId].value();
for (size_t e : _entities) {
if (!positions[e] || !velocities[e] || !ais[e]) continue;
auto& pos = positions[e].value();
auto& vel = velocities[e].value();
float dx = playerPos.x - pos.x;
float dy = playerPos.y - pos.y;
float inv = 1.f / std::sqrt(dx * dx + dy * dy + 0.000001f);
vel.vx = dx * inv * 0.5f * scaleFactor;
vel.vy = dy * inv * 0.5f * scaleFactor;
}
}
Usage
Simply attach an AI component to an entity to have it chase the player.