1
\$\begingroup\$

I'm having a problem in my code where the animation from another class does not animate and is stuck in one frame. The image moves across the screen in the right manner though. I know that the problem is somehow related to the UPDATE method of the animation. I have tried every possible solutions in my knowledge to find what causes the error and the solutions I found online were not quite helpful. Any help will be appreciated.

Here's my Code:

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;
        }
    }
\$\endgroup\$
1
\$\begingroup\$

I wrote a Ninja class for you. You can test it cause I don't have GDX on this PC here:

public class Ninja extends Actor {

    private Animation wLeftAnimation, wRightAnimation;
    private static final int  FRAME_COLS_WALK = 3;
    private static final int  FRAME_ROWS_WALK= 2;
    private float stateTime = 0f;



    public enum Direction{
        LEFT,
        RIGHT;
    }

    private Direction currentDirection = Direction.RIGHT;

    public Ninja(){
        Texture walkSheetRight = new Texture("ninjaWalkRight.png");
        Texture walkSheetLeft = new Texture("ninjaWalkLeft.png");


        TextureRegion[][] tmp = TextureRegion.split(walkSheetRight, (int) walkSheetRight.getWidth() / FRAME_COLS_WALK, (int) walkSheetRight.getHeight() / FRAME_ROWS_WALK);
        TextureRegion[] 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];
            }
        }


        tmp = TextureRegion.split(walkSheetLeft, (int) walkSheetRight.getWidth() / FRAME_COLS_WALK, (int) walkSheetRight.getHeight() / FRAME_ROWS_WALK);
        TextureRegion[] walkFramesLeft = new TextureRegion[FRAME_COLS_WALK * FRAME_ROWS_WALK];
        index = 0;
        for (int i = 0; i < FRAME_ROWS_WALK; i++) {
            for (int j = 0; j < FRAME_COLS_WALK; j++) {
                walkFramesLeft[index++] = tmp[i][j];
            }
        }

        wLeftAnimation = new Animation(0.044f,walkFramesLeft);
        wRightAnimation = new Animation(0.044f,walkFramesRight);

        setSize(wLeftAnimation.getKeyFrame(0f).getRegionWidth(), wLeftAnimation.getKeyFrame(0f).getRegionHeight());
        setPosition(0,0);
    }


    public void walkLeft(){
        currentDirection = Direction.LEFT;
        clearActions();
        addAction(Actions.moveBy(-5,0));
    }

    public void moveRight(){
        currentDirection = Direction.RIGHT;
        clearActions();
        addAction(Actions.moveBy(5,0));
    }

    @Override
    public void draw(Batch batch, float parentAlpha) {
        super.draw(batch, parentAlpha);


        final float delta = Gdx.graphics.getDeltaTime();
        this.act(delta);

        stateTime += delta;

        TextureRegion currentFrame;
        switch (currentDirection){
            case LEFT:
                currentFrame = wLeftAnimation.getKeyFrame(stateTime, true);
                break;
            case RIGHT:
                currentFrame = wLeftAnimation.getKeyFrame(stateTime, true);
                break;
            default:
                // if you add more states
                currentFrame = wLeftAnimation.getKeyFrame(stateTime, true);
                break;
        }

        batch.begin();
        batch.draw(currentFrame, getX(),getY(),getWidth(),getHeight());
        batch.end();

    }
}

Now in your screen you can create a Ninja:

Ninja ninja;

in Screen constructor/onCreate() call:

ninja = new Ninja();

add it to the stage:

stage.add(ninja);

in your update() in Screen update and draw your stage like this:

@Override
public void render(float delta) {
    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    if(Gdx.input.isKeyPressed(Input.Keys.LEFT))
            ninja.walkLeft();

    if(Gdx.input.isKeyPressed(Input.Keys.RIGHT))
            ninja.walkRight();

    update(delta);
}

public void update(float deltaTime){
    stage.act(deltaTime);
    stage.draw(); // this will draw the ninja cause he's on the stage!
}

And you can do some magic with his moveRight() and moveLeft() methods that I wrote. Check if they work and remove the whole WalkAnimate class! Post the errors, cause as I said, I wrote this in a notepad.

Tip: Use left and right on keyboard to walk ;)

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Hey man thanks for your help. I made a few corrections but it works :) \$\endgroup\$ – JAlmazan Nov 27 '16 at 6:37
  • \$\begingroup\$ Another problem arises though, the holdStart image does not show after adding ninja to the stage. \$\endgroup\$ – JAlmazan Nov 27 '16 at 6:39
  • \$\begingroup\$ Did you try to change button's size and position after adding ninja and button? Maybe ninja is overlapping the button and hiding it ;C \$\endgroup\$ – Jacob Nov 27 '16 at 8:37
  • \$\begingroup\$ The button's position is at the center while the ninja is at 0,0 and the sizes are in no way overlapping each other. \$\endgroup\$ – JAlmazan Nov 27 '16 at 8:58
  • \$\begingroup\$ After adding ninja to stage, the holdStart button is not shown but when I click on its designated position on the screen the background (levelonebackground) turns to black. \$\endgroup\$ – JAlmazan Nov 27 '16 at 9:03
1
\$\begingroup\$

In LevelOneScreen, make your update method call update on WalkAnimate:

@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);
}

Then, in WalkAnimate, make sure you select the correct keyframe in the update method:

public void update(float delta){
    stateTime += delta;
    currentFrameRight = walkAnimationRight.getKeyFrame(stateTime, true);
    currentFrameLeft = walkAnimationLeft.getKeyFrame(stateTime, true);
}
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Do you mean putting walkAnimate.update(deltaTime) in update method of LevelOneScreen? \$\endgroup\$ – JAlmazan Nov 24 '16 at 7:38
  • \$\begingroup\$ @JAlmazan No, I meant what I typed in the answer. It looks like you reference the currentFrameRight and currentFrameLeft directly from LevelOneScreen so you need to make sure those are being set to the right values, you do that by updating the key frame in the update method. \$\endgroup\$ – bornander Nov 24 '16 at 7:40
  • \$\begingroup\$ Ok I'll test it but I think I've tried that before. \$\endgroup\$ – JAlmazan Nov 24 '16 at 7:41
  • \$\begingroup\$ It's still stuck in one frame even though I commented out walkAnimate.update(deltaTime) in the render method of levelonescreen, I also put the currentframeright and left in update of walkAnimate \$\endgroup\$ – JAlmazan Nov 24 '16 at 7:52
  • \$\begingroup\$ Checking... :D! \$\endgroup\$ – Jacob Nov 24 '16 at 7:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.