【问题标题】:libgdx, How to make my image touchablelibgdx,如何使我的图像可触摸
【发布时间】:2016-06-07 12:31:55
【问题描述】:

我有一个按钮可以在屏幕上随机生成 4 个树图像(我称它们为徽章)。现在我想让这些徽章可以触摸。如果我触摸它,它只会打印出一条消息。目前代码看起来像这样。

public class PlayScreen implements Screen {
    int scWidth, scHeight;
    int playerWidth, playerHeight;

    Stage stage;
    Skin skin;
    BitmapFont font;
    private SpriteBatch batch; // This is in the render.
    ArrayList<Badge> badges;
    Iterator<Badge> badgeIterator;
    int badgeWidth = 160;
    int badgeHeight = 300;


    Game game;
    public PlayScreen(Game game){
        this.game = game;
    }


    // Create a button to randomise tree positions
    TextureAtlas buttonAtlas;
    TextButton.TextButtonStyle buttonStyle;
    TextButton playButton;

    int randomBadgePosition(String choice)
    {
        int min, max, range;
        if (choice == "x") {
            min = scWidth / 2 - scHeight / 2;
            max = scWidth / 2 + scHeight / 2 - badgeWidth;
            range = (max - min) + 1;
            return (int) (Math.random() * range) + min;
        } else{
            min = 0;
            max = scHeight - badgeHeight;
            range = (max - min) + 1;
            return (int)(Math.random() * range) + min;
        }
    }


    @Override
    public void show() {

        batch = new SpriteBatch();
        stage = new Stage();
        scWidth = Gdx.graphics.getWidth();
        scHeight = Gdx.graphics.getHeight();
        font = new BitmapFont();
        font.setColor(Color.BLACK);
        font.getData().setScale(5);

        int numBadges = 4;
        badges = new ArrayList<Badge>();

        for (int i = 0; i < numBadges; i ++){
            badges.add(new Badge(new Vector2(-400, -400),new Vector2(badgeWidth, badgeHeight) ));
        }

        skin = new Skin();
        buttonAtlas = new TextureAtlas("buttons/button1.txt");
        skin.addRegions(buttonAtlas); // You need to do that.
        buttonStyle = new TextButton.TextButtonStyle();
        buttonStyle.up = skin.getDrawable("button");
        buttonStyle.over = skin.getDrawable("buttonpressed"); // over is not necessary for android.
        buttonStyle.down = skin.getDrawable("buttonpressed");
        buttonStyle.font = font;
        playButton = new TextButton("play", buttonStyle);
        playButton.setPosition(50, 20);
        stage.addActor(playButton);


        Gdx.input.setInputProcessor(stage);

        // Input listener for buttons.
        playButton.addListener(new InputListener(){
            @Override
            public boolean touchDown (InputEvent event, float x, float y,
                                      int pointer, int button){
                // Randomise the locations of the badges.
                for (int i = 0; i < badges.size(); i++){
                    badges.get(i).setPosition(new Vector2(randomBadgePosition("x"), randomBadgePosition("y")));
                }
                return true;
            }
        });
    }

    @Override
    public void render(float delta) {

        Gdx.gl.glClearColor(1,1,1,1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        stage.act();
        stage.draw();
        batch.begin();

        badgeIterator = badges.iterator();
        // This is how to change the position of the badge.
        badges.get(1).setPosition(new Vector2(scWidth/2, scHeight/2));
        while(badgeIterator.hasNext()){
            Badge cur = badgeIterator.next();
            cur.draw(batch);
        }

        batch.end();
        player.update(); // Update the bound
    }
}

徽章类是:

public class Badge {

    Vector2 position, size;
    Texture badge;
    Rectangle bounds;

    public Badge(Vector2 position, Vector2 size){
        this.position = position;
        this.size = size;
        bounds = new Rectangle(position.x, position.y, size.x, size.y);
        badge = new Texture(Gdx.files.internal("tree.png"));
    }

    public void update(){
        bounds.set(position.x, position.y, size.x, size.y);
    }

