Make files for ghosts

This commit is contained in:
Patricia Aas 2021-07-28 15:28:36 +02:00
parent fe04e7d03a
commit 5b2b0d8e73
13 changed files with 191 additions and 75 deletions

27
lib/Blinky.cpp Normal file
View File

@ -0,0 +1,27 @@
#include "Blinky.hpp"
namespace pacman {
Blinky::Blinky()
: Ghost(Atlas::Ghost::blinky, pacman::initialBlinkyPosition(), pacman::blinkyScatterTarget()) {
}
double Blinky::speed(const GameState & gameState) const {
if (state == State::Eyes)
return 2;
if (state == State::Frightened)
return 0.5;
return 0.75;
}
Position Blinky::target(const GameState & gameState) const {
if (state == State::Eyes)
return startingPosition;
if (isInPen())
return pacman::penDoorPosition();
return blinkyScatterTarget();
}
}

27
lib/Clyde.cpp Normal file
View File

@ -0,0 +1,27 @@
#include "Clyde.hpp"
namespace pacman {
Clyde::Clyde()
: Ghost(Atlas::Ghost::clyde, initialClydePosition(), clydeScatterTarget()) {
}
double Clyde::speed(const GameState & gameState) const {
if (state == State::Eyes)
return 2;
if (state == State::Frightened)
return 0.5;
return 0.75;
}
Position Clyde::target(const GameState & gameState) const {
if (state == State::Eyes)
return startingPosition;
if (isInPen())
return penDoorPosition();
return clydeScatterTarget();
}
}

View File

