2017-05-27 102 views
1

我對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) 
+0

您將項目定義爲'Array ',然後將其重新定義爲'Array >'? 這對我來說是無稽之談。 –

+0

即使你沒有這樣做,你實際上會返回一個'Class'對象到一個正在被轉換到'Class'實例的對象。在你的池類中的某個地方,你需要實例化該對象,可能通過'Type' stdlib。 –

+0

注意原始代碼中表示'items [i] = new type()'的行。這實際上是實例化該類的一個對象。你不是。 –

回答

1

最好不要給我們Ë動態,特別是如果你可以創建typed object pool 更多有關Type Parameters

+0

好吧,這就是我正在尋找,但現在的代碼似乎工作,'var池:StarlingPool ; pool = new StarlingPool(myClass,15);'現在我必須指定我的類類型2次嗎?我不能做一次嗎? –

1

這是我會做什麼,使其工作的HAXE方式:

  • 做出StarlingPool與類型參數。然後它是通用的,所以也可以將函數名稱更改爲getItemputItem
  • lenitems是隻讀的(默認獲取訪問權限,不設置訪問權限)。
  • 不要使用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

+0

謝謝,我會試試看。 –