    public void draw(SpriteBatch batch){
        batch.draw(badge, position.x, position.y, size.x, size.y);
    }

    public Vector2 getPosition() {
        return position;
    }

    public void setPosition(Vector2 position) {
        this.position = position;
    }

    public Vector2 getSize() {
        return size;
    }

    public void setSize(Vector2 size) {
        this.size = size;
    }

    public Rectangle getBounds() {
        return bounds;
    }

    public void setBounds(Rectangle bounds) {
        this.bounds = bounds;
    }
}

我想我需要把它们放在舞台上然后添加监听器。虽然我知道 addlistener 部分(就像按钮一样)。我不知道如何以不同的方式修改 Badge 类和构造函数,以便可以将其添加到阶段。请帮忙。

【问题讨论】:

    标签: java android libgdx


    【解决方案1】:

    您正在使用 Scene2D,因此您可以使用 Image 类,而不是在 Badge 类中创建您自己的实现。当然,如果你需要一些 Image 无法提供的功能,你可以扩展它。

    Image 类本身继承自 Actor,您可以将其添加到舞台,也可以向其中添加侦听器,这正是您想要做的。

    如果您只想处理图像上的 clickClickListener 将是最好的 - 如果您需要处理更多事件,您可以添加 EventListener

    示例代码如下所示

        Stage stage;
    
        //...creating stage etc...
    
        Image badge = new Image(new Texture(Gdx.files.internal("tree.png"))); //Remember that you need to dispose Texture like this!
        badge.addListener( new ClickListener() {
            @Override
            public void clicked(InputEvent event, float x, float y) {
                System.out.println("Clicked!");
            }
        });
    
        stage.addActor(badge);
    

    另请注意,您需要将 stage 设置为输入处理器,方法是使用

        Gdx.input.setInputProcessor(stage);
    

    【讨论】:

    • 谢谢。因为我的徽章是4的arraylist。如何打印触摸树的当前位置?
    【解决方案2】:

    还记得previous answer 吗? :-) 这个想法是完全一样的,但不是这个:

    addListener(new DragListener() {
                @Override
                public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
                    return true;
                }
    
                @Override
                public void touchDragged(InputEvent event, float x, float y, int pointer) {
                    moveBy(x - getWidth()/2, y - getHeight()/2);
                }
            });
    

    你添加这个:

    addListener(new ClickListener() {
                @Override
                public void clicked(InputEvent event, float x, float y) {
                   System.out.println("Badge name is: " + ((Badge)event.getRelatedActor()).getName())
                }
            });
    

    【讨论】:

    • 嗨,我的第一个问题是我不能只使用 stage.addActor(badges),因为 badges 是一个 ArrayList。所以我使用了一个 for 循环来单独添加每一个。那样行吗?然后我的第二个问题(与播放器问题相同)是当我触摸屏幕时应用程序启动时它崩溃了。:(
    • 我发现崩溃是因为 System.out.println("Badge name is: " + ((Badge)event.getRelatedActor()).getName());... 所以我认为我将徽章添加到舞台的方式不正确。有没有办法使用 stage.addActor 添加 arrayList?
    • Jiajun,是的,我在您的 Badge 中创建了一个名为 getName() 的方法,该方法返回名称 - 您可以将其替换为您想要的任何内容。例如,如果您想知道单击了 ArrayList 中的哪个项目,请使用 for 循环遍历它,并查看列表中的哪一个与 ((Badge)event.getRelatedActor()) 的唯一属性匹配(如名称 I捏造)。 ((Badge)event.getRelatedActor()) 为您提供被点击的徽章。
    • 嗨 WonderfulWorld。 getName() 是一个合适的方法。它返回 nil 因此崩溃。我认为这是因为我添加演员的方式。我遍历数组列表并按索引单独添加它。也许这就是为什么当我点击徽章时它没有返回索引?
    猜你喜欢
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-10
    • 1970-01-01
    相关资源
    最近更新 更多