2014-03-26 46 views
0

目前我正在参加在Android开发和libgdx/scene2d ATM一些教程,但被困在touchevents:Touchevents使用libgdx和scene2d

对于初学者来说我实现一个棋盘游戏。到目前为止,我设法绘制了棋盘和一些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,因为一些非常方便的功能。然而,尽管我遵循了一些相当简单的教程,但似乎我无法设法使用touchevent来使用scene2d。由于其中一些引用了最近对scene2d的一些重大更改,我想知道这些教程是否可能已过时,并希望你们能帮我解决我的问题:)我将尝试只粘贴我的代码的相关部分,我的非工作代码的例子。 当然,我也很高兴关于如何“改善”我在常规的代码,因为我仍然在学习和可能打破这里的一些约定^^

让我们开始与我的演员一流的任何提示:

//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 InputProcessor设置为包含actors的阶段,它将在发生事件(例如touchDown)的情况下调用舞台上所有actor的inputProcessors。因此,因为我刚刚添加了一个包含touchDown的类,所以应该在触发了actor的情况下处理touchDown事件。 hitbox验证是由我的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(); 
    } 
} 

我想不出什么我缺少获得工作touchevents。所以我希望你能帮助我:)先谢谢了!

回答

1

我认为你的问题来自你手动创建的一个Viewport对象,它在内部处理unprojecting。 而不是

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

你应该使用

stage = new Stage(); 

要调整视口尺寸正确,一旦resize事件发生时需要调用

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

在ApplicationListener的大小调整方法。

+0

当我这样做时,我的render()方法不再绘制任何舞台内容。我是否还需要设置相机并将其分配给舞台?我用单线stage = new Stage()替换了相机,视点和舞台声明;现在。 – user3464149

+0

以及我检查了javadocs,现在感到困惑。在理论上阶段=新的阶段()应该自动地手持视口和相机设置。然而我的舞台不再被吸引。我确实将一些演员的x和y坐标设置为0,以防我默认情况下出现“奇怪”的观点,但没有出现。但是,如果我在我的Player类的draw方法中放置一个gdx.app.log,它会不断调用。我需要以任何方式修改我的纹理/或坐标以完成此项工作吗? – user3464149

+0

好像我在这里有另一个问题。我尝试使用stage = new Stage(),并将我的Actors的坐标设置为0,0 - 没有任何显示。然后我在每一帧中将x和y坐标增加1,但是没有任何演员在任何时候越过我的屏幕。接下来我尝试的是增加演员边界的大小,甚至重写我的演员的hit()方法来总是返回演员。但是我的InputListener的touchDown仍然没有触发!现在我回到手动设置视口,并确保将界限和演员设置为完全相同的坐标。因此,我仍然需要帮助=/ – user3464149