决战-Pow!第三集:对象系统
2018-02-05 本文已影响6人
回忆并快
这一集,为大家带来对象系统。
这个对象系统主要是解决了游戏内对象的管理(对象的增删查改),同时为了调用高效,使用了对象池来缓存已经创建的对象,每次重用,我们只需要重置即可。
首先实现一个对象池,不使用Laya提供的Pool自己建立一个,通过一个栈来管理:
1.能重用对象都需要编译 IPoolObject接口
interface IPoolObject {
getPoolType(): string;
dispose(): void;
}
2.对象池类:
class ObjectPool{
private _poolIdleObject:Dictionary<string, Stack<IPoolObject>>;
constructor(){
this._poolIdleObject = new Dictionary<string, Stack<IPoolObject>>();
}
public release(){
for (var pair of this._poolIdleObject)
{
while(pair.value.count != 0){
let obj:IPoolObject = pair.value.pop() as IPoolObject;
obj.dispose();
}
pair.value.clear();
}
}
public push(obj:IPoolObject):void {
let type:string = obj.getPoolType();
let stackIdleObject:Stack<IPoolObject> = this._poolIdleObject.get(type);
if(stackIdleObject == null) {
stackIdleObject = new Stack<IPoolObject>();
this._poolIdleObject.addKeyValue(type, stackIdleObject);
}
stackIdleObject.push(obj);
}
public pop(type:string):IPoolObject {
let stackIdleObject:Stack<IPoolObject> = this._poolIdleObject.get(type);
if(stackIdleObject != null && stackIdleObject.count > 0) {
return stackIdleObject.pop();
}
return null;
}
}
接着我们就可以建立一个用于继承实体对象类: EntityObject
提供实例化和释放的方法,需要严格按照接口进行。
class EntityObject implements IPoolObject {
private _isRelease: boolean = false;
public get isRelease(): boolean {
return this._isRelease;
}
constructor() { }
public instanceInFactory() {
this._isRelease = false;
}
public releaseInFactory() {
if (!this._isRelease) {
this.release();
this._isRelease = true;
}
}
public release() { }
public getPoolType() {
return this.constructor.name;
}
public dispose() {}
}
编写我们的实体(里面的View可以暂时忽略,下一集,对象视图再讲):
这里是我们处理对象逻辑的地方,都以数据进行驱动,例如下面type来控制创建的Icon类型。
class PowIconEntity extends EntityObject{
constructor(){
super();
}
private _pos:Laya.Point = new Laya.Point(0, 0);
private _type:number = GameVKey.SCISSORS;
public create(type:number){
this._type = type;
let view:PowIconView = ViewFactory.createView(PowIconView, this) as PowIconView;
view.setType(type);
}
public get type():GameVKey{
return this._type;
}
public release() {
ViewFactory.releaseView(this);
}
public moveTo(px:number, py:number){
this._pos = new Laya.Point(px, py);
}
public get position(){
return this._pos;
}
}
有了这些,我们需要统一的接口来进行对象的创建和重用:
使用简单工厂模式解决。这样的好处,统一了创建和销毁逻辑,方便调用管理,不同类的对象试用不同的栈结构管理,查找比较高效。
class EntityFactory {
private static _isInit: boolean = false;
private static _listObject: List<EntityObject>;
private static _objectPool: ObjectPool;
constructor() {
}
public static init(): void {
if (this._isInit) {
return;
}
this._isInit = true;
this._listObject = new List<EntityObject>();
this._objectPool = new ObjectPool();
}
public static release(): void {
this._isInit = false;
for (let i = 0; i < this._listObject.count; i++) {
this._listObject.get(i).releaseInFactory();
this._listObject.get(i).dispose();
}
this._listObject.clear();
this._objectPool.release();
}
public static instanceEntity(cls: any) {
let obj: EntityObject = null;
let useObjectPool: boolean = true;
// Logger.log(cls.name);
obj = this._objectPool.pop(cls.name) as EntityObject;
if (obj == null) {
useObjectPool = false;
obj = new cls() as EntityObject;;
// Logger.log("pool not.");
}else{
// Logger.log("pool pop.");
}
obj.instanceInFactory();
this._listObject.add(obj);
return obj;
}
public static releaseEntity(obj: EntityObject) {
if (obj != null) {
obj.releaseInFactory();
}
}
public static logPool(){
Logger.log(this._objectPool);
}
public static clearReleaseObjects() {
for (let i = this._listObject.count - 1; i >= 0; i--) {
if (this._listObject.get(i).isRelease) {
let obj: EntityObject = this._listObject.get(i);
this._listObject.removeAt(i);
//将对象加入对象池
this._objectPool.push(obj);
}
}
}
}
当我们创建对象的时候就可以这么调用:
EntityFactory.init() // 初始化
let pow:PowEntity = EntityFactory.instanceEntity(PowEntity) as PowEntity; // 创建
EntityFactory.releaseEntity(pow); // 回池,删除(内存还占用着)
今天的对象系统就这么多,回头见~