首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >libgdx动画精灵无方法错误

libgdx动画精灵无方法错误
EN

Stack Overflow用户
提问于 2017-01-05 00:52:44
回答 0查看 621关注 0票数 2

每当我上传一个用于动画目的的精灵地图集到overlaps2d版本0.1.2-快照的场景中。我的应用程序崩溃,并显示以下代码行(略有修改):

代码语言:javascript
复制
java.lang.NoSuchMethodError: No virtual method getKeyFrame(F)Lcom/badlogic/gdx/graphics/g2d/TextureRegion; in class Lcom/badlogic/gdx/graphics/g2d/Animation; or its super classes (declaration of 'com.badlogic.gdx.graphics.g2d.Animation' appears in /data/data/xxx.xxx.xxx/files/instant-run/dex/slice-gdx-1.9.5_xxx-classes.dex)

它在我的代码中指向下面这一行:

代码语言:javascript
复制
sceneLoader.getEngine().update(Gdx.graphics.getDeltaTime());

这会不会是一个版本不匹配的问题,因为overlap2d已经一年多没有更新了,但libgdx大约一个月前才更新?崩溃只发生在动画图像上,否则应用程序运行正常。我查看了错误所指的libgdx文件,结果如下所示:

代码语言:javascript
复制
package com.badlogic.gdx.graphics.g2d;

import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.utils.Array;

public class Animation<T> {

/** Defines possible playback modes for an {@link Animation}. */
public enum PlayMode {
    NORMAL,
    REVERSED,
    LOOP,
    LOOP_REVERSED,
    LOOP_PINGPONG,
    LOOP_RANDOM,
}

/** Length must not be modified without updating {@link #animationDuration}. See {@link #setKeyFrames(T[])}. */
T[] keyFrames;
private float frameDuration;
private float animationDuration;
private int lastFrameNumber;
private float lastStateTime;

private PlayMode playMode = PlayMode.NORMAL;

/** Constructor, storing the frame duration and key frames.
 * 
 * @param frameDuration the time between frames in seconds.
 * @param keyFrames the objects representing the frames. */
public Animation (float frameDuration, Array<? extends T> keyFrames) {
    this.frameDuration = frameDuration;
    T[] frames = (T[]) new Object[keyFrames.size];
    for (int i = 0, n = keyFrames.size; i < n; i++) {
        frames[i] = keyFrames.get(i);
    }
    setKeyFrames(frames);
}

/** Constructor, storing the frame duration and key frames.
 * 
 * @param frameDuration the time between frames in seconds.
 * @param keyFrames the objects representing the frames. */
public Animation (float frameDuration, Array<? extends T> keyFrames, PlayMode playMode) {
    this(frameDuration, keyFrames);
    setPlayMode(playMode);
}

/** Constructor, storing the frame duration and key frames.
 * 
 * @param frameDuration the time between frames in seconds.
 * @param keyFrames the objects representing the frames. */
public Animation (float frameDuration, T... keyFrames) {
    this.frameDuration = frameDuration;
    setKeyFrames(keyFrames);
}

/** Returns a frame based on the so called state time. This is the amount of seconds an object has spent in the
 * state this Animation instance represents, e.g. running, jumping and so on. The mode specifies whether the animation is
 * looping or not.
 * 
 * @param stateTime the time spent in the state represented by this animation.
 * @param looping whether the animation is looping or not.
 * @return the frame of animation for the given state time. */
public T getKeyFrame (float stateTime, boolean looping) {
    // we set the play mode by overriding the previous mode based on looping
    // parameter value
    PlayMode oldPlayMode = playMode;
    if (looping && (playMode == PlayMode.NORMAL || playMode == PlayMode.REVERSED)) {
        if (playMode == PlayMode.NORMAL)
            playMode = PlayMode.LOOP;
        else
            playMode = PlayMode.LOOP_REVERSED;
    } else if (!looping && !(playMode == PlayMode.NORMAL || playMode == PlayMode.REVERSED)) {
        if (playMode == PlayMode.LOOP_REVERSED)
            playMode = PlayMode.REVERSED;
        else
            playMode = PlayMode.LOOP;
    }

    T frame = getKeyFrame(stateTime);
    playMode = oldPlayMode;
    return frame;
}

/** Returns a frame based on the so called state time. This is the amount of seconds an object has spent in the
 * state this Animation instance represents, e.g. running, jumping and so on using the mode specified by
 * {@link #setPlayMode(PlayMode)} method.
 * 
 * @param stateTime
 * @return the frame of animation for the given state time. */
public T getKeyFrame (float stateTime) {
    int frameNumber = getKeyFrameIndex(stateTime);
    return keyFrames[frameNumber];
}

/** Returns the current frame number.
 * @param stateTime
 * @return current frame number */
public int getKeyFrameIndex (float stateTime) {
    if (keyFrames.length == 1) return 0;

    int frameNumber = (int)(stateTime / frameDuration);
    switch (playMode) {
    case NORMAL:
        frameNumber = Math.min(keyFrames.length - 1, frameNumber);
        break;
    case LOOP:
        frameNumber = frameNumber % keyFrames.length;
        break;
    case LOOP_PINGPONG:
        frameNumber = frameNumber % ((keyFrames.length * 2) - 2);
        if (frameNumber >= keyFrames.length) frameNumber = keyFrames.length - 2 - (frameNumber - keyFrames.length);
        break;
    case LOOP_RANDOM:
        int lastFrameNumber = (int) ((lastStateTime) / frameDuration);
        if (lastFrameNumber != frameNumber) {
            frameNumber = MathUtils.random(keyFrames.length - 1);
        } else {
            frameNumber = this.lastFrameNumber;
        }
        break;
    case REVERSED:
        frameNumber = Math.max(keyFrames.length - frameNumber - 1, 0);
        break;
    case LOOP_REVERSED:
        frameNumber = frameNumber % keyFrames.length;
        frameNumber = keyFrames.length - frameNumber - 1;
        break;
    }

    lastFrameNumber = frameNumber;
    lastStateTime = stateTime;

    return frameNumber;
}

/** Returns the keyframes[] array where all the frames of the animation are stored.
 * @return The keyframes[] field. */
public T[] getKeyFrames () {
    return keyFrames;
}

protected void setKeyFrames (T... keyFrames) {
    this.keyFrames = keyFrames;
    this.animationDuration = keyFrames.length * frameDuration;
}

/** Returns the animation play mode. */
public PlayMode getPlayMode () {
    return playMode;
}

/** Sets the animation play mode.
 * 
 * @param playMode The animation {@link PlayMode} to use. */
public void setPlayMode (PlayMode playMode) {
    this.playMode = playMode;
}

/** Whether the animation would be finished if played without looping (PlayMode#NORMAL), given the state time.
 * @param stateTime
 * @return whether the animation is finished. */
public boolean isAnimationFinished (float stateTime) {
    int frameNumber = (int)(stateTime / frameDuration);
    return keyFrames.length - 1 < frameNumber;
}

/** Sets duration a frame will be displayed.
 * @param frameDuration in seconds */
public void setFrameDuration (float frameDuration) {
    this.frameDuration = frameDuration;
    this.animationDuration = keyFrames.length * frameDuration;
}

/** @return the duration of a frame in seconds */
public float getFrameDuration () {
    return frameDuration;
}

/** @return the duration of the entire animation, number of frames times frame duration, in seconds */
public float getAnimationDuration () {
    return animationDuration;
}

据我所知,获取关键帧是从图像图集中检索帧,并根据时间对其进行更改,以提供运动的错觉。

EN

回答

页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41469214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档