在切换到另一个之前等待动画完成?

时间:2016-07-26 07:26:45

标签: android animation libgdx

我正在使用keyupkeyDown在我的游戏精灵的不同动画之间切换。在keyDown上,精灵根据正在按下的键切换动画,并在keyUp时,精灵切换回空闲动画。它适用于较小的动画,如步行,但当动画有点长时,一旦我释放键,精灵就会回到空闲动画而不完成上一个动画。我该如何实现?我试着阅读libgdx的动画文档,但方法isAnimationFinished不是我需要的。

package com.mygdx.game;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapRenderer;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;

public class MyGdxGame extends ApplicationAdapter implements InputProcessor {
    private SpriteBatch batch;
    private TextureAtlas textureAtlas;
    private Animation animation;
    private Animation animation2;
    private Animation animation3;
    private Animation currentAnimation;
    private float elapsedTime = 0;
    TiledMap tiledMap;
    OrthographicCamera camera;
    TiledMapRenderer tiledMapRenderer;


    int[] pos = {30,30};
    int acc = 0;
    int acc_cam = 0;

    @Override
    public void create() {
        batch = new SpriteBatch();
        textureAtlas = new TextureAtlas(Gdx.files.internal("Wolverine.txt"));
//        textureAtlas = new TextureAtlas(Gdx.files.internal("spritesheet.atlas"));
//        textureAtlas2 = new TextureAtlas(Gdx.files.internal("spritesheet(copy).atlas"));
//        animation = new Animation(1/7f, textureAtlas.getRegions());
//        animation2 = new Animation(1/7f, textureAtlas2.getRegions());
        animation = new Animation(1/7f, textureAtlas.findRegions("Standing"));
        animation2 = new Animation(1/7f, textureAtlas.findRegions("Walking"));
        animation3 = new Animation(1/15f, textureAtlas.findRegions("Attcak_Stand"));
        currentAnimation = animation;

        camera = new OrthographicCamera();
        camera.setToOrtho(false, 640, 480);


        tiledMap = new TmxMapLoader().load("Tiled_tilesheet2.tmx");
        tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap);


        Gdx.input.setInputProcessor(this);
    }

    @Override
    public void dispose() {
        batch.dispose();
        tiledMap.dispose();
        textureAtlas.dispose();
    }

    @Override
    public void render() {

        pos[0] += acc;
        camera.translate(acc_cam,0);

        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        camera.update();
        tiledMapRenderer.setView(camera);
        tiledMapRenderer.render();
        batch.begin();

        //sprite.draw(batch);
        elapsedTime += Gdx.graphics.getDeltaTime();
        batch.draw(currentAnimation.getKeyFrame(elapsedTime, true), pos[0],pos[1]);
        batch.end();
    }

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

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }

    @Override
    public boolean keyDown(int keycode) {
        if (keycode == Input.Keys.RIGHT) {
            currentAnimation = animation2;
            if(pos[0]>320){acc_cam+=2;}
            else{acc += 2;}

        }
        else if(keycode == Input.Keys.Z){
            currentAnimation = animation3;

        }
        return true;

    }

    @Override
    public boolean keyUp(int keycode) {
        currentAnimation = animation;
        acc_cam=0;
        acc = 0;

        return false;
    }

    @Override
    public boolean keyTyped(char character) {
        return false;
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        return false;
    }

    @Override
    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
        return false;
    }

    @Override
    public boolean touchDragged(int screenX, int screenY, int pointer) {
        return false;
    }

    @Override
    public boolean mouseMoved(int screenX, int screenY) {
        return false;
    }

    @Override
    public boolean scrolled(int amount) {
        return false;
    }
}

1 个答案:

答案 0 :(得分:1)

动画类没有办法在当前动画完成时通知您(如回调)。 isAnimationFinished()确实告诉你动画是否在PlayMode#NORMAL中完成,我相信你的动画被设置为你的构造函数没有指示他们循环。

您的渲染代码始终绘制一个基于键输入设置的动画。这就是为什么任何当前动画突然停止,因为你要告诉它立即切换。

我不知道你对各种动画(长度,何时调用等)的计划是什么。您可能需要重构代码以确定要完成哪些动画以及它与其他动画或键输入策略的关系,等等。一个简单的解决方案可能是拥有一个"下一个动画"您根据某些键输入进行设置,并让您的代码检查当前动画以查看它是否已完成(使用isAnimationeFinished - 您必须每帧都这样做)。如果完成,则将下一个动画交换为当前动画。如果您循环播放动画,则必须将其纳入您的逻辑中。

另一种选择可能是编写自己的回调/侦听器代码,以告诉您动画何时完成。向下滚动(几乎在最后)这篇文章:http://www.rengelbert.com/tutorial.php?id=179

可能还有其他一些选项,但所有这些都取决于您希望如何在动画之间进行转换,只有您知道,因为您的某些动画很短,有些很长,并且它们会根据您的输入进行更改正在你的游戏中创造。