对象池设计与打飞机演示

先来几张项目运行的截图。

 

是的。这就是大名鼎鼎的打飞机。看到那小飞机没有,是我用Cube拼出来的-_-。不过那不是重点。我们今天的重点是讲对象池。我们更多关注的是怎么管理子弹,而不是飞机~~~

不过文章最后还是会给出完整工程和可运行exe的下载地址。

0、为什么写

A、刚好项目需要,然后之前的对象池我胡写的(可以说没有)

B、刚好群里有人在问

C、刚好好久没发文章,不知道写什么

1、什么是对象池

        我经常说的一点,理解概念,理解基础很重要。因为概念理解深刻了,代码也就出来了。

        所以大家对这个概念如果还不懂的,要赶紧去查查。这里我不多说了,各种百科都可以找到。

2、我的设计

        我的对象池主要由:对象池、对象、对象工厂组成。

        为了拓展,对象池抽象为IObjectPool、对象为泛型、对象工厂为IObjectFactory。

3、IObjectPool

        接口比较简单,也做了注释。就不说明了。接着看

4、IObjectFactory

        依旧很简单的接口。没错,对象池真的很简单。

5、对象池实现BaseObjectPool

        这是一个基础的对象池。他构造的时候指定工厂和最大空闲的对象数目。

最大空闲的对象数目是干嘛的?就是比如你一般情况同时只会存在10个对象A。但是某个峰值从池中取出了100个。那么当这些对象被存回对象池的时候,有些会被抛弃。最后池中可用的对象不超过构造时指定的最大数目。

6、休息一下

        这时候,基本一个对象池已经完成了。就是你可以new BaseObjectPool。指定自己的工厂,然后就可以通过Take从池中取对象,通过Restore将对象存回。但是,还没完。

        我们不会就此止步。

        我还想着。这样我需要手动调用Restore来将对象存回对象池。有没有方便一点的。

7、定义一个主动回收的对象池IActiveRestoreObjectPool

        可以看到这个接口是从我们前面的对象池接口中继承的,然后又增加了一个检查可回收对象的方法。

8、主动回收对象池的实现ActiveRestoreObjectPool

        这个类之前在一些论坛或社区发的时候,笔误实现了IObjectPool。实际应该是实现IActiveRestoreObjectPool。

        可以看到,这个类其实很多接口的实现是托管给我们之前的BaseObjectPool来实现的。这样我们可以省下不少功夫~~

        然后可以看到CheckRestore方法中是通过IAutoRestoreObject中的IAutoRestoreChecker来检查一个对象是否可以被回收到池中。

        IAutoRestoreObject和IAutoRestoreChecker都是为了做主动回收而引入的新接口。

        我们接着看

        这两个接口和实现都简单的没法说了。。。

9、为了更方便的和U3D结合,我继续提供了U3DAutoRestoreObjectPool

        之前的类和接口都是与U3D无关的,没有引用到U3D的类。可以放到任何C#项目中使用。

        其实大家设计代码也应该如此,应该一步步地,从最本质剥离出通用的东西。

        到这一步,我们才设计出U3DAutoRestoreObjectPool,他是一个U3D组件。但是也具备了我们的对象池功能。

        从代码中可以看到这个组件引用了一个主动回收(ActiveRestoreObjectPool)的对象池,并且用PrefabFactory来构造这个对象池。

        然后在Update的时候会调用对象池的CheckRestore来检查哪些对象可以被回收,并实施回收处理。

        那么PrefabFactory是什么?

        是的,就几行代码。他就是从预设创建GameObject、隐藏和显示GameObject而已。

        看了那么多无聊的代码。或许应该看看怎么使用。

10、怎么调用对象池

        A、你可以直接通过new创建具体的对象池实现,然后从中获取对象。

        B、可以直接获取U3DAutoRestoreObjectPool组件,然后从中获取对象。

        C、通过实现我们定义的IObjectPool或IActiveRestoreObjectPool接口来自定义对象池(不要以为自定义就很麻烦,从上面就可以看到自定义其实很多还是组合了我们已经实现的BaseObjectPool来实现的)。

11、具体案例-打飞机

        A、打开我们工程中的场景

2

        B、选择Airplane对象

3

        这个就是飞机了。可以发现他上面有两个组件。

        一个是我们之前定义的U3D对象池实现U3DAutoRestoreObjectPool

        另一个是TestCastBullet组件。

        这个组件主要就是控制飞机移动、发射3种类型的子弹的。好吧。写到这里。我发现这个类名取的不好,如果叫AirplaneController可能更好。。。

        不管了。。先看代码

        大家可以看到在Update里面,是怎么从池中取数据的。

4

        至此,对象池从定义到实现到调用基本都讲完了。

        项目中还有控制雷和子弹的类的,大家有兴趣就自己去翻翻咯。

        是不是觉得一个对象池还是挺简单的,这。。怪我咯~~

        最后大家有不懂的再讨论就OK啦。

项目可运行程序下载:http://pan.baidu.com/s/1ntKhSHN

项目源文件下载:http://pan.baidu.com/s/1qWMdEck

发表评论

电子邮件地址不会被公开。 必填项已用*标注