栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Funcode学习笔记:写一个维护性高、扩展性强的框架【By Myself】【C++】

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Funcode学习笔记:写一个维护性高、扩展性强的框架【By Myself】【C++】

首先,我们先说明我们对框架的需求:

拿框架中管理播放动画的模块举例子:

1:我们要想像框架中加入某个动画,且可以自定义动画的名字、可以自定义由其他动画转移到该动画的条件,这些工作只需要我们要调用框架中的函数,并传递正确的参数即可;

2:修改框架的过程必须尽量简单;

3:框架中的模块之间的耦合度要尽量低;

这些是我们对框架整体的要求,另外还有我们在写代码时的准则;

1:在稳定性面前效率靠后;

2:在扩展性面前,效率靠后;

3:在不损失稳定性和扩展性的前提下,尽量提高效率;

4:在同一功能需求下,能调用C++的库绝对不手写;

好说完前缀就是重头戏了;

还是以框架中的动画播放模块为例,下面是动画播放模块的大题思路和部分代码,以及一些性质:

1:拓展性:

既然我们要拓展性,就绝对不能用简单的语句来堆叠我们的代码,必须要用的数据结构了,这里本菜选择有动态扩展效果的树为重载我们框架的数据结构;

那我们来想一下,我们该怎么来定义点和线:

一个点我们定义为里面有我们需要播放动画的信息【比如动画的名字等等...】,然后线呢,是我们在点之间穿梭的工具,因为点之间是不能随便穿梭的,所有我们必须要给线上加一些通过的条件,这些条件必须是我们在游戏时能够收集到的信息【比如人物的速度、朝向、是否处于攻击状态等等】,然后根据这些信息来判断该转移到哪一个点【这里打个比喻,如果我们按下J键是要让我们的玩家攻击,那么我们可以设定一个变量,J键处于按下和不按下时该变量处于不同的值,然后我们线上的条件通过一些途径与该变量绑定,然后我们的线就可以捕捉到该点的变化,以此来改变点的所处点的位置,在这里就是转移到存储攻击动作的信息的点的位置】

有了点和线我们就要有东西来管理它们,换句话说就是我们给出可以确定某个点或者某条线的信息后,我们可以快速访问到该点或者线,这里的实现呢本菜是选择了C++库里面的Unordered_map容器,这个容器里面自带红黑树和平衡树,所以稳定性高,且支持随机访问【离谱的是随机访问的时间复杂度是常数级别】;

这里不懂Unordered_map的铜血可以上百度,很方便操作的;

这里本菜选择用C++的string类作为Key,然后点和线类作为Val,这样做的好处是调用的了C++库模板,提高了稳定性,且string更好将Key区别;

另外更管理点的方式不同,我们管理线的方式是通过将一些头点相同的线放到一个线包类中进行管理的【一条线从A->B点,则A点是头点,B点是尾点,要注意,我们讨论的线都是单向线】

因为有多个线包,所以在树类【整颗树的管理类】我们依然用string+unordered_map的方式来管理每一个线包,在线包类中我们依然用string+unordered_map来定位线包中的每一根线,其中线包的unordered_map中的string类是尾点的名字,树类中管理线包中的string是头点【要注意如果两台线的头点相同,那么他们在同一个线包中】

这里灵敏的铜血可能遇见看出来了,用以上方式,我们就可以做到用头点的名字和尾点的名字来在树中唯一定义一根线了;

class Point{
    std::string Name;//点的名字
    点的数据//
    提取数据的方法//
    外界变量对点的数据提取的改变方法//
    往点中加数据的方法//
}

class Line{
    std::string Name;//线的名字
    Conidtion condition;//通过这条线的条件
    Point *Scr,*Nect;//该线中头点和尾点的指针
    通过该先的方法//
}

class LinePack{

    std::unordered_map Pack;
    判断线是否可通过的方法//
}

class Tree{
public:

    Point *PointPlaying;//正在调用的树的指针

    std::unordered_map PointMap;
    std::unordered_map LinePackMap;
    
    void AddPoint(std::string Name){//树中增加一个名字为Name的点
        PointMap[Name]=Point(Name);
        LinePackMap[Name]=LinePack(Name);//给该点加一个线包
    }

    void AddLine(std::string HeadName,std::string Tail){//在HeadName点与Tail点之间搭建一根Head->Tail的线
        LinePackMap[Head].Pack[Tail]=Line();
    }

}

这些是大概的样子,当然,只是实现了一些简单的存储点和线,以及定位点和线,但转移的方法有千千万万,点存储的数据又是千千万万,怎么来提取点中的数据的方式又是千千万万,所以这可树的可塑性极其高;

尽管本菜懂的东西不可能在一篇文章中写出来,但本菜可以分享一种效率高,稳定性高、扩展性高的提取点中的数据和存储点中的数据的方法,这个方法的灵感来自于Unity中的Blend tree;

本菜就不写代码了,直接放思路了;

我们在点在加一个坐标系类,坐标系类中有一个红点,我们可以在坐标系中加入一些数据单元,这些数据单元有x,y坐标,红点最靠进哪个数据单元,我们就提取哪个数据单元;

其红点的移动是靠外界的变量来控制的;

说实话,这里本菜只是将大概的思路讲了出来,会上面那些还只是杯水车薪,要真写出一颗神树,真得花很多时间来写;

【上面内容唯是本菜所感】

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/923417.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号