#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& players, const list& 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& rocks) { if (abs(_x - _targetX)>_speed || abs(_y - _targetY)>_speed) return; map > adjacentBlocks; pair 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 >::iterator iter=adjacentBlocks.begin(); iter!=adjacentBlocks.end(); ) { if (rockAtLocation(iter->second.first, iter->second.second, rocks) || maze.getSolid(static_cast(iter->second.first),static_cast(iter->second.second))) { adjacentBlocks.erase(iter); iter = adjacentBlocks.begin(); } else { ++iter; } } if (adjacentBlocks.empty()) { _speed = 0; return; } else { _speed = _baseSpeed; } map >::iterator reverseFacing = adjacentBlocks.find(Maze::backwards(_facing)); if ((reverseFacing != adjacentBlocks.end()) && (adjacentBlocks.size()>1)) { adjacentBlocks.erase(reverseFacing); } map >::const_iterator closestAdjacent = adjacentBlocks.begin(); double closestDistance = MazeMath::distance(closestAdjacent->second.first, closestAdjacent->second.second, chasingX, chasingY); for (map >::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& rocks) { for (list::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; }