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系统马上就会进行重构,到时候再写。


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值