LibGDX舞台和演员,事件和演员属性



我刚开始使用LibGdx框架开发android游戏。到目前为止,我读了很多在线教程,读得越多,我就越困惑:ApplicationListener, ApplicationAdapter, stage, Game, screen, Actors, Sprites, Images……更不用说所有的输入和手势监听器)。

我终于明白我应该为我心中的游戏(一种益智游戏)使用什么样的"模型":游戏,屏幕,舞台和演员。

这是我的第一个代码

这是主要的应用程序(游戏):

package com.my.game1;
import com.badlogic.gdx.Game;
public class MyGame extends Game {
    @Override
    public void create () {
        setScreen(new StarterScreen());
    } 
}

这是主屏幕类:

package com.my.game1;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.scenes.scene2d.Stage;
public class StarterScreen implements Screen {
    private Stage stage;
    private float screenW, screenH;
    private Tess tessera;
    @Override
    public void show() {
        tessera = new Tess("image.png");
        stage = new Stage();
        screenW = stage.getViewport().getWorldWidth();
        screenH = stage.getViewport().getWorldHeight();
        Gdx.input.setInputProcessor(stage);
        stage.addActor(tessera);
    }
    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0,0,0,1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        stage.act();
        stage.draw();
    }
    @Override
    public void resize(int width, int height) {
        // TODO Auto-generated method stub
    }
    @Override
    public void pause() {
        // TODO Auto-generated method stub
    }
    @Override
    public void resume() {
        // TODO Auto-generated method stub
    }
    @Override
    public void hide() {
        dispose();
    }
    @Override
    public void dispose() {
        stage.dispose();
    }  
}

下面是扩展了Actor的类:

package com.my.game1;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.utils.ActorGestureListener;
public class Tess extends Actor {
    private Texture texture;
    private boolean selected = false;
    public Tess (String img) {
        this.texture = new Texture(Gdx.files.internal(img));
        this.setBounds(0f, 0f, this.texture.getWidth(), this.texture.getHeight());
        this.setOrigin(this.texture.getWidth() / 2, this.texture.getHeight() / 2);
        this.setScale(0.25f);
        this.addListener(new ActorGestureListener() {
            public void tap(InputEvent event, float x, float y, int pointer, int button) {
                ((Tess)event.getTarget()).toggleSelect();
                ((Tess)event.getTarget()).setColor(0.5f, 0f, 0.5f, 1f);
            }
        });
    }
    @Override
    public void draw(Batch batch, float alpha){
        batch.draw(texture, 0, 0);
    }
    public void finalize() {
        this.texture.dispose();
    }
    public void toggleSelect(){
        this.selected = !this.selected;
        if (this.selected == true)
            this.setColor(0.5f, 0f, 0.5f, 1f);
        else
            this.setColor(0f, 0f, 0f, 0f);          
    }
}

屏幕正确显示了actor,但我无法设置actor的位置或比例,也无法检测到"tap"事件;颜色不变

我做错了什么?

有几个地方出了问题。首先,在另一方面,您不希望从Screen的hide()方法调用dispose()hide()可以简单地在屏幕关闭时调用,或者当应用程序切换到后台时,在此期间处理Screen会导致严重的问题。

有了这些,你的Actor应该是这样的:

package com.my.game1;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.Touchable;
public class Tess extends Actor {
    private Sprite sprite;
    private boolean selected = false;
    public Tess (String img) {
        this.sprite = new Sprite(new Texture(Gdx.files.internal(img)));
        this.setTouchable(Touchable.enabled);
        this.setBounds(this.sprite.getX(), this.sprite.getY(), this.sprite.getWidth(), this.sprite.getHeight());
        this.setOrigin(this.sprite.getWidth() / 2, this.sprite.getHeight() / 2);
        this.setScale(0.25f);
        this.addListener(new ActorGestureListener() {
            @Override
            public void tap (InputEvent event, float x, float y, int pointer, int button) {
                ((Tess)event.getTarget()).toggleSelect();
            }
        });
    }
    @Override
    public void draw(Batch batch, float alpha){
        sprite.draw(batch);
    }
    @Override
    public void positionChanged(){
        sprite.setPosition(getX(), getY());
    }
    public void toggleSelect(){
        this.selected = !this.selected;
        if (this.selected == true)
            sprite.setColor(0.5f, 0f, 0.5f, 1f);
        else
            sprite.setColor(0f, 0f, 0f, 0f);          
    }
}

第一件事改变了:你应该使用Sprite,而不是Texture,来轻松处理颜色,绘图和转换。Texture是可能的,但不像Sprite那样直接。

接下来,您需要在actor内部调用setTouchable(Touchable.enabled)来实际启用命中检测。如果没有这个,没有触摸事件传递给Actor

之后,对于setBounds(),您需要使用sprite.getX()sprite.getY(),以利用Sprite的位置值。将它们设置为任意数字似乎会禁用该Actor的任何触摸容量。

另一件事,如果所有这些都是OK的,就是你为每个触摸设置了两次颜色,一次是基于selected字段,然后直接设置为深紫色,所以我删除了第二组,只使用了你的toggle方法。

接下来,由于我们现在有了Sprite,我们可以使用draw()方法附加到Sprite本身并将Batch提供给它,而不是调用Batch的draw。

最后,当您想要更改图像的位置时,调用actor本身的setPosition,并利用positionChanged()方法的重写来根据Actor的新位置设置Sprite的位置。

最新更新