Skip to content

Commit

Permalink
merge: Merge pull request #41 from G-Epitech/40-arcade-pacman-game
Browse files Browse the repository at this point in the history
feat(games): add pacman game
  • Loading branch information
Yann-Masson authored Apr 7, 2024
2 parents 2780d5e + a0c1850 commit b50bd0c
Show file tree
Hide file tree
Showing 28 changed files with 998 additions and 3 deletions.
4 changes: 4 additions & 0 deletions assets/pacman/ghost.ascii
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
A%
B:
C
D
Binary file added assets/pacman/ghost.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions assets/pacman/map.ascii
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
###########################
# # #
# #### ##### # ##### #### #
#?#### ##### # ##### ####?#
# #### ##### # ##### #### #
# #
# #### # ######### # #### #
# #### # ######### # #### #
# # # # #
###### ##### # ##### ######
<<<<<# ##### # ##### #
<<<<<# # # #
<<<<<# # ####_#### # #
###### # #wwwwwww# # ######
#wwwwwww#
###### # #wwwwwww# # ######
<<<<<# # #wwwwwww# # #
<<<<<# # ######### # #
<<<<<# # # #
###### # ######### # ######
# # #
# #### ##### # ##### #### #
# #### ##### # ##### #### #
# ## o ## #
### ## ## ####### ## ## ###
# ## # ## #
#?########## # ##########?#
# ########## # ########## #
# #
###########################
Binary file added assets/pacman/map.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions assets/pacman/pacman.ascii
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<<<
>>>
^^^
vvv
Binary file added assets/pacman/pacman.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/pacman/point.ascii
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.0
Binary file added assets/pacman/point.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions games/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
add_subdirectory(pacman)
add_subdirectory(snake)
add_subdirectory(nibbler)
22 changes: 22 additions & 0 deletions games/pacman/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
project(pacman)
add_library(${PROJECT_NAME} SHARED
export.cpp
src/PacmanGame.cpp
src/PacmanGame.hpp
src/PacmanGameProvider.cpp
src/PacmanGameProvider.hpp
src/entities/map/MapEntity.cpp
src/entities/map/MapEntity.hpp
src/entities/player/PlayerEntity.cpp
src/entities/player/PlayerEntity.hpp
src/entities/player/components/HeadKeyboardComponent.cpp
src/entities/player/components/HeadKeyboardComponent.hpp
src/entities/map/PointEntity.cpp
src/entities/map/PointEntity.hpp
src/entities/ghost/GhostEntity.cpp
src/entities/ghost/GhostEntity.hpp
)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../common PRIVATE)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../..)
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/..)
22 changes: 22 additions & 0 deletions games/pacman/export.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
** EPITECH PROJECT, 2024
** arcade-shared
** File description:
** export
*/

#include "PacmanGameProvider.hpp"
#include "shared/types/Libraries.hpp"

using namespace shared::games;
using namespace shared::types;

extern "C" {
LibraryType SHARED_LIBRARY_TYPE_GETTER_NAME(void) {
return LibraryType::GAME;
}

IGameProvider *SHARED_GAME_PROVIDER_GETTER_NAME(void) {
return new arcade::games::pacman::PacmanGameProvider();
}
}
160 changes: 160 additions & 0 deletions games/pacman/src/PacmanGame.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
** EPITECH PROJECT, 2024
** PacmanGame.cpp
** File description:
** PacmanGame class
*/

#include <random>
#include "PacmanGame.hpp"
#include "entities/map/MapEntity.hpp"
#include "entities/ghost/GhostEntity.hpp"

using namespace arcade::games;

const shared::games::GameManifest pacman::PacmanGame::manifest = {
.name = "pacman",
.description = "The pacman arcade game",
.version = "1.0.0",
.authors = {
{
.name = "TekMath",
.email = "matheo.coquet@epitech.eu",
.website = "https://github.com/tekmath"
}
}
};

pacman::PacmanGame::PacmanGame() : common::AGame(Vector2u(27, 30), 60),
_player(std::make_unique<PlayerEntity>(Vector2i(13, 23))),
_map(std::make_unique<MapEntity>()) {

for (const auto &entity: this->_map->generateWalls(MAP_PATH)) {
this->_registerEntity(entity);
}

this->_currentScore = 0;

for (unsigned int i = 0; i < 4; i++) {
this->_ghosts.push_back(std::make_unique<GhostEntity>(i));
this->_registerEntity(this->_ghosts[i]);
}

this->_registerEntity(this->_map);
this->_registerEntity(this->_player);
this->_clock = std::chrono::milliseconds(0);
}

const shared::games::GameManifest &pacman::PacmanGame::getManifest() const noexcept {
return this->manifest;
}

void pacman::PacmanGame::compute(shared::games::DeltaTime dt) {
this->_clock += dt;

if (this->_canEatGhost && this->_stopEatGhostTime < this->_clock) {
this->_canEatGhost = false;
for (auto ghost : this->_ghosts) {
ghost->disableCanBeEat();
}
}

if (this->_clock > std::chrono::milliseconds(100) + this->_player->lastMove) {
this->_player->lastMove = this->_clock;
if (this->_map->mapData[this->_player->getPosition().y + this->_player->direction.y][
this->_player->getPosition().x + this->_player->direction.x] != '#') {
this->_player->forward();
}
}

for (auto ghost : this->_ghosts) {
if (this->_clock > std::chrono::milliseconds(100) + ghost->lastMove) {
if (ghost->direction.x == 0 && ghost->direction.y == 0) {
ghost->direction = Vector2i(0, -1);
ghost->position = Vector2i(13, 12);
}
if (this->_map->mapData[ghost->position.y + ghost->direction.y][
ghost->position.x + ghost->direction.x] != '#') {
ghost->lastMove = this->_clock;
ghost->forward();
} else {
this->_redirectGhost(ghost);
}
}
}
}



