Haxe Starling对象池与动态对象类型
我对haxe openfl非常陌生,我曾经用flash和starling开发游戏,我对从flash转换为openfl haxe感到困惑。Haxe Starling对象池与动态对象类型
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;
}
}
下面是李布赖姆洛创建八哥池类我不知道我怎样才能将其转换为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)
最好不要给我们Ë动态,特别是如果你可以创建typed object pool 更多有关Type Parameters
好吧,这就是我正在寻找,但现在的代码似乎工作,'var池:StarlingPool
这是我会做什么,使其工作的HAXE方式:
- 做出StarlingPool与类型参数。然后它是通用的,所以也可以将函数名称更改为
getItem
和putItem
。 -
len
和items
是只读的(默认获取访问权限,不设置访问权限)。 - 不要使用Class数组,但会提供一个分配器函数,该函数将返回一个实例。这可以很好,因为您可以在池类之外准备/装饰新的Sprite。当拥有不同的池时,这可能非常方便。
- 而不是在池为空时抛出错误,而是使用allocator函数返回新实例。这对我来说更有意义。当然,你必须衡量一个体面的长度池,以使内存使用的良好平衡,所以你可以在那里记录一个警告,用于调试目的。
这里是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
谢谢,我会试试看。 –
您将项目定义为'Array',然后将其重新定义为'Array >'? 这对我来说是无稽之谈。 –
即使你没有这样做,你实际上会返回一个'Class'对象到一个正在被转换到'Class'实例的对象。在你的池类中的某个地方,你需要实例化该对象,可能通过'Type' stdlib。 –
注意原始代码中表示'items [i] = new type()'的行。这实际上是实例化该类的一个对象。你不是。 –