• cocos2dx 魔塔项目总结(一)


    《魔塔天城》发布已经有半年的时间了,一直想找时间来总结一下这个项目,但总是一拖再拖。如果再这么拖下去,就永远都不会有时间来写这个总结了,时间总是挤出来的。

    魔塔天城使用的cocos2dx 3.2版本,当时这个版本刚刚发布。网上的学习资料都是2.0版本的。只有官网提供的示例demo是最新的,好在这些demo涵盖的面比较宽,对于学习API来说已经足够了。

    魔塔的程序框架并不复杂

    总的来说就是这几大块,对象继承结构,碰撞检测,node和layer层次结构,UI实现,剧情脚本

    在魔塔世界中 World是由Cell构成的,所有的事物都是Cell。我们按照MVC思想来分析一下Cell

    model:Cell的属性集合就是我们所说的MVC模式中model,我们从外部读取数据表格文件中的数据(这里我使用了csv文件),然后初始化这些Cell的model(注意:数据表格中的数据通常记录的是类的基本属性),在游戏中不同的对象model会产生不同的变化,如果我们想要保存这些变化,只要保存这些容易发生变化的属性就行了,这里假设保存在model_New里。然后下次再加载存档的时候,首先利用数据表格初始化model,然后再加载保存的model_New覆盖合并当前model,这就是基本的存档功能。

    所以我的Cell必须实现这些初始化,加载并保存model的功能,这里我们就可以添加这些函数

    virtual void initModel() = 0;
    virtual void loadModel(ValueMap &map) = 0;
    virtual ValueMap saveModel() = 0;

    这里我们使用cocos2dx 3.2 提供的 ValueMap数据结构实现我们的model。

    view:这里的View应该不单单是一张张图片,因为我们还需要动画。所以cocos2dx里面的Sprite显示精灵是最佳选择。

    controller:事物之间是需要交互的,这样我们的世界才如此生机盎然。在程序里,事物就是对象,那么如何让对象之间交互呢,没错,利用事件Event。cocos2dx已经为我们实现好了这些事件机制,我们唯一需要做就是为每个对象添加事件侦听或回调函数,一个发送事件,一个接受事件并作出反映,这就实现了交互。当然,我们也可以通过发送事件来操纵对象,就像游戏中的控制台一样,让对象接收命令。

    事件监听

    _listener = EventListenerCustom::create(getName(), [=](EventCustom *event){onTrigger(event);});
    _eventDispatcher
    ->addEventListenerWithFixedPriority(_listener, 1);

    回调函数

    virtual bool onTrigger(EventCustom *event) = 0;

    事件机制就是观察者模式的衍生,在cocod2dx中我们的事件都由EventDispatcher的一个实例来管理,这就像是接线员一样。会根据号码(事件id)来传递事件。这个事件id我们用对象的名字来表示,因此,这就变得非常好理解了,对象之间通过名字来交互也更现实些。

    Cell是万物的基类,由此我们可以派生出Item、Actor等一系列子类。万物是由上帝创造的,在这个程序架构的世界里,我们就是上帝。但是要让我们一个一个new对象却是很累,所以工厂模式是派上用场了。CellFactory,根据我们的订单创建Cell,它有可能是一个道具,也有可能是个NPC。总之把你的需求打包成一个map数据结构传递给工厂就行了。

    创建完成了Cell,但我们还要把它添加到世界里。

    World是个魔塔的世界,这个世界除了塔没别的。所以World里包含Tower的数组

    Tower魔塔是由一层一层的Floor构成的,所以Tower里面有Floor的数组。

    我们是世界的二维的,每次只能显示一层Floor。所以Floor就是游戏地图的基本单位。我们创建的Cell都要添加到Floor里面,Floor会包含很多元素(地面、墙壁、怪物、NPC、道具等等),也就是说这些元素都要派生自Cell。

    Cell也是碰撞检测的基本单位,魔塔中的碰撞检测是基于方格碰撞的。Cell的有效碰撞区域都是一个个相同大小的方块。碰撞检测说到底就是通过数学计算判断两个形体是否相交。为了简化计算,我们通常把形体简化成矩形或长方体。如果是多个物体的话,我们往往会让每个物体都跟其他物体作比较,如果物体很多的话,这会非常耗时。所以我们需要方法简化比较次数,比如有些物体之间相距很远,是绝对不可能会碰到的,通过划分区域可以很好的解决这个问题。区域的划分也是十分讲究的,比如四叉树算法、八叉树算法。这里不做具体分析,有兴趣的同学可以自行百度。在魔塔中,我们就不用使用这些复杂的算法了,因为我们的地图通常并不大,但是区域划分是不能忽略的,我们可以将地图划分为网格。网格中的每一个小方格都是一个区域,而且大小与Cell的有效碰撞区域相同。

  • 相关阅读:
    1052 Linked List Sorting (25 分)
    1051 Pop Sequence (25 分)
    1050 String Subtraction (20 分)
    1049 Counting Ones (30 分)
    1048 Find Coins (25 分)
    1047 Student List for Course (25 分)
    1046 Shortest Distance (20 分)
    1045 Favorite Color Stripe (30 分)
    1044 Shopping in Mars (25 分)
    1055 The World's Richest (25 分)
  • 原文地址:https://www.cnblogs.com/sdlwlxf/p/4553197.html
Copyright © 2020-2023  润新知