java - 使用 libgdx 和 scene2d 的触摸事件

标签 java android libgdx scene2d

我目前正在学习一些关于 android 开发和 libgdx/scene2d atm 的教程,但卡在了 touchevents 上:

首先,我正在实现一个棋盘游戏。到目前为止,我已经成功绘制了棋盘和一些 meeples(玩家标记),并将它们的位置调整到正确的坐标。当我开始使用 libgdx 时,我还成功地实现了第一个测试,以查看触摸输入是否正常工作。测试看起来像这样:

if(Gdx.input.isTouched()){
        touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
        camera.unproject(touchPos);
        stone.x=touchPos.x - stone.width/2;
        stone.y=touchPos.y - stone.height/2;

现在我重新安排了我的代码以使用 scene2d,因为有一些非常方便的功能。然而,尽管我遵循了一些相当简单的教程,但似乎我无法设法让 touchevents 与 scene2d 一起使用。由于其中一些引用了 scene2d 最近的一些重大更改,我想知道这些教程是否可能已经过时,希望你们能帮助我解决我的问题:) 我将尝试仅将代码的相关部分粘贴到此处以呈现最小的内容我的非工作代码的示例。 当然,我也很高兴关于如何“改进”我的代码的任何提示,因为我仍在学习,并且可能会在这里打破一些约定 ^^

让我们从我的 Actor 类别开始:

//deleted: imports

public class Player extends Actor{
    private int xval; //x Position of the Player on the board
    private int yval; //y Position of the Player on the board
    private Color color;
    private TextureRegion playerTexture;
    //deleted: some variables that are unimportant for touchevents

    public Player(int x, int y, TextureRegion texture){
        //initializing some Variables with default values
            this.xval = x;
            this.yval = y;
            color = new Color(1,1,1,1);

            playerTexture = texture;
            this.setTouchable(Touchable.enabled); //this should be set by default, but i added it just to be sure.

        //setBounds seems to be necessary in addition to the "touchable" flag to be able to "grab" or "touch" Actors.
        //getX and getY are methods of the actor class which i do not overwrite. I use distinct getters and setters to modify the Variables xval and yval.
            setBounds(getX(), getY(), playerTexture.getRegionWidth(), playerTexture.getRegionHeight()); 

        //now i implement the InputListener. This doesnt seem to get called, since the "touch started" message doesn't appear in LogCat.
        //In Theory the testevent should move the meeple one space to the right. 
        //To do that i call event.getTarget() which returns the actor of which the TouchDown is called. I then cast it to my Actor class (Player) and set xval to xval+1.
            this.addListener(new InputListener(){
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int buttons){
                Gdx.app.log("Example", "touch started at (" + x + ", " + y + ")");
                ((Player)event.getTarget()).setXf(((Player)event.getTarget()).getXf()+1);
                return true;
                }
            });
    }

    //This is my draw method, which just sets the color of my meeple and then draws it to its current position.
    public void draw(Batch batch, float alpha){
        batch.setColor(color);
        batch.draw(playerTexture, getX(), getY());      
    }

    //deleted: several getters and setters
}

所以,如果我没猜错的话,gdx inputProcessor 正在管理所有输入。如果我将 Gdx 输入处理器设置为包含 Actor 的舞台,则在发生事件(例如触摸)时,它将调用舞台上所有 Actor 的输入处理器。因此,由于我刚刚在我的类中添加了一个包含 touchDown 的事件,因此应该在 Actor 实际被触摸的情况下处理 touchDown 事件。用于验证的命中框是由我的 Player 类中的语句“setBounds”设置的。

我在我的 ApplicationListener 类中实现了这个:

//deleted: imports

public class QuoridorApplicationListener implements ApplicationListener{

    Stage stage;
    OrthographicCamera camera;
    //deleted: several variable declarations.       

    //deleted: constructor - this only fills some of my variables with values depending on game settings.

    @Override
    public void create() {
        //set stage - since "stage = new Stage(800,400,false)" doesn't seem to work anymore, i did set up a viewport manually. If you got suggestions how to this straightforward, please leave a note :)
        Gdx.app.log("Tag", "game started");
        camera = new OrthographicCamera();
        camera.setToOrtho(false, 800, 480);
        Viewport viewport = new Viewport() {};
        viewport.setCamera(camera);
        stage = new Stage(viewport);
        Gdx.input.setInputProcessor(stage); //like i described above, this should forward incoming touchevents to the actors on the stage.

        //deleted: setting textures, music, setting up the board (the boardtiles are actors which are added to the stage) 

        //deleted: setting TextureRegion, player colors, player positions and player attributes.
            for (int i = 0; i < playercount; i++){
                stage.addActor(players[i]);
            }
    }

    //deleted: dispose(), pause(), resume(), resize() methods.

    @Override
    public void render() {
        camera.update();

        for (int i=0; i< playercount; i++){
            players[i].setX(/*Formula to determine x-coordinates from Player.xval*/);
            players[i].setY(/*Formula to determine x-coordinates from Player.yval*/);
    } 

    stage.act(Gdx.graphics.getDeltaTime());
    stage.draw();
    }
}

我不知道我缺少什么来让触摸事件正常工作。所以我希望你能帮助我:) 提前非常感谢!

最佳答案

我认为您的问题源于您手动创建的 Viewport 对象,该对象在内部处理取消投影。 而不是

stage = new Stage(800,400,false);

你应该使用

stage = new Stage();

要在发生调整大小事件后将视口(viewport)调整为正确的大小,您需要调用

stage.getViewport().update( newWidth, newHeight )

在您的 ApplicationListener 的调整大小方法中。

关于java - 使用 libgdx 和 scene2d 的触摸事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22663380/

相关文章:

java - 查看MySQL数据库内容

java - 限制 JTextPane 空间使用

android - 我做项目的时候加的。 AndroidX Artifact 从此就没有mqt通信了。问题是什么?

c# - 发现 WiFi Direct 服务 - Windows <=> Android

java - libgdx 上的无限滚动背景

java - Camunda Spring 事务集成不起作用

java - 游戏编程中的类设计

android - 如何将openssl生成的RSA私钥导入AndroidKeyStore

java - LibGDX 绘制圆以某种方式缩放

java - Libgdx:即使在成功构建后,库也不会显示在自动完成中?