图像没有动画并且卡在一帧中

Image Does Not Animate and is Stuck in one Frame

我的代码有问题,来自另一个 class 的动画没有动画并且卡在一帧中。图像以正确的方式在屏幕上移动。我知道这个问题在某种程度上与动画的 UPDATE 方法有关。我已经尝试了我所知的所有可能的解决方案来找出导致错误的原因,而我在网上找到的解决方案并不是很有帮助。任何帮助将不胜感激。

这是我的代码:

LevelOneScreen.java

public class LevelOneScreen implements Screen {

    private final MyGame app;
    WalkAnimate walkAnimate;
    private Stage stage;
    private Image levelOneImage;
    private Image holdStartImage;
    public Image walkRightImage;
    public Image walkLeftImage;
    public float deltaTime = Gdx.graphics.getDeltaTime();




    public LevelOneScreen(final ThumbChase app){
        this.app = app;
        this.stage = new Stage(new StretchViewport(app.screenWidth,app.screenHeight , app.camera));

    }
    @Override
    public void show() {

        Gdx.input.setInputProcessor(stage);
        walkAnimate = new WalkAnimate();
        walkAnimate.update(deltaTime);


        levelOneBackground();
        holdStart();
        ninjaWalk();


    }



    public void holdStart(){
        Texture holdStartTexture = new Texture("HoldStart.png");
        holdStartImage = new Image(holdStartTexture);
        float holdStartImageW = holdStartImage.getWidth();
        float holdStartImageH = holdStartImage.getHeight();
        float holdStartImgWidth = app.screenWidth*0.8f;
        float holdStartImgHeight = holdStartImgWidth *(holdStartImageH/holdStartImageW);
        holdStartImage.isTouchable();
        holdStartImage.setSize(holdStartImgWidth,holdStartImgHeight);
        holdStartImage.setPosition(stage.getWidth()/2-holdStartImgWidth/2,stage.getHeight()/2-holdStartImgHeight/2);
        stage.addActor(holdStartImage);
        holdStartImage.addListener(new ActorGestureListener(){
           /* public void touchDown (InputEvent event, float x, float y, int pointer, int button){
                holdStartImage.setVisible(false);
            };*/
           public void fling(InputEvent event, float velocityX, float velocityY, int button)  {
               holdStartImage.setVisible(false);
           }
            public void touchDown (InputEvent event, float x, float y, int pointer, int button){
                holdStartImage.setVisible(false);
            };
            public void touchDrag (InputEvent event, float x, float y, int pointer, int button){
                holdStartImage.setVisible(false);
            };

        });


        }


    public void levelOneBackground(){
        Texture levelOneTexture = new Texture("BGBlue Resize.png");
        levelOneImage = new Image(levelOneTexture);
        levelOneImage.setSize(app.screenWidth,app.screenHeight);
        levelOneImage.setPosition(0,0);
        stage.addActor(levelOneImage);
        /*levelOneImage.addListener(new ActorGestureListener(){
            public void touchDown (InputEvent event, float x, float y, int pointer, int button){
                holdStartImage.setVisible(false);
            };
        });*/
    }
    public void ninjaWalk(){
        TextureRegion ninjaWalkRight = new TextureRegion(walkAnimate.getCurrentFrameRight());
        TextureRegion ninjaWalkLeft = new TextureRegion(walkAnimate.getCurrentFrameLeft());
        //Texture ninjaWalkRight = new Texture("badlogic.jpg");
        //Texture ninjaWalkLeft = new Texture("badlogic.jpg");
        walkRightImage = new Image(ninjaWalkRight);
        walkLeftImage = new Image(ninjaWalkLeft);
        float walkImageW = walkRightImage.getWidth();
        float walkImageH = walkRightImage.getHeight();
        float walkImageWidth = app.screenWidth*0.25f;
        float walkImageHeight = walkImageWidth*(walkImageH/walkImageW);
        walkRightImage.isTouchable();
        walkLeftImage.isTouchable();
        walkRightImage.setSize(walkImageWidth,walkImageHeight);
        walkLeftImage.setSize(walkImageWidth,walkImageHeight);
        walkRightImage.setPosition(stage.getWidth()/2-walkImageWidth/2,0);
        walkLeftImage.setPosition(stage.getWidth()/2-walkImageWidth/2,0);
        walkRightImage.addAction(moveBy(app.screenWidth*0.2f,0,1f));
        stage.addActor(walkRightImage);
        walkRightImage.addListener(new ActorGestureListener(){
            public void pan(InputEvent event, float x, float y, float deltaX, float deltaY) {
                holdStartImage.setVisible(true);
            }
        });


    }

    @Override
    public void render(float delta) {

        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        //walkAnimate.update(deltaTime);
        update(delta);
    }

    public void update(float deltaTime){
        stage.act(deltaTime);

        stage.draw();
        app.batch.begin();

        app.batch.end();
    }

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

    }

    @Override
    public void pause() {

    }

    @Override
    public void resume() {

    }

    @Override
    public void hide() {

    }

    @Override
    public void dispose() {
        stage.dispose();

    }
}

WalkAnimate.java

public class WalkAnimate {

