繁体   English   中英

libgdx动画精灵没有方法错误

[英]libgdx animated sprite no method error

每当我将用于动画目的的精灵图集上载到overlays2d版本0.1.2-快照中的场景中时。 我的应用程序崩溃并显示以下行(略作编辑):

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)

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

sceneLoader.getEngine().update(Gdx.graphics.getDeltaTime());

这可能是版本不匹配的问题,因为overlap2d一年多没有更新,但是libgdx大约一个月前才更新? 崩溃只会发生在具有动画图像的情况下,否则应用程序可以正常运行。 我查看了错误所指向的libgdx文件,这是它的样子:

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

据我了解,关键帧是从图像集中检索帧并根据时间对其进行更改以产生运动幻觉的功能。

使用libgdx的早期版本,即1.9.4。 在libgdx版本1.9.5中,动画类具有一些更改,该更改不会使用overlay2d快照版本进行更新,因此您遇到了问题。

在根项目的build.gradle中降级版本。 希望它会有所帮助。

谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM