OOP中的正确方法。游戏示例。 Player :: walk或Map :: playerWalk?

时间:2014-11-03 15:55:16

标签: c++ oop class-design

假设有一个游戏。有一个地图类和一个玩家类。地图存储字段和字段存储播放器。 这将是一个在OOP中正确的方法。当负责玩家行走的方法是Player :: walk或Map :: playerWalk?

关于第一个例子(Player :: walk),似乎在现实生活中这是正确的方式和它的相似之处 - 走路的玩家, 但是它必须通过地图实例访问目标字段,检查它是否可以走到那里,从开始字段中删除它并在目的地字段上添加它,我的印象是玩家会过多地知道"。

3 个答案:

答案 0 :(得分:3)

最终这是一个设计问题,两者都很适合OOP范例。

我倾向于在语义上放置最有意义的类。在这种情况下,这意味着Player::walk,除非地图做了什么让“玩家”移动(即在脚蹼游戏中,游戏板使球[又名'玩家'移动)然后它可能更多语义使该实体调用例如Board::movePlayer

如果您选择Player::walk设计,则应将地图实例传递给播放器。所以你最终得到了Player::walk(Map &map /*more parameters here, maybe a direction or vector speed?*/)

要指出的另一点是,您应该尝试告诉而不是询问。这意味着不是:

//in Player::walk
if (map.cells[wantToWalkTo] == 0) {
    map.cells[wantToWalkTo] = this.playerId;
}
//TODO: handle failed moves

您应该执行以下操作:

bool moved = map.moveTo(position, this); //encapsulate the logic for moving a player to a position
//TODO: handle failed moves

答案 1 :(得分:1)

您的播放器实例不必“知道”所有这些内容。它可以通过接口与Map实例通信。一个人可以看到周围的环境,看到一些东西,但看不到其他东西(例如可以看到一堵墙,但不能看到背后的东西)。 Map实例可以控制可见内容和不可见内容。

Python-ish伪代码:

class Player:
    def __init__(self, Map, location):
        """Create a player, and tell them what Map they live on."""
        self.Map = Map
        self.location = location

    def walk(self, destination):
        """Try to walk to the destination."""
        path = self.Map.path_visible(location, destination)

        if path:
            self.location = destination

class Map:
    def path_visible(self, location, destination):
        """Can a player at location see how to get to the destination?"""

答案 2 :(得分:0)

正确的OOP方法是让地图呈现某种允许的接口:

  1. 检查某个字段是否为空/该字段上的对象是
  2. 在地图上放置对象/删除它们
  3. 移动播放器的逻辑应完全在播放器类中。因此,检查玩家是否可以访问目标字段,是否为空等等,应该由玩家使用Map接口或其他类提供的信息来处理。例如,当你想允许玩家穿过墙壁,在水上行走或类似的东西时 - 例如,改变的是玩家,而不是地图!