        public MyGame app;
        public Stage stage;


        private Animation walkAnimationRight;
        private Animation walkAnimationLeft;
        private Texture walkSheetRight;
        private Texture walkSheetLeft;
        private TextureRegion[] walkFramesRight;
        private TextureRegion[] walkFramesLeft;
        private TextureRegion   currentFrameRight;
        private TextureRegion   currentFrameLeft;
        private float stateTime;
        private Rectangle bound; //used for positioning and collision detection
        private static final int  FRAME_COLS_WALK = 3;
        private static final int  FRAME_ROWS_WALK= 2;
        private float screenWidth = Gdx.graphics.getWidth();
        private float screenHeight = Gdx.graphics.getHeight();
        public float currentFrameWidth = (float)(screenHeight*0.15);
        public float currentFrameHeight = (float)(screenHeight*0.15);
        public float walkSheetWidth;
        public float walkSheetHeight;



        public WalkAnimate () {

            walkSheetRight = new Texture("ninjaWalkRight.png");
            walkSheetWidth = walkSheetRight.getWidth();
            walkSheetHeight = walkSheetRight.getWidth();
            TextureRegion[][] tmp = TextureRegion.split(walkSheetRight, (int) walkSheetRight.getWidth() / FRAME_COLS_WALK, (int) walkSheetRight.getHeight() / FRAME_ROWS_WALK);
            walkFramesRight = new TextureRegion[FRAME_COLS_WALK * FRAME_ROWS_WALK];
            int index = 0 ;
            for (int i = 0; i < FRAME_ROWS_WALK; i++) {
                for (int j = 0; j < FRAME_COLS_WALK; j++) {
                    walkFramesRight[index++] = tmp[i][j];
                }
            }
            walkAnimationRight = new Animation(0.044f, walkFramesRight);
            stateTime = 0f;


            walkSheetLeft = new Texture("ninjaWalkLeft.png");
            walkSheetWidth = walkSheetLeft.getWidth();
            walkSheetHeight = walkSheetLeft.getWidth();
            TextureRegion[][] tmp1 = TextureRegion.split(walkSheetLeft, (int) walkSheetRight.getWidth() / FRAME_COLS_WALK, (int)walkSheetLeft.getHeight() / FRAME_ROWS_WALK);
            walkFramesLeft = new TextureRegion[FRAME_COLS_WALK * FRAME_ROWS_WALK];
            int index1 = 0;
            for (int i = 0; i < FRAME_ROWS_WALK; i++) {
                for (int j = 0; j < FRAME_COLS_WALK; j++) {
                    walkFramesLeft[index1++] = tmp1 [i][j];
                }
            }
            walkAnimationLeft = new Animation(0.044f, walkFramesLeft);
            stateTime = 0f;

            currentFrameRight = walkAnimationRight.getKeyFrame(stateTime, true);
            currentFrameLeft = walkAnimationLeft.getKeyFrame(stateTime, true);




        }


        public Rectangle getBound(){
            return bound;
        }

        public void update(float delta){
            stateTime += delta;



        }


        public TextureRegion getCurrentFrameRight(){
            return currentFrameRight;

        }
        public TextureRegion getCurrentFrameLeft(){
            return currentFrameLeft;
        }
    }

就像 Eames 之前的评论一样。只需看一眼您的代码,我就可以说您应该先移动

walkAnimate.update(delta);

到渲染部分。 show 部分只运行一次(当 class 启动时)。你的 walkAnimate.update(delta) 应该 运行 不断地改变框架。否则只会更新一次。

你也可以按照我的方法做。

class 您要使用它的地方。 16代表图像的数量。 1F 表示它在一秒钟内完成。

public void show() {
        texture = new Texture("item/coin_animation.png");
        animation = new Animation(new TextureRegion(texture), 16, 1f);
}


public void render(float delta) {
        animation.update(delta);
}

动画Class

public Array<TextureRegion> frames;
private float maxFrameTime;
private float currentFrameTime;
private int frameCount;
private int frame;
private static TextureRegion textureRegion;

public Animation(TextureRegion region, int frameCount, float cycleTime){

    textureRegion = region;

    frames = new Array<TextureRegion>();
    int frameWidth = textureRegion.getRegionWidth() / frameCount;

    for (int i = 0; i < frameCount; i++){
        frames.add(new TextureRegion(textureRegion, i * frameWidth, 0, frameWidth, textureRegion.getRegionHeight()));
    }


    this.frameCount = frameCount;
    maxFrameTime = cycleTime / frameCount;
    frame = 0;
}


public void update(float delta){
    currentFrameTime += delta;
    if (currentFrameTime > maxFrameTime){
        frame++;
        currentFrameTime = 0;
    }

    if (frame >= frameCount)
        frame = 0;
}


public TextureRegion getFrame(){
    return  frames.get(frame);
}

public void restart(){
    frame = 0;
    currentFrameTime = 0;
}

我会回答我的问题,我试过为动画使用一个单独的舞台并且它有效。我还使用 inputmultiplexor 将两个阶段都设置为输入处理器。我知道这不是最好的解决方案,我愿意寻求更合适的解决方案。这是开放编辑。