summary refs log tree commit diff stats
path: root/src/components
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2015-03-19 16:15:47 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2015-03-19 16:15:47 -0400
commit4b4125e234cb727c70822e0a1fce0688c357741e (patch)
tree5b446ebe6f0454304d4202368bd18fba3f629d3d /src/components
parent281bdf956a646fd8c9944e9a44f867c984792216 (diff)
downloadtherapy-4b4125e234cb727c70822e0a1fce0688c357741e.tar.gz
therapy-4b4125e234cb727c70822e0a1fce0688c357741e.tar.bz2
therapy-4b4125e234cb727c70822e0a1fce0688c357741e.zip
Implemented a simple AI
Diffstat (limited to 'src/components')
-rw-r--r--src/components/ai.cpp142
-rw-r--r--src/components/ai.h73
-rw-r--r--src/components/map_collision.cpp15
-rw-r--r--src/components/physics_body.cpp8
-rw-r--r--src/components/player_physics.cpp8
5 files changed, 235 insertions, 11 deletions
diff --git a/src/components/ai.cpp b/src/components/ai.cpp new file mode 100644 index 0000000..9f8c764 --- /dev/null +++ b/src/components/ai.cpp
@@ -0,0 +1,142 @@
1#include "ai.h"
2#include <cstdlib>
3#include "entity.h"
4
5void AIActionContainer::addAction(std::shared_ptr<AIAction> action)
6{
7 actions.push_back(action);
8}
9
10void AIActionContainer::start(Game& game, Entity& entity)
11{
12 currentAction = begin(actions);
13
14 if (currentAction != end(actions))
15 {
16 (*currentAction)->start(game, entity);
17 }
18}
19
20void AIActionContainer::perform(Game& game, Entity& entity, double dt)
21{
22 if (!isDone())
23 {
24 (*currentAction)->perform(game, entity, dt);
25
26 if ((*currentAction)->isDone())
27 {
28 currentAction++;
29
30 if (!isDone())
31 {
32 (*currentAction)->start(game, entity);
33 }
34 }
35 }
36}
37
38bool AIActionContainer::isDone() const
39{
40 return currentAction == end(actions);
41}
42
43AI::AI(int chance)
44{
45 this->chance = chance;
46}
47
48int AI::getChance() const
49{
50 return chance;
51}
52
53AI& AIComponent::emplaceAI(int chance)
54{
55 maxChance += chance;
56 ais.emplace_back(chance);
57
58 return ais.back();
59}
60
61void AIComponent::tick(Game& game, Entity& entity, double dt)
62{
63 if (currentAI == nullptr)
64 {
65 int toChoose = rand() % maxChance;
66 for (auto& ai : ais)
67 {
68 if (toChoose < ai.getChance())
69 {
70 currentAI = &ai;
71 break;
72 } else {
73 toChoose -= ai.getChance();
74 }
75 }
76
77 if (currentAI != nullptr)
78 {
79 currentAI->start(game, entity);
80 }
81 }
82
83 if (currentAI != nullptr)
84 {
85 currentAI->perform(game, entity, dt);
86
87 if (currentAI->isDone())
88 {
89 currentAI = nullptr;
90 }
91 }
92}
93
94MoveAIAction::MoveAIAction(Direction dir, int len, int speed)
95{
96 this->dir = dir;
97 this->len = len;
98 this->speed = speed;
99}
100
101void MoveAIAction::start(Game& game, Entity& entity)
102{
103 remaining = len;
104}
105
106void MoveAIAction::perform(Game&, Entity& entity, double dt)
107{
108 double dist = dt * speed;
109 remaining -= dist;
110
111 switch (dir)
112 {
113 case Direction::Left:
114 {
115 entity.position.first -= dist;
116 break;
117 }
118
119 case Direction::Right:
120 {
121 entity.position.first += dist;
122 break;
123 }
124
125 case Direction::Up:
126 {
127 entity.position.second -= dist;
128 break;
129 }
130
131 case Direction::Down:
132 {
133 entity.position.second += dist;
134 break;
135 }
136 }
137}
138
139bool MoveAIAction::isDone() const
140{
141 return remaining <= 0.0;
142}
diff --git a/src/components/ai.h b/src/components/ai.h new file mode 100644 index 0000000..840283b --- /dev/null +++ b/src/components/ai.h
@@ -0,0 +1,73 @@
1#ifndef AI_H
2#define AI_H
3
4#include <list>
5#include <map>
6#include <string>
7#include <memory>
8
9#include "entity.h"
10
11class AIAction {
12 public:
13 virtual void start(Game& game, Entity& entity) = 0;
14 virtual void perform(Game& game, Entity& entity, double dt) = 0;
15 virtual bool isDone() const = 0;
16};
17
18class AIActionContainer {
19 public:
20 void addAction(std::shared_ptr<AIAction> action);
21 virtual void start(Game& game, Entity& entity);
22 virtual void perform(Game& game, Entity& entity, double dt);
23 virtual bool isDone() const;
24
25 private:
26 std::list<std::shared_ptr<AIAction>> actions;
27 std::list<std::shared_ptr<AIAction>>::iterator currentAction {end(actions)};
28};
29
30class AI : public AIActionContainer {
31 public:
32 AI(int chance);
33
34 int getChance() const;
35
36 private:
37 int chance;
38};
39
40class AIComponent : public Component {
41 public:
42 AI& emplaceAI(int chance);
43 void tick(Game& game, Entity& entity, double dt);
44
45 private:
46 int maxChance = 0;
47 std::list<AI> ais;
48 AI* currentAI = nullptr;
49};
50
51class MoveAIAction : public AIAction {
52 public:
53 enum class Direction {
54 Left,
55 Right,
56 Up,
57 Down
58 };
59
60 MoveAIAction(Direction dir, int len, int speed);
61
62 void start(Game& game, Entity& entity);
63 void perform(Game& game, Entity& entity, double dt);
64 bool isDone() const;
65
66 private:
67 Direction dir;
68 int len;
69 int speed;
70 double remaining;
71};
72
73#endif /* end of include guard: AI_H */
diff --git a/src/components/map_collision.cpp b/src/components/map_collision.cpp index 83ad33d..432fea6 100644 --- a/src/components/map_collision.cpp +++ b/src/components/map_collision.cpp
@@ -156,15 +156,24 @@ void MapCollisionComponent::processCollision(Game& game, Entity& collider, Colli
156 if (dir == Direction::left) 156 if (dir == Direction::left)
157 { 157 {
158 collider.position.first = collision.axis; 158 collider.position.first = collision.axis;
159 collider.send(game, Message::Type::stopMovingHorizontally); 159
160 Message msg(Message::Type::setHorizontalVelocity);
161 msg.velocity = 0.0;
162 collider.send(game, msg);
160 } else if (dir == Direction::right) 163 } else if (dir == Direction::right)
161 { 164 {
162 collider.position.first = collision.axis - collider.size.first; 165 collider.position.first = collision.axis - collider.size.first;
163 collider.send(game, Message::Type::stopMovingHorizontally); 166
167 Message msg(Message::Type::setHorizontalVelocity);
168 msg.velocity = 0.0;
169 collider.send(game, msg);
164 } else if (dir == Direction::up) 170 } else if (dir == Direction::up)
165 { 171 {
166 collider.position.second = collision.axis; 172 collider.position.second = collision.axis;
167 collider.send(game, Message::Type::stopMovingVertically); 173
174 Message msg(Message::Type::setVerticalVelocity);
175 msg.velocity = 0.0;
176 collider.send(game, msg);
168 } else if (dir == Direction::down) 177 } else if (dir == Direction::down)
169 { 178 {
170 collider.position.second = collision.axis - collider.size.second; 179 collider.position.second = collision.axis - collider.size.second;
diff --git a/src/components/physics_body.cpp b/src/components/physics_body.cpp index acbdc5d..97394d1 100644 --- a/src/components/physics_body.cpp +++ b/src/components/physics_body.cpp
@@ -13,12 +13,12 @@ void PhysicsBodyComponent::receive(Game&, Entity&, const Message& msg)
13 } else if (msg.type == Message::Type::stopWalking) 13 } else if (msg.type == Message::Type::stopWalking)
14 { 14 {
15 velocity.first = 0.0; 15 velocity.first = 0.0;
16 } else if (msg.type == Message::Type::stopMovingHorizontally) 16 } else if (msg.type == Message::Type::setHorizontalVelocity)
17 { 17 {
18 velocity.first = 0.0; 18 velocity.first = msg.velocity;
19 } else if (msg.type == Message::Type::stopMovingVertically) 19 } else if (msg.type == Message::Type::setVerticalVelocity)
20 { 20 {
21 velocity.second = 0.0; 21 velocity.second = msg.velocity;
22 } 22 }
23} 23}
24 24
diff --git a/src/components/player_physics.cpp b/src/components/player_physics.cpp index 1d14f35..40e9948 100644 --- a/src/components/player_physics.cpp +++ b/src/components/player_physics.cpp
@@ -29,12 +29,12 @@ void PlayerPhysicsComponent::receive(Game&, Entity& entity, const Message& msg)
29 { 29 {
30 velocity.first = 0.0; 30 velocity.first = 0.0;
31 direction = 0; 31 direction = 0;
32 } else if (msg.type == Message::Type::stopMovingHorizontally) 32 } else if (msg.type == Message::Type::setHorizontalVelocity)
33 { 33 {
34 velocity.first = 0.0; 34 velocity.first = msg.velocity;
35 } else if (msg.type == Message::Type::stopMovingVertically) 35 } else if (msg.type == Message::Type::setVerticalVelocity)
36 { 36 {
37 velocity.second = 0.0; 37 velocity.second = msg.velocity;
38 } else if (msg.type == Message::Type::hitTheGround) 38 } else if (msg.type == Message::Type::hitTheGround)
39 { 39 {
40 if (isFalling) 40 if (isFalling)