blob: 4858000b127fb75bb92024771559dfad9eddb33f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
#include "api/LoopTimer.h"
#include "api/Rigidbody.h"
#include "api/Transform.h"
#include "manager/ComponentManager.h"
#include "manager/Mediator.h"
#include "types.h"
#include "AISystem.h"
using namespace crepe;
void AISystem::update() {
const Mediator & mediator = this->mediator;
ComponentManager & mgr = mediator.component_manager;
RefVector<AI> ai_components = mgr.get_components_by_type<AI>();
double dt = LoopTimer::get_instance().get_delta_time();
for (AI & ai : ai_components) {
RefVector<Rigidbody> rigidbodies
= mgr.get_components_by_id<Rigidbody>(ai.game_object_id);
Rigidbody & rigidbody = rigidbodies.front().get();
vec2 force = this->calculate(ai);
vec2 acceleration = force / rigidbody.data.mass;
rigidbody.data.linear_velocity += acceleration * dt;
}
}
vec2 AISystem::calculate(AI & ai) {
vec2 force;
if (ai.on(AI::BehaviorType::SEEK)) {
vec2 force_to_add = this->seek(ai);
if (!this->accumulate_force(ai, force, force_to_add)) {
return force;
}
}
if (ai.on(AI::BehaviorType::FLEE)) {
// Flee from the target
}
if (ai.on(AI::BehaviorType::ARRIVE)) {
// Arrive at the target
}
if (ai.on(AI::BehaviorType::PATH_FOLLOW)) {
// Follow the path
}
return force;
}
bool AISystem::accumulate_force(AI & ai, vec2 & running_total, vec2 force_to_add) {
float magnitude = running_total.length();
float magnitude_remaining = ai.max_force - magnitude;
if (magnitude_remaining <= 0.0f) {
return false;
}
float magnitude_to_add = force_to_add.length();
if (magnitude_to_add < magnitude_remaining) {
running_total += force_to_add;
} else {
force_to_add.normalize();
running_total += force_to_add * magnitude_remaining;
}
return true;
}
vec2 AISystem::seek(const AI & ai) {
const Mediator & mediator = this->mediator;
ComponentManager & mgr = mediator.component_manager;
RefVector<Transform> transforms = mgr.get_components_by_id<Transform>(ai.game_object_id);
Transform & transform = transforms.front().get();
RefVector<Rigidbody> rigidbodies = mgr.get_components_by_id<Rigidbody>(ai.game_object_id);
Rigidbody & rigidbody = rigidbodies.front().get();
vec2 desired_velocity = ai.seek_target - transform.position;
desired_velocity.normalize();
desired_velocity *= rigidbody.data.max_linear_velocity;
return desired_velocity - rigidbody.data.linear_velocity;
}
|