@ -73,10 +73,10 @@ void Game::step(std::chrono::milliseconds delta, InputState inputState) {
if (!gameState.pacMan.hasDirection())
return;
gameState.blinky.update(delta);
gameState.pinky.update(delta);
gameState.inky.update(delta);
gameState.clyde.update(delta);
gameState.blinky.update(delta, gameState);
gameState.pinky.update(delta, gameState);
gameState.inky.update(delta, gameState);
gameState.clyde.update(delta, gameState);
checkCollision(gameState.blinky);
checkCollision(gameState.pinky);
@ -87,7 +87,7 @@ void Game::step(std::chrono::milliseconds delta, InputState inputState) {
eatPellets();
}
void Game::checkCollision(Ghost ghost) {
void Game::checkCollision(Ghost & ghost) {
if (pacManDying() || ghost.isEyes())
return;

View File

@ -7,8 +7,7 @@ namespace pacman {
Ghost::Ghost(Atlas::Ghost spritesSet, Position startingPosition, Position scatterTarget)
: spritesSet(spritesSet),
pos(startingPosition),
startingPosition(startingPosition),
scatterTarget(scatterTarget) {
startingPosition(startingPosition) {
}
void Ghost::frighten() {
@ -62,7 +61,7 @@ GridPosition Ghost::positionInGrid() const {
return positionToGridPosition(pos);
}
void Ghost::update(std::chrono::milliseconds time_delta) {
void Ghost::update(std::chrono::milliseconds time_delta, const GameState & gameState) {
if (state == State::Eyes && isInPen())
state = State::Scatter;
@ -73,17 +72,17 @@ void Ghost::update(std::chrono::milliseconds time_delta) {
}
updateAnimation(time_delta);
updatePosition(time_delta);
updatePosition(time_delta, gameState);
}
bool Ghost::isInPen() const {
return pacman::isInPen(positionInGrid());
}
void Ghost::updatePosition(std::chrono::milliseconds time_delta) {
updateDirection();
void Ghost::updatePosition(std::chrono::milliseconds time_delta, const GameState & gameState) {
updateDirection(gameState);
double position_delta = (0.004 * time_delta.count()) * speed();
double position_delta = (0.004 * time_delta.count()) * speed(gameState);
switch (direction) {
case Direction::NONE:
@ -107,14 +106,6 @@ void Ghost::updatePosition(std::chrono::milliseconds time_delta) {
}
}
double Ghost::speed() const {
if (state == State::Eyes)
return 2;
if (state == State::Frightened)
return 0.5;
return 0.75;
}
/*
* Each time a ghost finds itself at an intersection,
* it picks a target position - the specific target depends on the state
@ -131,7 +122,7 @@ double Ghost::speed() const {
* In the scatter state, each ghost tries to reach an unreachable position outside of the map.
* This makes ghosts run in circle around the island at each of the 4 map corner.
*/
void Ghost::updateDirection() {
void Ghost::updateDirection(const GameState & gameState) {
const auto current_grid_position = positionInGrid();
if (current_grid_position == last_grid_position)
return;
@ -149,7 +140,7 @@ void Ghost::updateDirection() {
Move{ Direction::DOWN, { x, y + 1 } },
Move{ Direction::RIGHT, { x + 1, y } } } };
const Position target_position = target();
const Position target_position = target(gameState);
for (auto & move : possible_moves) {
const bool invalid_position = (move.position.x < 0 || move.position.y < 0);
@ -177,16 +168,6 @@ void Ghost::updateDirection() {
last_grid_position = current_grid_position;
}
Position Ghost::target() const {
if (state == State::Eyes)
return startingPosition;
if (pacman::isInPen(positionInGrid()))
return pacman::penDoorPosition();
return scatterTarget;
}
void Ghost::updateAnimation(std::chrono::milliseconds time_delta) {
timeForAnimation += time_delta.count();
if (timeForAnimation >= 250) {
@ -195,20 +176,4 @@ void Ghost::updateAnimation(std::chrono::milliseconds time_delta) {
}
}
Blinky::Blinky()
: Ghost(Atlas::Ghost::blinky, pacman::initialBlinkyPosition(), pacman::blinkyScatterTarget()) {
}
Pinky::Pinky()
: Ghost(Atlas::Ghost::speedy, pacman::initialSpeedyPosition(), pacman::speedyScatterTarget()) {
}
Inky::Inky()
: Ghost(Atlas::Ghost::inky, pacman::initialInkyPosition(), pacman::inkyScatterTarget()) {
}
Clyde::Clyde()
: Ghost(Atlas::Ghost::clyde, pacman::initialClydePosition(), pacman::clydeScatterTarget()) {
}
} // namespace pacman

27
lib/Inky.cpp Normal file
View File

@ -0,0 +1,27 @@
#include "Inky.hpp"
namespace pacman {
Inky::Inky()
: Ghost(Atlas::Ghost::inky, pacman::initialInkyPosition(), pacman::inkyScatterTarget()) {
}
double Inky::speed(const GameState & gameState) const {
if (state == State::Eyes)
return 2;
if (state == State::Frightened)
return 0.5;
return 0.75;
}
Position Inky::target(const GameState & gameState) const {
if (state == State::Eyes)
return startingPosition;
if (isInPen())
return pacman::penDoorPosition();
return inkyScatterTarget();
}
}

27
lib/Pinky.cpp Normal file
View File

@ -0,0 +1,27 @@
#include "Pinky.hpp"
namespace pacman {
Pinky::Pinky()
: Ghost(Atlas::Ghost::speedy, pacman::initialSpeedyPosition(), pacman::speedyScatterTarget()) {
}
double Pinky::speed(const GameState & gameState) const {
if (state == State::Eyes)
return 2;
if (state == State::Frightened)
return 0.5;
return 0.75;
}
Position Pinky::target(const GameState & gameState) const {
if (state == State::Eyes)
return startingPosition;
if (isInPen())
return pacman::penDoorPosition();
return speedyScatterTarget();
}
}

14
lib/include/Blinky.hpp Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include "Ghost.hpp"
namespace pacman {
class Blinky : public Ghost {
public:
explicit Blinky();
[[nodiscard]] double speed(const GameState & gameState) const override;
[[nodiscard]] Position target(const GameState & gameState) const override;
};
} // namespace pacman

14
lib/include/Clyde.hpp Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include "Ghost.hpp"
namespace pacman {
class Clyde : public Ghost {
public:
explicit Clyde();
[[nodiscard]] double speed(const GameState & gameState) const override;
[[nodiscard]] Position target(const GameState & gameState) const override;
};
} // namespace pacman

View File

@ -20,7 +20,7 @@ private:
void step(std::chrono::milliseconds delta, InputState inputState);
void eatPellets();
void processEvents(InputState & inputState);
void checkCollision(Ghost ghost);
void checkCollision(Ghost & ghost);
void killPacMan();
bool pacManDying() const;
void handleDeathAnimation(std::chrono::milliseconds delta);

View File

@ -1,8 +1,12 @@
#pragma once
#include "Blinky.hpp"
#include "Clyde.hpp"
#include "Ghost.hpp"
#include "Inky.hpp"
#include "PacMan.hpp"
#include "Pellets.hpp"
#include "Pinky.hpp"
#include "Score.hpp"
#include "SuperPellets.hpp"

View File

@ -8,6 +8,8 @@
namespace pacman {
class GameState;
class Ghost {
public:
enum class State {
@ -25,7 +27,7 @@ public:
[[nodiscard]] GridPosition positionInGrid() const;
void update(std::chrono::milliseconds time_delta);
void update(std::chrono::milliseconds time_delta, const GameState & gameState);
void frighten();
void die();
[[nodiscard]] bool isFrightened() const;
@ -33,13 +35,15 @@ public:
void reset();
private:
[[nodiscard]] double speed() const;
void updateAnimation(std::chrono::milliseconds time_delta);
void updatePosition(std::chrono::milliseconds time_delta);
void updateDirection();
[[nodiscard]] Position target() const;
void updatePosition(std::chrono::milliseconds time_delta, const GameState & gameState);
void updateDirection(const GameState & gameState);
protected:
[[nodiscard]] virtual double speed(const GameState & gameState) const = 0;
[[nodiscard]] virtual Position target(const GameState & gameState) const = 0;
Atlas::Ghost spritesSet;
Direction direction = Direction::NONE;
double timeForAnimation = 0;
@ -49,29 +53,8 @@ protected:
int timeChase = 0;
Position pos;
Position startingPosition;
Position scatterTarget;
GridPosition last_grid_position = { 0, 0 };
[[nodiscard]] bool isInPen() const;
};
class Blinky : public Ghost {
public:
explicit Blinky();
};
class Pinky : public Ghost {
public:
explicit Pinky();
};
class Inky : public Ghost {
public:
explicit Inky();
};
class Clyde : public Ghost {
public:
explicit Clyde();
};
} // namespace pacman

14
lib/include/Inky.hpp Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include "Ghost.hpp"
namespace pacman {
class Inky : public Ghost {
public:
explicit Inky();
[[nodiscard]] double speed(const GameState & gameState) const override;
[[nodiscard]] Position target(const GameState & gameState) const override;
};
} // namespace pacman

14
lib/include/Pinky.hpp Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include "Ghost.hpp"
namespace pacman {
class Pinky : public Ghost {
public:
explicit Pinky();
[[nodiscard]] double speed(const GameState & gameState) const override;
[[nodiscard]] Position target(const GameState & gameState) const override;
};
} // namespace pacman