Java libgdx,如何使我的图像可触摸

Java libgdx,如何使我的图像可触摸,java,android,libgdx,Java,Android,Libgdx,我有一个按钮,可以在屏幕上随机生成4个树图像(我称它们为徽章)。现在我想让那些徽章可以触摸。如果我触摸它,它只需打印一条信息。目前代码如下所示 public class PlayScreen implements Screen { int scWidth, scHeight; int playerWidth, playerHeight; Stage stage; Skin skin; BitmapFont font; private Sprite

我有一个按钮,可以在屏幕上随机生成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
    }
}
我想我需要把他们放在舞台上,然后加入听众。虽然我知道addlistener部分(就像按钮一样)。我不知道如何修改Badge类,并以不同的方式将其添加到stage中。请帮忙

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

Image
类本身继承了该类,您可以从该类向stage添加内容,也可以向其添加侦听器,这正是您想要做的

如果你只想处理,点击图片将是最好的-如果你需要处理更多的事件,你可以添加

示例代码可能看起来像

    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);
还请注意,您需要使用将
阶段设置为输入处理器

    Gdx.input.setInputProcessor(stage);
您正在使用Scene2D,因此可以使用类,而不是在
Badge
类中创建自己的实现。当然,如果您需要一些图像无法提供的功能,您可以扩展此功能

Image
类本身继承了该类,您可以从该类向stage添加内容,也可以向其添加侦听器,这正是您想要做的

如果你只想处理,点击图片将是最好的-如果你需要处理更多的事件,你可以添加

示例代码可能看起来像

    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);
还请注意,您需要使用将
阶段设置为输入处理器

    Gdx.input.setInputProcessor(stage);
还记得吗?:-)想法完全相同,但不是这样:

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())
            }
        });
还记得吗?:-)想法完全相同,但不是这样:

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())
            }
        });

谢谢因为我的徽章是4的数组列表。如何打印被触摸树的当前位置?谢谢。因为我的徽章是4的数组列表。如何打印被触摸树的当前位置?嗨,我的第一个问题是我不能只是stage.addActor(徽章),因为徽章是一个数组列表。所以我使用了for循环来分别添加每一个。可以吗?然后,我的第二个问题(与播放器问题相同)是当我一触到屏幕应用程序就启动时它崩溃了。:(我发现崩溃是由于System.out.println(“徽章名称是:”+((徽章)event.getRelatedActor()).getName();…所以我认为我将徽章添加到stage的方式不正确。有没有办法使用stage.addActor添加arrayList?Jiajun,是的,我创建了一个名为getName()的方法在返回名称的徽章中-您可以用任何您想要的内容替换它。例如,如果您想知道ArrayList中的哪个项目被单击,请使用For循环对其进行迭代,并查看列表中的哪个项目与((Badge)event.getRelatedActor())的唯一属性(如我创建的名称)匹配。((Badge)event.getRelatedActor())为您提供已单击的徽章。您好WonderfulWorld.getName()是一个正确的方法。它返回nil,因此崩溃。我认为这是因为我添加actor的方式。我循环遍历数组列表,并按索引逐个添加。也许这就是为什么当我单击徽章时,它没有返回索引的原因?嗨,我的第一个问题是,我不能只是stage.addActor(徽章)因为badges是一个ArrayList。所以我使用了一个for循环来分别添加每一个。可以吗?然后我的第二个问题(与播放器问题相同)是当我一触到屏幕应用程序就启动时它崩溃了。:(我发现崩溃是因为System.out.println(“Badge name是:”+((Badge)event.getRelatedActor()).getName());…所以我认为我将徽章添加到stage的方式不正确。有没有办法使用stage.addActor添加arrayList?Jiajun,是的,我创建了一个名为getName()的方法在返回名称的徽章中-您可以用任何您想要的内容替换它。例如,如果您想知道ArrayList中的哪个项目被单击,请使用For循环对其进行迭代,并查看列表中的哪个项目与((Badge)event.getRelatedActor())的唯一属性(如我创建的名称)匹配。((Badge)event.getRelatedActor())给你点击的徽章。嗨WonderfulWorld.getName()是一个合适的方法。它返回nil,因此崩溃。我想这是因为我添加actor的方式。我循环遍历数组列表并按索引逐个添加它。也许这就是为什么当我点击徽章时,它没有返回索引的原因?