如何在Android中实现动画

时间:2011-06-26 10:34:34

标签: android

我有一个小问题。如果我想让一个男人在Android中运行一种方法,这样做是为了获得不同位置的男人的图像并将它们显示在不同的位置。但是,这通常不能很好地工作并且看起来正在绘制两个不同的图像。我还有其他任何方式可以实现自定义动画。(比如创建一个自定义图像并告诉其中一个部分要移动)。

2 个答案:

答案 0 :(得分:2)

我这样做的方法是使用精灵表格(不是我的图形!):

enter image description here

然后您可以使用这样的类来处理动画:

public class AnimSpriteClass {

private Bitmap mAnimation;
private int mXPos;
private int mYPos;
private Rect mSRectangle;
private int mFPS;
private int mNoOfFrames;
private int mCurrentFrame;
private long mFrameTimer;
private int mSpriteHeight;
private int mSpriteWidth;

public AnimSpriteClass() {
    mSRectangle = new Rect(0,0,0,0);
    mFrameTimer =0;
    mCurrentFrame =0;
    mXPos = 80;
    mYPos = 200;
}

public void Initalise(Bitmap theBitmap, int Height, int Width, int theFPS, int theFrameCount) {
    mAnimation = theBitmap;
    mSpriteHeight = Height;
    mSpriteWidth = Width;
    mSRectangle.top = 0;
    mSRectangle.bottom = mSpriteHeight;
    mSRectangle.left = 0;
    mSRectangle.right = mSpriteWidth;
    mFPS = 1000 /theFPS;
    mNoOfFrames = theFrameCount;
}
public void Update(long GameTime) {
    if(GameTime > mFrameTimer + mFPS ) {
        mFrameTimer = GameTime;
        mCurrentFrame +=1;

        if(mCurrentFrame >= mNoOfFrames) {
            mCurrentFrame = 0;
        }
    }

    mSRectangle.left = mCurrentFrame * mSpriteWidth;
    mSRectangle.right = mSRectangle.left + mSpriteWidth;
}

public void draw(Canvas canvas) {
    Rect dest = new Rect(getXPos(), getYPos(), getXPos() + mSpriteWidth,
                getYPos() + mSpriteHeight);

    canvas.drawBitmap(mAnimation, mSRectangle, dest, null);
}
  • mAnimation - 这将保存包含动画的实际位图。
  • mXPos / mYPos - 它们保存X和Y屏幕坐标,以便我们想要精灵在屏幕上的位置。这些是指图像的左上角。
  • mSRectangle - 这是源矩形变量,控制我们为每个帧渲染的图像部分。
  • mFPS - 这是我们希望每秒显示的帧数。 15-20 FPS足以愚弄人眼认为静止图像正在移动。然而,在移动平台上,你不太可能拥有足够的内存3 - 10 FPS,这对大多数需求都很好。
  • mNoOfFrames - 这只是我们动画的精灵表中的帧数。
  • mCurrentFrame - 我们需要跟踪我们正在渲染的当前帧,以便我们按顺序移动到下一帧.~
  • mFrameTimer - 它控制帧之间的时间。
  • mSpriteHeight / mSpriteWidth - 这些包含单个帧的高度和宽度,而不是整个位图,用于计算源矩形的大小。

现在,为了使用这个类,你必须在图形线程中添加一些东西。首先声明一个类的新变量,然后可以在构造函数中初始化它,如下所示。

Animation = new OurAnimatedSpriteClass();
Animation.Initalise(Bitmap.decodeResource(res, R.drawable.stick_man), 62, 39, 20, 20);

为了传递位图的值,首先必须使用Bitmap Factory类来解码资源。它从资源文件夹中解码位图,并允许将其作为变量传递。其余值取决于您的位图图像。

为了能够正确计时帧,首先需要在游戏代码中添加游戏计时器。您可以通过首先添加一个变量来存储时间,如下所示。

private long mTimer;

我们现在需要使用每帧的正确时间更新此计时器,因此我们需要在run函数中添加一行来执行此操作。

public void run() {
    while (mRun) {
        Canvas c = null;
        mTimer = System.currentTimeMillis(); /////This line updates timer
        try {
            c = mSurfaceHolder.lockCanvas(null);
            synchronized (mSurfaceHolder) {
                Animation.update(mTimer);
                doDraw(c);
            }....

然后你只需要添加Animation.draw(canvas);你的Draw功能,动画就会在正确的位置绘制当前帧。

答案 1 :(得分:0)

当你描述:“这样做的一种方法是将人物的图像放在不同的位置并将它们显示在不同的位置”,这确实不仅仅是一种渲染动画的编程技术,而是一种应用于各种形式的动画:它适用于制作电影,制作漫画,电脑游戏等等。

我们的眼睛看到每秒24幅图像的频率。每秒超过12帧,你的大脑会感受到真实,流畅的动作。

所以,是的,这就是方法,如果你感觉运动不是真的,那么你必须提高帧速率。但这很有效。

仅移动图像的一部分不适合表示人跑的小精灵。然而,请记住这个想法以便以后,当您对动画编程更加轻松时,您将看到这适用于不是每帧完全绘制的更大区域,以便减少“制作”所需的计算次数。一个框架”。整个屏幕的某些部分不是每次都“重新计算”,这种技术称为双缓冲,你很快就会在制作游戏时介绍它。

但是现在,你应该首先让你的男人跑步,迅速取代另一张照片。如果移动不是fuild,请提高帧速率(优化程序)或选择彼此更接近的图像。

此致  斯特凡