LibGdx----scene2d

scene2d

  scene2d package是一個2D場景圖結構,用來管理場景中的actors組。它能處理用戶輸入,並在相對於父actor的座標系統中進行旋轉和縮放。它還提供一個刷新actors的框架。scene2d.ui package對建立GUI很有用。

Important classes

  Stage類有一個名爲"root"的group(組),可以向其中添加actors。Stage有一個camera和一個SpriteBatch。camera的viewport尺寸與屏幕相同。當需要繪製Stage時,SpriteBatch就作爲參數傳遞給root組。

  Group類派生自Actor類,其實就是一個包含其他actors的Actor。對Group的旋轉和縮放操作同時影響它的chidren。Group負責把繪製操作和用戶輸入分配給合適的children。

  Actor類提供場景結點(node)所需的全部基本函數,包含position, size, scale, rotation, origin, color這些屬性,有一個可選的name,可以在debug模式下顯示整個actor樹形結構。

Stage setup

  Stage類有一個viewport size的屬性,該屬性可以在構造函數裏初始化,但最好還是在程序的resized事件中設置該屬性。構造函數中還有一個名爲"stretch"的參數,如果它爲true,就算Stage的viewportsize和屏幕分辨率不同,stage也會被拉伸到屏幕分辨率。如果爲false,stage的viewportsize中較大的那個維度會放大到和屏幕分辨率一樣。如果在resized事件中把viewport size設置成和屏幕一樣,則stretch值就無關緊要了。

  Stage有一個"act"函數,輸入參數包括兩幀的間隔時間,可以使場景中所有actor都調用各自的act()函數。

private Stage stage;

public void create () {
        stage = new Stage(0, 0, true);
}

public void resize (int width, int height) {
        stage.setViewport(width, height, true);
}

public void render () {
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        stage.act(Gdx.graphics.getDeltaTime());
        stage.draw();
}

public void dispose() {
        stage.dispose();
}

Actor

  請創建Actor的派生類來實現繪製、碰撞檢測、處理用戶輸入等工作。

Drawing

  當Stage::draw()函數被調用時,它會調用root group,然後root再調用它的所有children。要繪製actor,需要實現它的draw函數:

TextureRegion region;

public void draw (SpriteBatch batch, float parentAlpha) {
        batch.setColor(1, 1, 1, parentAlpha);
        batch.draw(region, x, y, width, height);
}
  actor::draw函數裏收到的SpriteBatch已經被轉換過了,所以actor的position, size, rotation, scale屬性都是相對於父group的左下角的。這使繪製操作變得很簡單。在上面的代碼中,x,y,width,height都是Actor類的public屬性。

  如果actor的visible屬性被設置爲false,Group就不會調用該actor的draw()函數。

  draw()函數裏的parentAlpha參數是該actor的parent的alpha值。如果draw函數使用了透明度,那麼整個group和它的所有children都會變得透明。

  SpriteBatch::begin()在actor::draw()函數被調用前就已經調用過了。如果一個actor需要用其他方式來繪製,比如使用ShapeRenderer,好麼batch應該先end()並在繪製結束後再begin()。當然,這樣會使得batch被重置,所以應該謹慎使用,具體使用方法如下:

private ShapeRenderer renderer;

public void draw (SpriteBatch batch, float parentAlpha) {
        batch.end();

        renderer.setProjectionMatrix(batch.getProjectionMatrix());
        renderer.setTransformMatrix(batch.getTransformMatrix());
        renderer.translate(x, y, 0);

        renderer.begin(ShapeType.Rectangle);
        renderer.rect(0, 0, width, height);
        renderer.end();

        batch.begin();
}

Hit detection

  當Stage::hit()被調用時,它會調用root group,然後root再調用所有children。第一個返回非null值的actor將被stage返回。要進行碰撞檢測,需要實現下面的函數:

public Actor hit (float x, float y) {
        return x > 0 && x < width && y > 0 && y < height ? this : null;
}
  函數中用到的座標都是actor的局部座標系的。

Input handling

  要想觸發手機屏幕的用戶輸入,需要實現touchDown, touchDragged, touchUp函數。

public boolean touchDown (float x, float y, int pointer) {
        return true;
}

public void touchDragged (float x, float y, int pointer) {
}

public void touchUp (float x, float y, int pointer) {
}
  當stage::touchDown被觸發時,它調用root group。root group會先調用所有children的hit()函數,然後由第一個被hit()函數返回的actor調用touchDown函數。如果touchDown返回false,表示該actor忽略touch down事件,所以group會繼續調用hit(),並由被hit到的actor調用touchDown。如果touchDown()返回true,則該actor成爲group的focused actor(焦點),這意味着該actor可以接收到touchDragged和touchUp事件,即使它們並沒有在該actor上發生(它們會接收到事件,但如果不在它們身上發生,就可以選擇忽略)。如果touchUp被調用(一旦touchDown已經觸發,touchUp就一定會觸發),該actor就失去焦點。

  如果actor的touchable屬性設置爲false,則Group不會觸發它的touch事件。

Actions

  當前的action系統馬上就會進行重構,到時候再寫。


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