具有动态对象类型的Haxe Starling对象池

时间:2017-05-27 21:59:01

标签: html5 haxe starling-framework openfl

我是haxe openfl的新手,我曾经用flash和starling开发游戏,我对从flash到openfl haxe的转换感到困惑。

public class StarlingPool
{
public var items:Array;
private var counter:int;

    public function StarlingPool(type:Class, len:int)
    {
        items = new Array();
        counter = len;

        var i:int = len;
        while(--i > -1)
            items[i] = new type();
    }

    public function getSprite():DisplayObject
    {
        if(counter > 0)
            return items[--counter];
        else
            throw new Error("You exhausted the pool!");
    }

    public function returnSprite(s:DisplayObject):void
    {
        items[counter++] = s;
    }

    public function destroy():void
    {
        items = null;
    }
}

这是由Lee Brimelow创建的Starling Pool Class我想知道如何将其转换为Haxe,

我试过 -

 class StarlingPool
{
    public var items:Array<Class>;
    private var counter:Int;

    public function new(type:Class<Dynamic>, len:Int)
    {
        items = new Array<Class<Dynamic>>();
        counter = len;

        var i:Int = len;
        while (--i > -1)
            items[i] = type;
    }

    public function getSprite():Class<Dynamic>
    {
        if (counter > 0)
            return items[--counter];
        else
            throw new Error("You exhausted the pool!");
            return null;
    }

    public function returnSprite(s:Dynamic):Void
    {
        items[counter++] = s;
    }

    public function destroy():Void
    {
        items = null;
    }
}

但是我没有工作,也许我没有正确地施展它? 例如 -

pool = new StarlingPool(Bullet, 100);
var b:Bullet = cast(pool.getSprite()); //or 
var b:Bullet = cast(pool.getSprite(),Bullet)

2 个答案:

答案 0 :(得分:1)

最好不要使用动态,特别是如果你可以创建typed object pool 有关Type Parameters

的更多信息

答案 1 :(得分:1)

这就是我要做的事情,让它以Haxe的方式运作:

  • 使用类型参数创建StarlingPool。然后它是通用的,所以我们也可以将函数名称更改为getItemputItem
  • lenitems是只读的(默认获取访问权限,无设置访问权限。)
  • 不要使用Class数组,但提供一个返回实例的allocator函数。这可能很好,因为您可以在池类之外准备/装饰新的Sprite。这可以在拥有不同的游泳池时使用。
  • 我不会在池为空时抛出错误,而是使用allocator-function返回新实例。这对我来说更有意义。当然,你必须测量池的合适长度才能很好地平衡内存使用量,因此你可以在那里记录警告以进行调试。

这是StarlingPool类:

class StarlingPool<T>
{
    public var items(default, null):Array<T>;
    public var len(default, null):Int;

    private var _allocator:Void->T;

    public function new(len:Int, allocator:Void->T)
    {
        this.len = len;
        _allocator = allocator;

        // create array full of instances using comprehension syntax
        items = [for(i in 0...len) allocator()];
    }

    public function getItem():T
    {
        if (items.length > 0)
            return items.pop();
        else
            // instead of returning null, why not just provide new objects.
            return _allocator();
    }

    public function putItem(item:T):Void
    {
        if(items.length < len)
        {
            items.push(item);
        }
    }

    public function destroy():Void
    {
        _allocator = null;
        items = null;
    }
}

现在这是一个不错的游泳池,你可以像这样使用它:

var pool = new StarlingPool(50, function() return new Sprite());

trace(pool.items.length); // actual items in pool: 50
var item = pool.getItem();
trace(pool.items.length); // actual items in pool: 49
pool.putItem(item); // give item back
trace(pool.items.length); // actual items in pool: 50

$type(item); // type of this item is: Sprite

由于池是通用的,因此您可以使用其他对象创建不同的对象池。 (当然,你不能混合多种类型)

var pool2 = new StarlingPool(50, function() return new OtherObject());

var item2 = pool2.getItem();
$type(item2); // type of this item is: OtherObject

希望这会有所帮助。自己玩吧:https://try.haxe.org/#979E1