libgdx API之Actor.setZIndex():渲染有序

起初看到Actor.setZIndex(int index)這個方法以爲Actor除了x,y還有個z屬性。其實不然,裏面的實現是:以index爲索引改變actor在root中順序。getIndex是調用Array的indexOf,壓根沒有z成員,stage對其下的actor的渲染沒有什麼z的參與,還是按root中順序。調用這個方法的前提actor之前已經被stage add過了。可以說setIndex不是設置初始化z-order,是改變z-order。渲染順序本質還是root中的順序。

錯誤的setZIndex用法:

backGround.setZIndex(0);
tree.setZIndex(1);
...
stage.addActor(tree);
stage.addActor(backGround);
別以爲tree會在background之上,實際setZIndex沒作用。還是按addActor順序。應該如此:

stage.addActor(tree);
stage.addActor(backGround);
...
backGround.setZIndex(0);
tree.setZIndex(1);
假如覺得這樣不滿足,能像cocos2dx的Node中維護一個z多好,那你大可以寫一個繼承Actor的類,給它加個z屬性。然後在渲染時排一下序。代碼大致如下:

<pre name="code" class="java">public class ActorWithZ extends Actor{
    private int z;
    public void setZ(int z){
        this.z=z;};
    public void getZ(){
        return z;};}

public class ActorComparatorZ implements Comparator < ActorWithZ > {
    @Override
    public int compare(ActorWithZ arg0, ActorWithZ arg1) {
        if (arg0.getZ() < arg1.getZ()) {
            return 1;
        } else if (arg0.getZ() == arg1.getZ()) {
            return 0;
        } else {
            return -1;
        }
    }
}

//遊戲的主邏輯中
public void render(){
    Sort.instance.sort(stage.getRoot().getChildren,new ActorComparatorZ();
    stage.act();
    stage.draw();}
順便提下Sort.instance是線程安全的。大致思想是這樣,也有不同寫法的,假如不想擴展Actor,可以使用Actor的userObject屬性作爲z,userObject不參加Actor原生的任何東西,是給開發者方便使用的一個屬性,剛好用在這種情況。
其實我覺得setZIndex()夠用了,Actor還有toBack(),toFront()方法。都要記得在stage.addActor後調用。也許講得不是很清晰但大家瞅瞅Actor,Stage,Group源碼也就明白。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章