目前我正在参加在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。所以我希望你能帮助我:)先谢谢了!
当我这样做时,我的render()方法不再绘制任何舞台内容。我是否还需要设置相机并将其分配给舞台?我用单线stage = new Stage()替换了相机,视点和舞台声明;现在。 – user3464149
以及我检查了javadocs,现在感到困惑。在理论上阶段=新的阶段()应该自动地手持视口和相机设置。然而我的舞台不再被吸引。我确实将一些演员的x和y坐标设置为0,以防我默认情况下出现“奇怪”的观点,但没有出现。但是,如果我在我的Player类的draw方法中放置一个gdx.app.log,它会不断调用。我需要以任何方式修改我的纹理/或坐标以完成此项工作吗? – user3464149
好像我在这里有另一个问题。我尝试使用stage = new Stage(),并将我的Actors的坐标设置为0,0 - 没有任何显示。然后我在每一帧中将x和y坐标增加1,但是没有任何演员在任何时候越过我的屏幕。接下来我尝试的是增加演员边界的大小,甚至重写我的演员的hit()方法来总是返回演员。但是我的InputListener的touchDown仍然没有触发!现在我回到手动设置视口,并确保将界限和演员设置为完全相同的坐标。因此,我仍然需要帮助=/ – user3464149