libGDX MoveToAction nullPointerException

Я начал небольшой проект, чтобы помочь мне изучить scene2D в libGDX и продолжать сталкиваться с 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 = acter.getX(); Я был очень сбит с толку и пробовал разные вещи в течение нескольких дней, и я отчаянно пытаюсь понять, что я делаю неправильно.

Большое спасибо за Вашу помощь


person Chief Peanut    schedule 31.03.2014    source источник
comment
РЕДАКТИРОВАТЬ: Это ДЕЙСТВИТЕЛЬНО показывает, что персонаж прыгает, но как только он возвращается вниз, игра вылетает.   -  person Chief Peanut    schedule 31.03.2014


Ответы (2)


Я не знаю точную ошибку. Для этого вы должны использовать отладку с точками останова. Сама ошибка возникает внутри метода MoveToAction.begin() в строке 26. Вы должны посмотреть на эту строку, чтобы узнать, какая переменная имеет значение null в данный момент. Как только вы это узнаете, ваш код станет легче отлаживать.
Глядя на код, он видит, что ваш Actor равен нулю. Вы где-то устанавливаете для него значение null?
В любом случае, я бы предложил использовать класс 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 для обновления положения, поворота... в зависимости от времени. ЕСЛИ, например, Actor должен двигаться со скоростью 10 единиц в секунду, act(delta) говорит setX(getX()+10*delta).
  2. float parentAlpha описывает значение alpha (непрозрачность) group, в котором находится Actor. У каждого stage есть корневая группа, к которой ваш Actor добавляется stage.addActor(myActor). Конечно, вы также можете добавить свои собственные Group к stage. Если вы хотите, чтобы group был наполовину прозрачным, установите alpha на 0,5f. Все Actor в этом group получат это как parentAlpha в своем методе отрисовки. Вы можете позволить своему ActorClass (в вашем случае классу Tony) игнорировать эту альфу, но вы также можете позволить этой альфе влиять на него:

    public void draw (пакет SpriteBatch, float parentAlpha) { Color color = getColor(); // Актеры окрашивают цвет batch.setColor(color.r, color.g, color.b, color.a*parentAlpha); // рисовать }

Что почитать: вики-статья о Scene2D

person Springrbua    schedule 31.03.2014
comment
Это мучило меня уже около 4 дней, и вы исправили это. Это было то, что я должен был добавить это, чтобы заставить его работать. Спасибо большое - person Chief Peanut; 31.03.2014
comment
Я рад, что смог помочь (: - person Springrbua; 01.04.2014

Попробуйте использовать действия Scene2d из пула. Класс «Действия» имеет статические методы, которые создают или повторно используют действия из пула. Это более читабельно и более эффективно для памяти.

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

person ilkinulas    schedule 31.03.2014