当前位置:  开发笔记 > 编程语言 > 正文

关于基于类的文本冒险游戏设计的质疑.

如何解决《关于基于类的文本冒险游戏设计的质疑.》经验,为你挑选了1个好方法。

我整个夏天都在学习C#,现在感觉就像我到目前为止做的一个小项目.我决定采用一种基于文本的冒险游戏.

游戏的基本结构将涉及具有多个扇区(或房间).进入房间后,将输出描述并采取一些行动等等; 能够检查,拾取,使用那个房间里的东西; 可能是战斗系统等等.扇区可以连接多达4个其他扇区.

无论如何,在纸上涂写关于如何为此设计代码的想法,我对我的部分代码的结构感到头疼.

我已经决定了一个球员级别,以及一个代表级别/地牢/区域的"级别"级别.这个级别的课程将由许多相互关联的"部门"组成.在任何给定时间,玩家将出现在该级别中的某个特定部门中.

所以这就是混乱:

从逻辑上讲,人们会期望像player.Move(Dir d)
这样的方法这样的方法应该改变关卡对象中的"当前扇区"字段.这意味着类Player需要知道类级别.嗯.并且Level可能必须操纵Player对象(例如,玩家进入房间,被某些东西伏击,从库存中丢失一些东西.)所以现在Level还需要持有对玩家对象的引用?

这感觉不太好; 一切都必须提到其他一切.

在这一点上,我记得从我正在使用的书中读到有关代表的内容.虽然我知道C++中的函数指针,但有关代表的章节中提供了一些带有"基于事件"编程观点的例子,我对此并没有多少启示.

这给了我设计类的想法如下:

玩家:

class Player
{
    //...

    public delegate void Movement(Dir d);   //enum Dir{NORTH, SOUTH, ...}

    public event Movement PlayerMoved;

    public void Move(Dir d)
    {        
        PlayerMoved(d);

        //Other code...
    }

}

水平:

class Level
{
    private Sector currSector;
    private Player p;
    //etc etc...

    private void OnMove(Dir d)
    {
        switch (d)
        {
            case Dir.NORTH:
                //change currSector
                //other code
                break;

                //other cases
        }
    }

    public Level(Player p)
    {
        p.PlayerMoved += OnMove;  
        currSector = START_SECTOR;
        //other code
    }

    //etc...
}

这是一个好的方法吗?
如果代表章节没有按原样呈现,我就不会想到使用这样的"事件".那么在不使用回调的情况下实现它的好方法是什么?

我习惯于发表非常详细的帖子......抱歉v__v



1> Alex Humphre..:

那么"游戏"类可以容纳大部分信息,如播放器和当前房间.对于诸如移动玩家之类的操作,游戏类可以基于房间的等级地图将玩家移动到不同的房间.

游戏类将管理游戏的各个组件之间的所有交互.

将事件用于此类事件会带来事件变得混乱的危险.如果你不小心,你最终会发现事件相互关闭并且溢出你的堆栈,这将导致标志在特殊情况下关闭事件,以及一个不太容易理解的程序.

UDPATE:

为了使代码更易于管理,您可以将主类之间的一些交互建模为类本身,例如Fight类.使用接口可以使主类执行某些交互.(请注意,我已经冒昧地发明了一些你可能不想要的东西).

例如:

// Supports existance in a room.
interface IExistInRoom { Room GetCurrentRoom(); }

// Supports moving from one room to another.
interface IMoveable : IExistInRoom { void SetCurrentRoom(Room room); }

// Supports being involved in a fight.
interface IFightable
{
  Int32 HitPoints { get; set; }
  Int32 Skill { get; }
  Int32 Luck { get; }
}

// Example class declarations.
class RoomFeature : IExistInRoom
class Player : IMoveable, IFightable
class Monster : IMoveable, IFightable

// I'd proably choose to have this method in Game, as it alters the
// games state over one turn only.
void Move(IMoveable m, Direction d)
{
  // TODO: Check whether move is valid, if so perform move by
  // setting the player's location.
}

// I'd choose to put a fight in its own class because it might
// last more than one turn, and may contain some complex logic
// and involve player input.
class Fight
{
  public Fight(IFightable[] participants)

  public void Fight()
  {
    // TODO: Logic to perform the fight between the participants.
  }
}

在你的问题中,你确定了如果你在Player类上遇到像Move方法这样的东西,你会有许多必须互相了解的类.这是因为移动既不属于玩家也不属于房间 - 移动会相互影响两个对象.通过对主要对象之间的"交互"进行建模,可以避免许多依赖关系.

推荐阅读
wangtao
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有