void pacman::PacmanGame::addNewPoint(Vector2i position) {
this->_entities.erase(std::remove_if(this->_entities.begin(), this->_entities.end(),
[&position](const shared::games::entity::EntityPtr &entity) {
auto tail = std::dynamic_pointer_cast<PointEntity>(entity);
if (tail) {
return tail->position.x == position.x &&
tail->position.y == position.y;
}
return false;
}), this->_entities.end());

this->_currentScore += 5;
}

void pacman::PacmanGame::_redirectGhost(std::shared_ptr<GhostEntity> ghost) {
std::vector<Vector2i> pos;

if (this->_map->mapData[ghost->position.y - 1][
ghost->position.x] == ' ')
pos.push_back(Vector2i(0, -1));
if (this->_map->mapData[ghost->position.y + 1][
ghost->position.x] == ' ')
pos.push_back(Vector2i(0, 1));
if (this->_map->mapData[ghost->position.y][
ghost->position.x - 1] == ' ')
pos.push_back(Vector2i(-1, 0));
if (this->_map->mapData[ghost->position.y][
ghost->position.x + 1] == ' ')
pos.push_back(Vector2i(1, 0));

std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<int> dis(0, pos.size() - 1);

ghost->direction = pos[dis(gen)];
}

void pacman::PacmanGame::eatPlayer(Vector2i position) {
if (this->_canEatGhost) {
unsigned int index = 0;

for (auto ghost : this->_ghosts) {
if (ghost->position.x == position.x && ghost->position.y == position.y) {
ghost->reset(index);
return;
}
index++;
}
}

this->_clock = std::chrono::milliseconds(0);
this->_player->reset(Vector2i(13, 23));
if (this->_currentScore > this->_score)
this->_score = this->_currentScore;
this->_currentScore = 0;

unsigned int index = 0;
for (auto ghost : this->_ghosts) {
ghost->reset(index);
index++;
}

}

void pacman::PacmanGame::canEatGhosts() {
this->_canEatGhost = true;
this->_stopEatGhostTime = this->_clock + std::chrono::seconds(5);

for (auto ghost : this->_ghosts) {
ghost->enableCanBeEat();
}
}
78 changes: 78 additions & 0 deletions games/pacman/src/PacmanGame.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
** EPITECH PROJECT, 2024
** PacmanGame.hpp
** File description:
** PacmanGame class
*/

#pragma once

#include "common/game/AGame.hpp"
#include "entities/player/PlayerEntity.hpp"
#include "entities/map/MapEntity.hpp"
#include "entities/ghost/GhostEntity.hpp"

#define MAP_PATH "assets/pacman/map.ascii"

namespace arcade::games::pacman {
class PacmanGame;
}

class arcade::games::pacman::PacmanGame : public arcade::games::common::AGame {
public:
PacmanGame();

~PacmanGame() override = default;

/**
* @brief Game manifest
*
*/
static const shared::games::GameManifest manifest;

/**
* @brief Get the manifest object
*
* @return const shared::games::GameManifest&
*/
const shared::games::GameManifest &getManifest() const noexcept override;

/**
* @brief Allow game possible actions
*
* @param dt Delta time from last frame
*/
void compute(shared::games::DeltaTime dt) override;

/**
* @brief Add new point to player
*/
void addNewPoint(Vector2i position);

/**
* @brief When a ghost eat a player
*/
void eatPlayer(Vector2i position);

/**
* @brief Enable the ghost mode
*/
void canEatGhosts();

protected:
shared::games::DeltaTime _clock;
std::shared_ptr<PlayerEntity> _player;
std::shared_ptr<MapEntity> _map;
std::vector<std::shared_ptr<GhostEntity>> _ghosts;

bool _canEatGhost;
shared::games::DeltaTime _stopEatGhostTime;

/**
* @brief Redirect the ghost when he is blocked
* @param ghost
*/
void _redirectGhost(std::shared_ptr<GhostEntity> ghost);

int _currentScore;
};
19 changes: 19 additions & 0 deletions games/pacman/src/PacmanGameProvider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
** EPITECH PROJECT, 2024
** PacmanGameProvider.cpp
** File description:
** PacmanGameProvider class
*/

#include "PacmanGame.hpp"
#include "PacmanGameProvider.hpp"

using namespace arcade::games;

const shared::games::GameManifest &pacman::PacmanGameProvider::getManifest() const noexcept {
return PacmanGame::manifest;
}

std::shared_ptr<shared::games::IGame> pacman::PacmanGameProvider::createInstance() {
return std::make_shared<PacmanGame>();
}
35 changes: 35 additions & 0 deletions games/pacman/src/PacmanGameProvider.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
** EPITECH PROJECT, 2024
** PacmanGameProvider.hpp
** File description:
** PacmanGameProvider class
*/

#pragma once

#include "shared/games/IGameProvider.hpp"

namespace arcade::games::pacman {
class PacmanGameProvider;
}

class arcade::games::pacman::PacmanGameProvider : public shared::games::IGameProvider {
public:
PacmanGameProvider() = default;

~PacmanGameProvider() override = default;

/**
* @brief Provides the game manifest
*
* @return Manifest of current game
*/
const shared::games::GameManifest &getManifest() const noexcept override;

/**
* @brief Provides a new instance of the game
*
* @return Created game instance
*/
std::shared_ptr<shared::games::IGame> createInstance() override;
};
Loading

0 comments on commit b50bd0c

Please sign in to comment.