【4月6日】
【一些想法】
明天将基于MVC模型规范现有代码和逻辑。
其中Model存储自身信息及状态,及改变自身信息或获取自身信息的方法和规则,在信息或状态改变时发送消息。其不应继承与monobehavior。
View接受点击或者其他用户操作,提供改变自己的方法,接受用户操作,并将操作消息发送给Controll。并且负责Update。
Controller接受Model的消息,改变View;接受View的消息改变Model。
将整个游戏分为五个部分:People,Map,Ui,Time。
在游戏中,主要输入为用户输入,游戏时间变化,Ai行动。
游戏时间变化一方面影响Map的外观,另一方面影响Ai行动,并表现在Ui上。
用户输入影响Map外观,Player行动,Ai行动,Ui,Time
Ai行动影响Map外观,Ui
故我们设置三个总Controller来分别处理三种输入。
一个一个分析。
首先对于游戏时间,只提供查询和修改的接口。所有需要时间的其他事物,都将调用这些方法。
对于用户点击,分为点击地图(物品或地板),点击NPC,点击Ui。则该Controller接受来自地图,NPC,Ui的被点击需要Player参与的调用,调用修改Player的Controller。Controller修改完毕后通过该Controller发信息给对应的地图,NPC和Ui
对于Ai,可以作为无点击自发的Player行为。配置文件读取时间,模拟用户点击地图的行为。
对于Map,让其只拥有寻路、建造、统计的功能。
从底层开始,每一个Grid包含有自己的坐标(以及遮盖情况、寻路算法参数、包含人数)作为Model。Grid的View检测grid的遮盖情况,修改Model的遮盖情况,和自身贴图,在自己被点击时发送消息。
每一个地板GoundModel包含有一组GridModel,和自己的一些基本信息。
每一个墙WallModel包含有另一组GridModel,和自己的一些基本信息。
每一个房间Room包含有两组GridMap,每一个场地Place包含有一组GridMap。
每一层Floor包含有该层的墙,地板,房间,场地。其Controller负责创建这些,并且分发来自上级的调用。
Map包含所有的Floor。监听所有Grid的点击事件,调用对应的Floor的Controller来处理事件。
Item
每个Item的Model包括 State(是否在建造,是否在使用,被如何使用,是否等待拆除等等)和Info。这些状态的改变会通知Controller让View播放相应的动画。View接受点击发送给 Controller来处理交互。
而Ai的Contoller将直接调用Controller中的函数来模拟交互所产生的使用效果。Item属于层。
【4月7日】
【一些想法】
将总的Controller分为五类,分别是Event、Map、People、Time、Ui
定义Model保存和修改状态及数据。提供保存修改状态数据的方法。当一些状态数据发生改变时,通知View。
定义View具体处理某个控件的移动、变形、贴图变化等,接受用户点击和交互请求。接受Modle的消息,做出显示上的调整,或调用Controller方法处理。限制其只能够查看Modle和接受Modle的消息。
定义Controller向View提供方法,接受来自Manager的消息,接受来自Manager的消息。作为层级之间沟通的桥梁。
定义Manager沟通五大类Controller。五大类Controller彼此不知道对方的存在。通过Manager协调调用各大类的Controller来运作游戏。
五大类之间的关系,决定了一个Manager需要沟通多少个大类,同时决定了Controller需要发送多少消息。并且,我们将Ui层剥离出去,因为对于Ui层来说,他本身就是一个View,其Manager是一个Controller,所有涉及Ui的为它的Model,它可以自己决定它想要使用的数据,它只关心数据改变,和输入操作,但是其他类不能从它这里获得内容。同样将Event剥离出去,它监听所有它想听的数据,并在数据符合它需要的时候修改其他类。然后把Time写成一个全局可以查询的值,其他类用update更新即可。
然后我们根据输入来考虑各种情况。
最本质的输入只有两种情况,一种是玩家的操作,一种是游戏时间的变动。
玩家的操作会影响Time,但是我们让这个行为仅仅只能通过Ui实现,那么Time就可以省略了。其次,玩家的操作点击地图和NPC,会影响Player和NPC的行为。其中,和NPC的交流需要通过Map。
Time的变动是最主要的变动。Time的变动会影响NPC的自主行为。我们同样给NPC提前设置一个行为队列,当时间合适的时候(可以用update实现)他就去执行。NPC的行为会单独的和地图发生。同时Time会影响到Map的外观效果(这也可以用Update 实现)。
最终我们需要实现的Manager在这里只需要包含People和Map即可。
现在,考虑People和Map的Manager
首先把People分为Player和NPC。
用户输入地图点击,Player做出相对的动作。
因为动作会消耗时间,所以每当Player完成一条动作的时候都需要回去告诉Map我完成了。动作队列将显示在Ui上。
为Player写一个行为队列。每一个行为队列都可以基础的表达为,走到item处,产生动画,结束。把单纯的和Grid交互的行为定义为Moving。那么剩余的item都会包含有Moving行为为先导。同时Map也应该有一个同样的队列,来表示发出的请求。即,当我们和Map发生交互了以后,Map首先添加这个动作到队列,然后发送这个消息给Manager,Manager将这个动作添加到Player的队列。每完成一个动作,Player发送消息给Manager,Manager从Map的队列中删除这个动作。
同理,对与NPC来说,他的行为队列是由Time决定的。Player的行为会打断他的队列。将其动作分为两种,固定的和随机的。固定的不能被打断,故不需要Map去维持它的队列,它只需要在开始和结束时各通知Manager一次来改变Map就可以了。而Player可以在随机动作时段访问NPC,一旦Player碰到NPC就打断原有的随机动作,从而产生一个动作停止。接下来Player和NPC的互动就是Peopke内部的事情了。
【4月8日】
【开发记录】
今天终于把之前的内容全部改好了,现在他是一个完整的MVC模式了。
同时修订了一些层级之间的规则。对于任何一个下层的Controller,向上发送消息到最底层的相关Controller,然后从该Controller开始层层上传,直到到最上方的相关者。这样使得通过调用在层级间向下发送任务,通过消息向上通知任务完成。
在此基础上写了基类BaseController和基类BaseView。
同时,将People从原来的基类定义为People组的上层类。其Model拥有一个Npc链表和一个Player。Npc和Player的基类变更为BasePeople。
设计一个People的行为队列:
先进先出。
一个状态对应一个行为。
在行为发生时,有两种种情况,一种是含非Move的行为,一种是Move行为。我们将纯Move行为看做是和地板的交互,这就需要提供行为终点的交互目标,在这里把目标定义为一个Controller。
现在,PeopleAction含有四个参数,行为、目标、路径、行为的发起者。
这个队列由Manager和接受者共同维护。即只从PeopleModel处创造该队列。
注意:
事件应该在执行的时候再去向发起者获取内容。