0

我已经开始了一个小项目来帮助我在 libGDX 中学习 scene2D 并不断遇到 nullPointerException。我的目标是让玩家通过使用和动作序列来跳跃。我的问题是玩家确实会跳起来,但一旦跌落下来,游戏就会崩溃。我已经包含了我认为导致问题的代码部分。由于我对 libGDX 和 scene2d 还很陌生,因此我不熟悉 setX() setY() 和可能导致问题的 setPosition(x,y) 方法之间的区别。

我还想进一步了解 delta 和 parentAlpha 到底是什么以及如何正确使用它们

我得到的错误

    Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.badlogic.gdx.scenes.scene2d.actions.MoveToAction.begin(MoveToAction.java:26)
at com.badlogic.gdx.scenes.scene2d.actions.TemporalAction.act(TemporalAction.java:48)
at com.badlogic.gdx.scenes.scene2d.actions.SequenceAction.act(SequenceAction.java:65)
at com.badlogic.gdx.scenes.scene2d.Actor.act(Actor.java:85)
at com.chiefpeanut.noodle.Tony.act(Tony.java:48)
at com.badlogic.gdx.scenes.scene2d.Group.act(Group.java:48)
at com.badlogic.gdx.scenes.scene2d.Stage.act(Stage.java:225)
at com.chiefpeanut.noodle.GameScreen.render(GameScreen.java:54)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:207)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)

我的球员班的重要组成部分

public class Tony extends Actor{

public Rectangle bounds;
public float posX;
public float posY;
MoveToAction jumpUp;
MoveToAction jumpDown;
public Tony() {     
    posX = 10f;
    posY = 10f;
        
    bounds = new Rectangle();
    setHeight(100);
    setWidth(100);
    //scale(1, 1);
    setPosition(10, 10);
    
    
    setX(10f);
    setY(10f);
    setPosition(10, 10);
    jumpUp = new MoveToAction();
    jumpUp.setPosition(10, 80);
    jumpUp.setDuration(2f);
    
    jumpDown = new MoveToAction();
    jumpDown.setPosition(10, 10);
    jumpDown.setDuration(2f);
    
}


public void act(float delta){
    super.act(delta);<<--------SHOWS ERROR OCCURRING HERE------
    updateBounds();
    }
public void jump() {
    addAction(Actions.sequence(jumpUp, jumpDown));

}

public void draw(SpriteBatch batch, float parentAlpha){
    batch.draw(Assets.textureTony, getX(), getY(), getWidth(), getHeight());
    
}


}

至于我的 GameScreen 课程的重要部分,我有

public class GameScreen implements Screen, GestureListener {

MyGame game;
OrthographicCamera camera;
static SpriteBatch batch;
Stage stage;
Tony player;
Array<Block> blocks;

public GameScreen(MyGame game) {
    this.game = game;
    camera = new OrthographicCamera();
    camera.setToOrtho(false, 1920, 1080);
    camera.update();
    
    player = new Tony();
    
    batch = new SpriteBatch();
    stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    
    stage.addActor(player);     
    
}

@Override
public void render(float delta) {
    Gdx.gl.glClearColor(1F, 1F, 1F, 1F);
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    batch.setProjectionMatrix(camera.combined);
    
    stage.act(delta);//<<----SHOWS ANOTHER ERROR OCCURRING HERE-------
    stage.draw();
    System.out.println("rendered");
    

    if(Gdx.input.isKeyPressed(Keys.W)){
        player.jump();
    }
    if(Gdx.input.isKeyPressed(Keys.D)){
        //player.testMove();
        System.out.println(player.getX());
    }
    
    
}

@Override
public void resize(int width, int height) {

}

@Override
public void show() {
    Gdx.input.setInputProcessor(new GestureDetector(this));

}

@Override
public void hide() {
    Gdx.input.setInputProcessor(null);

}

}

我开始假设我错误地使用了我的渲染——这可能是正确的,因为我正在学习 5 个不同的教程——但是在单击堆栈跟踪中的 MoveToAction.java:26 错误后,它显示了第 26行文档(在 github 上),错误出现在“startX = actor.getX();”的行上 几天来我一直很困惑并尝试不同的事情,并且迫切希望找出我做错了什么。

非常感谢您的帮助

4

2 回答 2

0

尝试使用池中的 Scene2d 动作。“Actions”类具有创建或重用池中的操作的静态方法。这更具可读性和内存效率。

addAction( Actions.sequence( Actions.moveTo(x1, y1, t1), Actions.moveBy(x2, y2, t2)));

于 2014-03-31T06:12:04.987 回答
0

我不知道确切的错误。为此,您必须使用带断点的调试。错误本身发生在MoveToAction.begin()方法内部,在第 26 行。您必须查看这一行才能知道此时哪个变量为空。一旦你知道它就更容易调试你的代码。
查看代码,您的代码似乎Actor为空。您是否在某处将他设置为空?
无论如何,我建议使用该Actions课程。它为您返回一个合并的操作,并且易于使用。在您的jump()方法中,您可以像这样使用它:

public void jump() {
    this.addAction(Actions.sequenze(Actions.moveTo(10, 80, 2f), Actions.moveTo(10, 10, 2f)));
}

如果jump()方法被调用,例如,如果你正在按下一个键,你应该持有一个布尔值,它表示你是否已经准备好跳跃。

对于你的第二个问题:

  1. float delta是自上次调用方法以来经过的时间,render()以秒为单位。FPS(每秒帧数)是使用alpha:计算的FPS = 1/delta。的act(delta)方法Actor使用它delta来更新位置,旋转......取决于时间。例如,如果 aActor应该每秒移动 10 个单位,则act(delta)表示setX(getX()+10*delta)
  2. float parentAlpha描述了 的值(alpha不透明度)。每个都有一个根组,您将添加到该组中。当然,您也可以将自己的添加到. 如果您希望它是半透明的,请将 设置为 0.5f。然后,其中的所有s 都将其作为draw 方法中的 s 。你可以让你的(在你的情况下是班级)忽略这个阿尔法,但你也可以让他受到这个阿尔法的影响:groupActorstageActorstage.addActor(myActor)GroupstagegroupalphaActorgroupparentAlphaActorClassTony

    public void draw (SpriteBatch batch, float parentAlpha) { Color color = getColor(); // Actors tint color batch.setColor(color.r, color.g, color.b, color.a*parentAlpha); // 画 }

阅读内容:Scene2D wiki 文章

于 2014-03-31T06:32:06.983 回答