Arkanoid
Arkanoid game with OOP patterns
Install / Use
/learn @LimeTheCoder/ArkanoidREADME
Arkanoid
Arkanoid game based on design patterns
Patterns
Facade
Facade pattern hides the complexities of the system and provides an interface to the client using which the client can access the system.
- Class diagram

- Code sample
<b>resource_manager.h</b>
class ResourseManager {
public:
sf::Texture* getTexture(Textures::Code code);
sf::Font* getFont(Fonts::Code code);
private:
TextureManager texture_manager;
FontManager font_manager;
};
<b>resource_manager.cpp</b>
sf::Texture* ResourseManager::getTexture(Textures::Code code) {
return texture_manager.getTexture(code);
}
sf::Font * ResourseManager::getFont(Fonts::Code code) {
return font_manager.getFont(code);
}
Flyweight
Flyweight pattern tries to reuse already existing similar kind objects by storing them and creates new object when no matching object is found.
- Code sample
sf::Texture *TextureManager::getTexture(Textures::Code code) {
sf::Texture *texture = nullptr;
if(textures.find(code) != textures.end())
return textures[code];
texture = new sf::Texture();
switch (code) {
case Textures::Code::MenuBackground:
texture->loadFromFile(ResourceLocations::MenuTexture);
break;
case Textures::Code::ScoreBackground:
texture->loadFromFile(ResourceLocations::ScoresTexture);
break;
case Textures::Code::GameBackground:
texture->loadFromFile(ResourceLocations::GameTexture);
break;
default:
break;
}
textures[code] = texture;
return texture;
}
Command
Command pattern encapsulates a request or as an object, thereby letting you parametrize clients with different requests, queue or log requests, and support undoable operations.
- Class diagram

- Code sample
<b>command.h</b>
class Command {
public:
virtual void Execute(Paddle &paddle) = 0;
};
class MoveLeftCommand : public Command {
public:
void Execute(Paddle &paddle) {
paddle.moveLeft();
}
};
class MoveRightCommand : public Command {
public:
void Execute(Paddle &paddle) {
paddle.moveRight();
}
};
class DefaultCommand : public Command {
public:
void Execute(Paddle &paddle) {
paddle.stayAtPlace();
}
};
<b>play_state.cpp</b>
if(sf::Keyboard::isKeyPressed(BUTTON_LEFT) && paddle.getLeft() > 0)
current_command = button_left;
else if(sf::Keyboard::isKeyPressed(BUTTON_RIGHT) &&
paddle.getRight() < WINDOW_WIDTH)
current_command = button_right;
else
current_command = default_command;
State pattern
In State pattern, we create objects which represent various states and a context object whose behavior varies as its state object changes.
- Class diagram

- Code sample
<b>game_state.cpp</b>
class GameState {
public:
GameState(Game *state_holder) : game(state_holder) {}
virtual void render() = 0;
virtual void update() = 0;
virtual void processEvents() = 0;
protected:
Game *game;
};
<b>game.cpp</b>
GameState* Game::getState() const {
if(screens.empty()) return nullptr;
return screens.top();
}
void Game::addState(States::Code state) {
switch (state) {
case States::Code::Game:
screens.push(new PlayState(this));
break;
case States::Code::Menu:
screens.push(new MenuState(this));
break;
case States::Code::Pause:
break;
case States::Code::Scores:
screens.push(new ScoresState(this));
break;
case States::Code::EndGame:
screens.push(new EndState(this));
default:
break;
}
}
void Game::changeState(States::Code state) {
if(!screens.empty())
popState();
addState(state);
}
void Game::popState() {
delete screens.top();
screens.pop();
}
Observer pattern
Observer pattern is used when there is one-to-many relationship between objects such as if one object is modified, its depenedent objects are to be notified automatically.
- Class diagram

- Code sample
<b>ball.cpp</b>
void Ball::attach(IObserver *observer) {
observers.push_back(observer);
}
void Ball::detach(IObserver *observer) {
observers.remove(observer);
}
void Ball::notifyObservers() {
for(IObserver *iter : observers) {
iter->handleBallPosChange(*this);
}
}
Prototype
Prototype pattern refers to creating duplicate object while keeping performance in mind.
- Class diagram

- Code sample
Block* BlockSpawner::getBlock(int type) const {
Block *out = nullptr;
switch (type) {
case 3:
out = strongBlock->clone();
break;
case 2:
out = mediumBlock->clone();
break;
case 1:
out = easyBlock->clone();
break;
default:
break;
}
Screens
Main menu

Highscores

Game process

Game over

Related Skills
node-connect
337.3kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
83.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
337.3kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
83.2kCommit, push, and open a PR
