簡體   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