使用 Scene2D 在 Libgdx 中移动精灵(演员?)
Moving a sprite (Actor?) in Libgdx using Scene2D
我一直在尝试学习 scene2d,但在按下某个键时我无法让 sprite/Actor 移动。我尝试了几种不同的方法,但我似乎无法弄清楚。这是我目前拥有的代码,它会在我每次按下按键时移动演员,但在按住按键时不会。
class Player extends Actor {
Sprite sprite = new Sprite(new Texture (Gdx.files.internal("character.png")));
public Player() {
setBounds(sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight());
setTouchable(Touchable.enabled);
addListener( new InputListener() {
@Override
public boolean keyDown(InputEvent event, int keycode) {
if (keycode == Input.Keys.RIGHT) {
MoveByAction mba = new MoveByAction();
mba.setAmount(1f, 0f);
Player.this.addAction(mba);
}
return true;
}
});
}
@Override
protected void positionChanged() {
sprite.setPosition(getX(), getY());
super.positionChanged();
}
@Override
public void draw(Batch batch, float parentAlpha) {
sprite.draw(batch);
}
@Override
public void act(float delta) {
super.act(delta);
}
}
您可以使用状态机制来做到这一点。这可以是一个简单的枚举:
public enum PlayerMoveState {
RIGHT,
LEFT,
IDLE
}
在您的 sprite 类型的 PlayerMoveState 下方定义一个字段,如下所示:
PlayerMoveState moveState;
根据您的 keyDown 方法中的 Input.Keys.RIGHT、Input.Keys.LEFT 将其设置为正确的状态。通过在您需要覆盖和实现的 keyUp 方法中将其设置为 IDLE 来重置状态。
@Override
public boolean keyUp(InputEvent event, int keycode) {
moveState = PlayerMoveState.IDLE;
}
最后,在你播放器的act方法中写一个简单的switch case块。
@Override
public void act(float delta) {
super.act(delta);
switch(moveState) {
case RIGHT :
// Move right by using whatever method you want.
// Directly increasing x
// Increase x according to velocity you have defined.
// Use actions, little bit dangerous.
break;
case LEFT :
// Move left by using whatever method you want.
break;
case IDLE :
// Don't change x coordinate of your player.
break;
default :
break;
}
}
我不太确定 actor 是否专注于自身来处理 KeyUp/Down 事件,这就是为什么我会避免使用侦听器来移动 player。
另外,更改演员的位置不需要操作 - Actorclass 中有一个简单的 setPosition() 方法。您还可以使用 getX() 和 getY() 方法来获取演员的当前位置。
我会做的是检查是否有 Key is down (by using Gdx.input 不是 lisetners) 并设置由某些定义的步骤修改的位置,例如:
//Actor class
final float STEP = 1f;
...
@Override
public void act(float delta) {
super.act(delta);
if(Gdx.input.isKeyPressed(Keys.W))
this.setPosition(getX(), getY() + STEP);
if(Gdx.input.isKeyPressed(Keys.S))
this.setPosition(getX(), getY() - STEP);
if(Gdx.input.isKeyPressed(Keys.A))
this.setPosition(getX() - STEP, getY());
if(Gdx.input.isKeyPressed(Keys.D))
this.setPosition(getX() + STEP, getY());
}
在每个渲染中调用 act() 方法(当然,如果您正在调用舞台的 act),因此移动将是连续的。
我一直在尝试学习 scene2d,但在按下某个键时我无法让 sprite/Actor 移动。我尝试了几种不同的方法,但我似乎无法弄清楚。这是我目前拥有的代码,它会在我每次按下按键时移动演员,但在按住按键时不会。
class Player extends Actor {
Sprite sprite = new Sprite(new Texture (Gdx.files.internal("character.png")));
public Player() {
setBounds(sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight());
setTouchable(Touchable.enabled);
addListener( new InputListener() {
@Override
public boolean keyDown(InputEvent event, int keycode) {
if (keycode == Input.Keys.RIGHT) {
MoveByAction mba = new MoveByAction();
mba.setAmount(1f, 0f);
Player.this.addAction(mba);
}
return true;
}
});
}
@Override
protected void positionChanged() {
sprite.setPosition(getX(), getY());
super.positionChanged();
}
@Override
public void draw(Batch batch, float parentAlpha) {
sprite.draw(batch);
}
@Override
public void act(float delta) {
super.act(delta);
}
}
您可以使用状态机制来做到这一点。这可以是一个简单的枚举:
public enum PlayerMoveState {
RIGHT,
LEFT,
IDLE
}
在您的 sprite 类型的 PlayerMoveState 下方定义一个字段,如下所示:
PlayerMoveState moveState;
根据您的 keyDown 方法中的 Input.Keys.RIGHT、Input.Keys.LEFT 将其设置为正确的状态。通过在您需要覆盖和实现的 keyUp 方法中将其设置为 IDLE 来重置状态。
@Override
public boolean keyUp(InputEvent event, int keycode) {
moveState = PlayerMoveState.IDLE;
}
最后,在你播放器的act方法中写一个简单的switch case块。
@Override
public void act(float delta) {
super.act(delta);
switch(moveState) {
case RIGHT :
// Move right by using whatever method you want.
// Directly increasing x
// Increase x according to velocity you have defined.
// Use actions, little bit dangerous.
break;
case LEFT :
// Move left by using whatever method you want.
break;
case IDLE :
// Don't change x coordinate of your player.
break;
default :
break;
}
}
我不太确定 actor 是否专注于自身来处理 KeyUp/Down 事件,这就是为什么我会避免使用侦听器来移动 player。
另外,更改演员的位置不需要操作 - Actorclass 中有一个简单的 setPosition() 方法。您还可以使用 getX() 和 getY() 方法来获取演员的当前位置。
我会做的是检查是否有 Key is down (by using Gdx.input 不是 lisetners) 并设置由某些定义的步骤修改的位置,例如:
//Actor class
final float STEP = 1f;
...
@Override
public void act(float delta) {
super.act(delta);
if(Gdx.input.isKeyPressed(Keys.W))
this.setPosition(getX(), getY() + STEP);
if(Gdx.input.isKeyPressed(Keys.S))
this.setPosition(getX(), getY() - STEP);
if(Gdx.input.isKeyPressed(Keys.A))
this.setPosition(getX() - STEP, getY());
if(Gdx.input.isKeyPressed(Keys.D))
this.setPosition(getX() + STEP, getY());
}
在每个渲染中调用 act() 方法(当然,如果您正在调用舞台的 act),因此移动将是连续的。