0评论

设计模式之享元模式(Flyweight)

萧然 2018-10-25 111浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏开发行业精英群711501594

命令模式一样,本次是对《Game.Programming.Patterns》中享元模式的一些理解和示例转换,代码为主,欢迎大家的意见和建议~~

先看一下菜鸟教程对享元模式的描述:

个人理解的享元,顾名思义就是共享单元,使用一个共享实例,代替大量重复的实例。

实现:将地图划分为多个规则排列的格子,随机地形
    //地形实例类
    public class Terrain
    {
        public Terrain(int terrainCost, bool terrainIsWater, Texture terrainTexture)
        {
            movementCost = terrainCost;
            isWater = terrainIsWater;
            texture = terrainTexture;
        }
        //只读属性
        public int movementCost { get; private set; }
        public bool isWater { get; private set; }
        public Texture texture { get; private set; }
    }
    //所有地形数据类
    public class Wold
    {
        //地形块实例(该实例是指数据实例, 非实例化的对象)
        Terrain grassTerrain, hillTerrain, riverTerrain;
        //地形块贴图
        Texture grassTexture, hillTexture, riverTexture;
        int width = 10, height = 10;
        //所有地形块数据
        public Terrain[][] terrain { get; private set; }
        public Wold()
        {
            //创建三种地形实例, 每种地形创建一个, 是为共享单元
            grassTerrain = new Terrain(1, false, grassTexture);
            hillTerrain = new Terrain(3, false, hillTexture);
            riverTerrain = new Terrain(2, true, riverTexture);
            //
            GenerateTerrain();
        }
        //创建地形
        void GenerateTerrain()
        {
            //每个类型的地形块都是相同的, 相同的地形块引用相同的地形实例
            //添加地形块
            terrain = new Terrain[width][];
            for (int i = 0; i < width; i++)
            {
                terrain[i] = new Terrain[height];
                for (int j = 0; j < height; j++)
                {
                    if (Random.Range(0, 10) < 2)
                        terrain[i][j] = hillTerrain;
                    else
                        terrain[i][j] = grassTerrain;
                }
            }
            //加入河流
            int x = Random.Range(0, width);
            for (int y = 0; y < height; y++)
            {
                terrain[x][y] = riverTerrain;
            }
        }
    }
    //测试类
    public class WoldControl : MonoBehaviour
    {
        //MCV数据分离, Wold只保存数据信息, 即M层, 在C层(该测试类)控制实例化地形的时机及方式
        Wold wold;
        void Start()
        {
            CreatWold();
        }
        //在此实例化地形, 可以考虑动态加载, 协程分批次加载
        void CreatWold()
        {
            wold = new Wold();
            for (int i = 0; i < wold.terrain.Length; i++)
            {
                for (int j = 0; j < wold.terrain[i].Length; j++)
                {
                    //具体地形块,实例化到场景之后, 由V层控制显示
                    Debug.Log(wold.terrain[i][j].movementCost);
                }
            }
        }
    }