summaryrefslogtreecommitdiff
path: root/source/logic/EnemyCar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/logic/EnemyCar.cpp')
-rw-r--r--source/logic/EnemyCar.cpp104
1 files changed, 104 insertions, 0 deletions
diff --git a/source/logic/EnemyCar.cpp b/source/logic/EnemyCar.cpp
new file mode 100644
index 0000000..ce455a6
--- /dev/null
+++ b/source/logic/EnemyCar.cpp
@@ -0,0 +1,104 @@
+#include "EnemyCar.h"
+
+EnemyCar::EnemyCar(double x, double y)
+ :Car(x,y,BitmapStore::ENEMY,Maze::UP),
+ _state(CHASING),
+ _targetX(x),
+ _targetY(y)
+{
+}
+
+void EnemyCar::update(const Maze& maze, const list<PlayerCar>& players, const list<Rock>& rocks)
+{
+ if (!players.empty()) checkFacing(maze, players.front().x(), players.front().y(), rocks);
+
+ if (_state!=BLINDED)
+ {
+ move(maze);
+ }
+ else
+ {
+ _state = CHASING;
+ _speed = _baseSpeed;
+ }
+}
+
+void EnemyCar::checkFacing(const Maze& maze, double chasingX, double chasingY, const list<Rock>& rocks)
+{
+ if (abs(_x - _targetX)>_speed || abs(_y - _targetY)>_speed) return;
+
+ map<Maze::Direction, pair<double, double> > adjacentBlocks;
+ pair<double, double> evaluatingTarget;
+
+ adjacentBlocks[Maze::LEFT] = make_pair(MazeMath::round(_x-1), MazeMath::round(_y));
+ adjacentBlocks[Maze::RIGHT] = make_pair(MazeMath::round(_x+1), MazeMath::round(_y));
+ adjacentBlocks[Maze::UP] = make_pair(MazeMath::round(_x), MazeMath::round(_y-1));
+ adjacentBlocks[Maze::DOWN] = make_pair(MazeMath::round(_x), MazeMath::round(_y+1));
+
+ //remove adjacent blocks that would result in crashing into a rock or a wall
+ for (map<Maze::Direction, pair<double, double> >::iterator iter=adjacentBlocks.begin(); iter!=adjacentBlocks.end(); )
+ {
+ if (rockAtLocation(iter->second.first, iter->second.second, rocks) || maze.getSolid(static_cast<int>(iter->second.first),static_cast<int>(iter->second.second)))
+ {
+ adjacentBlocks.erase(iter);
+ iter = adjacentBlocks.begin();
+ }
+ else
+ {
+ ++iter;
+ }
+ }
+
+ if (adjacentBlocks.empty())
+ {
+ _speed = 0;
+ return;
+ }
+ else
+ {
+ _speed = _baseSpeed;
+ }
+
+ map<Maze::Direction, pair<double, double> >::iterator reverseFacing = adjacentBlocks.find(Maze::backwards(_facing));
+ if ((reverseFacing != adjacentBlocks.end()) && (adjacentBlocks.size()>1))
+ {
+ adjacentBlocks.erase(reverseFacing);
+ }
+
+ map<Maze::Direction, pair<double, double> >::const_iterator closestAdjacent = adjacentBlocks.begin();
+ double closestDistance = MazeMath::distance(closestAdjacent->second.first, closestAdjacent->second.second, chasingX, chasingY);
+
+ for (map<Maze::Direction, pair<double, double> >::const_iterator iter = ++adjacentBlocks.begin(); iter!=adjacentBlocks.end(); ++iter)
+ {
+ double newDistance = MazeMath::distance(iter->second.first, iter->second.second, chasingX, chasingY);
+ if (newDistance < closestDistance)
+ {
+ closestDistance = newDistance;
+ closestAdjacent = iter;
+ }
+ }
+
+ _targetX = closestAdjacent->second.first;
+ _targetY = closestAdjacent->second.second;
+ _facing = closestAdjacent->first;
+}
+
+bool EnemyCar::rockAtLocation(double x, double y, const list<Rock>& rocks)
+{
+ for (list<Rock>::const_iterator iter = rocks.begin(); iter!=rocks.end(); ++iter)
+ {
+ if (abs(x - iter->x())<1 && abs(y - iter->y())<1) return true;
+ }
+ return false;
+}
+
+void EnemyCar::crash()
+{
+ _destroyed = true;
+}
+
+void EnemyCar::blind()
+{
+ _state = BLINDED;
+ _speed = 0;
+}