一个不甚完美的多功能三维动画的类

Posted on 2013-08-02 22:22  冰天雪域  阅读(222)  评论(0编辑  收藏  举报

在andorid中,使用camera,matrix和动画Animation类,结合activity, view, window 可以创建出令人目眩神迷的场景动画,为锁屏,启动器,动态墙纸提供丰富的视觉效果。下面的动画类可以创建以Y轴为中心旋转,沿X, Y, X三个方向移动的动画,当然沿Y轴移动的动画也能变相的实现VIEW缩小放大功能。几种效果可以同时具有,这时会产生像降落伞或者直升机一样沿垂直和水平方向加旋转缩小的动画效果,也可以做为在重力和水平风力的效果。这个类经过完善,完全可以再添加上沿X,Z轴旋转的效果,再加上侦听效果。不过一个根据个人需要修改吧,大而全的功能,往往意味需要增加更多的CPU运算时间或者内存开销。

 

package com.example.scr;

import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.Transformation;

public class Rotate3dAnimation extends Animation {
	// 开始角度
	private final float mFromDegrees;
	// 结束角度
	private final float mToDegrees;
	// 开始x
	private final float mFromx;
	// 结束x
	private final float mTox;
	// 开始y
	private final float mFromy;
	// 结束y
	private final float mToy;
	// 开始z
	private final float mFromz;
	// 结束z
	private final float mToz;
	// 中心点
	private final float mCenterX;
	private final float mCenterY;
	// 是否需要返回
	private final boolean mReverse;
	// 摄像头
	private Camera mCamera;
	
	private Runnable mExitFunc = null;

	public void setExitFunction(Runnable run) {
		mExitFunc = run;
	}


	public Rotate3dAnimation(float fromDegrees, float toDegrees, 
			float fromx, float tox,float fromy, 
			float toy,float fromz,float toz,float centerX,
			float centerY, boolean reverse) {
		mFromDegrees = fromDegrees;
		mToDegrees = toDegrees;
		mFromx = fromx;
		mTox = tox;
		mFromy = fromy;
		mToy = toy;
		mFromz = fromz;
		mToz = toz;
		mCenterX = centerX;
		mCenterY = centerY;
		mReverse = reverse;
	}

	@Override
	public void initialize(int width, int height, int parentWidth,
			int parentHeight) {
		super.initialize(width, height, parentWidth, parentHeight);
		mCamera = new Camera();
	}

	// 生成Transformation
	@Override
	protected void applyTransformation(float interpolatedTime, Transformation t) {
		final float fromDegrees = mFromDegrees;
		// 生成中间角度
		float degrees = mFromDegrees
				+ ((mToDegrees - mFromDegrees) * interpolatedTime);
		float X = mFromx
				+ ((mTox - mFromx) * interpolatedTime);
		float Y = mFromy
				+ ((mToy - mFromy) * interpolatedTime);
		float Z = mFromz
				+ ((mToz - mFromz) * interpolatedTime);
		final float centerX = mCenterX;
		final float centerY = mCenterY;
		final Camera camera = mCamera;
		final Matrix matrix = t.getMatrix();
		camera.save();
		if (mReverse) {
			camera.translate(X*interpolatedTime, Y* interpolatedTime, Z * interpolatedTime);
		} else {
			camera.translate(X*(1-interpolatedTime), Y* (1-interpolatedTime), Z * (1.0f - interpolatedTime));
		}
		camera.rotateY(degrees);
		// 取得变换后的矩阵
		camera.getMatrix(matrix);
		camera.restore();
		matrix.preTranslate(-centerX, -centerY);
		matrix.postTranslate(centerX, centerY);
	}

	@Override
	public boolean getTransformation(long currentTime,
			Transformation outTransformation) {
		// TODO Auto-generated method stub
		return super.getTransformation(currentTime, outTransformation);
	}
  
}


在使用上也十分简单,这里可以看做是个飞走的飞机。

 

 

private void applyRotation(float start, float end) {
		// 计算中心点
		final float centerX = Ulv.getWidth() / 2.0f;
		final float centerY = Ulv.getHeight() / 2.0f;
		final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, 0,
				1000, 0, 1000, 0, 1000, centerX, centerY, true);
		rotation.setDuration(1000);
		rotation.setFillAfter(true);
		rotation.setInterpolator(new AccelerateInterpolator());
		// 设置监听
		rotation.setAnimationListener(new Animation.AnimationListener() {

			public void onAnimationStart(Animation animation) {
			}

			// 动画结束
			public void onAnimationEnd(Animation animation) {
				if (mExitFunc != null) {
					mExitFunc.run();
				}
			}

			public void onAnimationRepeat(Animation animation) {
			}
		});

		Pmv.startAnimation(rotation);
		Ulv.startAnimation(rotation);
	}


 

 

Copyright © 2024 冰天雪域
Powered by .NET 8.0 on Kubernetes