Witam, proszę o ocenę poniższego kodu źródłowego. Jego głównym zadaniem jest obsługa zdarzeń klawiatury, aby umożliwić graczowi ruch.
MovementKeys.h (klawisze do sterowania graczem)
#pragma once
#include <SFML/Window/Keyboard.hpp>
class MovementKeys {
public:
MovementKeys(sf::Keyboard::Key up,
sf::Keyboard::Key down,
sf::Keyboard::Key left,
sf::Keyboard::Key right)
: up(up), down(down), left(left), right(right) {}
bool isUp(sf::Keyboard::Key key) const { return key == up; }
bool isDown(sf::Keyboard::Key key) const { return key == down; }
bool isLeft(sf::Keyboard::Key key) const { return key == left; }
bool isRight(sf::Keyboard::Key key) const { return key == right; }
private:
const sf::Keyboard::Key up;
const sf::Keyboard::Key down;
const sf::Keyboard::Key left;
const sf::Keyboard::Key right;
};
PlayerEvent.h
#pragma once
class PlayerEvent {
public:
void turnOnMovingUp() { movingUp = true; }
void turnOffMovingUp() { movingUp = false; }
bool isMovingUp() const { return movingUp; }
void turnOnMovingDown() { movingDown = true; }
void turnOffMovingDown() { movingDown = false; }
bool isMovingDown() const { return movingDown; }
void turnOnMovingLeft() { movingLeft = true; }
void turnOffMovingLeft() { movingLeft = false; }
bool isMovingLeft() const { return movingLeft; }
void turnOnMovingRight() { movingRight = true; }
void turnOffMovingRight() { movingRight = false; }
bool isMovingRight() const { return movingRight; }
private:
bool movingUp = false;
bool movingDown = false;
bool movingLeft = false;
bool movingRight = false;
};
PlayerEventHandler.h
#pragma once
#include <SFML/Window/Event.hpp>
class PlayerEvent;
class MovementKeys;
class PlayerEventHandler {
public:
void handleEvent(PlayerEvent& playerEvent,
const MovementKeys& movementKeys,
const sf::Event& event) const;
private:
void handlePressedKey(PlayerEvent& playerEvent,
const MovementKeys& movementKeys,
const sf::Event::KeyEvent& keyEvent) const;
void handleReleasedKey(PlayerEvent& playerEvent,
const MovementKeys& movementKeys,
const sf::Event::KeyEvent& keyEvent) const;
};
PlayerEventHandler.cpp
#include "PlayerEventHandler.h"
#include "PlayerEvent.h"
#include "MovementKeys.h"
void PlayerEventHandler::handleEvent(PlayerEvent& playerEvent,
const MovementKeys& movementKeys,
const sf::Event& event) const
{
switch (event.type) {
case sf::Event::KeyPressed:
handlePressedKey(playerEvent, movementKeys, event.key);
break;
case sf::Event::KeyReleased:
handleReleasedKey(playerEvent, movementKeys, event.key);
break;
}
}
void PlayerEventHandler::handlePressedKey(PlayerEvent& playerEvent,
const MovementKeys& movementKeys,
const sf::Event::KeyEvent& keyEvent) const
{
const sf::Keyboard::Key key = keyEvent.code;
if (movementKeys.isUp(key))
playerEvent.turnOnMovingUp();
else if (movementKeys.isDown(key))
playerEvent.turnOnMovingDown();
else if (movementKeys.isLeft(key))
playerEvent.turnOnMovingLeft();
else if (movementKeys.isRight(key))
playerEvent.turnOnMovingRight();
}
void PlayerEventHandler::handleReleasedKey(PlayerEvent& playerEvent,
const MovementKeys& movementKeys,
const sf::Event::KeyEvent& keyEvent) const
{
const sf::Keyboard::Key key = keyEvent.code;
if (movementKeys.isUp(key))
playerEvent.turnOffMovingUp();
else if (movementKeys.isDown(key))
playerEvent.turnOffMovingDown();
else if (movementKeys.isLeft(key))
playerEvent.turnOffMovingLeft();
else if (movementKeys.isRight(key))
playerEvent.turnOffMovingRight();
}
Player.h
#pragma once
#include "MovementKeys.h"
#include "PlayerEvent.h"
#include "PlayerEventHandler.h"
#include <SFML/Window/Event.hpp>
class Player {
public:
Player(const MovementKeys& movementKeys)
: movementKeys(movementKeys) {}
void handleEvent(const PlayerEventHandler& eventHandler, const sf::Event& event)
{
eventHandler.handleEvent(playerEvent, movementKeys, event);
}
private:
const MovementKeys movementKeys;
PlayerEvent playerEvent;
};
Generalnie, czy wykorzystanie klasy PlayerEventHandler ma sens? Jej metoda handleEvent przyjmuje aż 3 argumenty, a przecież równie dobrze można to zaimplementować bezpośrednio w klasie Player.
Uogólniając, czy wydzielenie zachowania obiektu od jego danych to dobry pomysł? Jeżeli tak, to czy warto dane pakować w strukturę, aby ułatwić przekazywanie ich do klas obsługujących zachowanie?