java跳跳球代码,《Android卡通片高手成长记》跳跳球效果

阅读: 评论:0

java跳跳球代码,《Android卡通片高手成长记》跳跳球效果

java跳跳球代码,《Android卡通片高手成长记》跳跳球效果

在介绍本文动画效果实现之前,先来介绍属性动画相关的几个知识点。

ValueAnimator与ObjectAnimator。

Interpolator插值器与TypeEvaluator估值器。

在Android3.0之前,系统提供了两种动画效果实现方式,帧动画frame-by-frame animation和补间动画tweened animation。帧动画就是类似电影播放一样,将整部影片拆分成一片片的然后连贯起来播放。补间动画则可以实现对view的缩放、平移、旋转等操作。在3.0之后,出现了一种新的动画模式称为属性动画property animation。

属性动画产生的原因

属性动画的出现不是用来替代补间动画的,而是用来解决补间动画所不能够完成的事件的。如果我们的需求超出了操控view的旋转、缩放、平移等操作范围,那么我们就需选择属性动画去实现了。那么属性动画可以做到哪些补间动画做不到的事情呢?下面列举几点,当然属性动画的功能很强大,不仅限于我列举的几点。

属性动画可以做到对一个非view类进行动画操作。

属性动画可以做到真正的改变view对象的属性值。而补间动画只是改变了view的动画效果。

ValueAnimator与ObjectAnimator

ObjectAnimator是属性动画中最总要的执行类,ObjectAnimator可以操作某个对象的属性值,但是这个属性值必须要有get和set方法,同时也可以设置view的执行线路,通过插值器来控制。

举个简单的例子:

ObjectAnimator

.ofFloat(view, "rotationY", 0.0F, 360.0F)

.setDuration(500)

.start();

其可操作的属性有x/y;scaleX/scaleY;rotationX/ rotationY;transitionX/ transitionY等。

上面的例子是修改view的单个属性值,同样也可以同时修改多个属性,下面介绍两种

PropertyValuesHolder属性值持有者

PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", 0, 1);

PropertyValuesHolder pvhTop = PropertyValuesHolder.ofInt("top", 0, 1);

ObjectAnimator.ofPropertyValuesHolder( this, pvhLeft, pvhTop).

提供一个不存在的属性值

ObjectAnimator anim = ObjectAnimator.ofFloat(view, "long", 1.0F, 0.0F).setDuration(500);

anim.start();

anim.UpdateListener(new AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

float cVal = (Float) AnimatedValue();

view.setAlpha(cVal);

view.setScaleX(cVal);

view.setScaleY(cVal);

}

});

上面提到的都是修改对象已有的setter和getter方法的属性值。那么如果对象没有为某个属性提供提供setter和getter方法呢,我们也可以做到修改这些属性值,下面提供两种实现方式:

通过valueAnimation来实现,这个下面会讲解。

通过自己写一个包装类来实现。然后为该属性提供setter和getter方法。

class ViewWrapper{

private View mView;

public int getWidth(){

LayoutParams().width;

}

}

ValueAnimator包含Property Animation动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等。

属性动画的应用有两个步骤:

1、计算属性的值。2、根据属性值执行相应的动作。

ValueAnimator只是完成了第一步骤,而要完成第二步还要借助于UpdateListener接口,在此方法中可以通过ValueAnimator对象的getAnimatedValue()函数可以得到当前的属性值。

ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);

animation.setDuration(1000);

animation.addUpdateListener(new AnimatorUpdateListener () {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

Log.i("update", ((AnimatedValue()).toString());

// 此处可以根据getAnimatedValue获取到的属性值改变view相关的属性从而执行某些动作

}

});

animation.setInterpolator(new CycleInterpolator(3));

animation.start();

Time Interpolator插值器与TypeEvaluator估值器

Time interplator:定义了属性值变化的方式,如线性均匀改变,开始慢然后逐渐快等。在Property Animation中是TimeInterplator,在View Animation中是Interplator,这两个是一样的,在3.0之前只有Interplator,3.0之后实现代码转移至了TimeInterplator。Interplator继承自TimeInterplator,内部没有任何其他代码。

AccelerateInterpolator 加速,开始时慢中间加速

DecelerateInterpolator 减速,开始时快然后减速

AccelerateDecelerateInterolator 先加速后减速,开始结束时慢,中间加速

AnticipateInterpolator 反向 ,先向相反方向改变一段再加速播放

AnticipateOvershootInterpolator 反向加回弹,先向相反方向改变,再加速播放,会超出目的值然后缓慢移动至目的值

BounceInterpolator 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100

CycleIinterpolator 循环,动画循环一定次数,值的改变为一正弦函数:Math.sin(2 * mCycles * Math.PI * input)

LinearInterpolator 线性,线性均匀改变

OvershottInterpolator 回弹,最后超出目的值然后缓慢改变到目的值

TimeInterpolator 一个接口,允许你自定义interpolator,以上几个都是实现了这个接口

TypeEvaluator:根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值,android提供了以下几个evalutor:

IntEvaluator:属性的值类型为int。

FloatEvaluator:属性的值类型为float。

ArgbEvaluator:属性的值类型为十六进制颜色值。

TypeEvaluator:一个接口,可以通过实现该接口自定义Evaluator。

当然我们也可以自己定义估值器,如下:

public class FloatEvaluator implements TypeEvaluator {

public Object evaluate(float fraction, Object startValue, Object endValue) {

float startFloat = ((Number) startValue).floatValue();

return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);

}

}

实例

接下来我们要实现的就是如下的 效果图:

在本例的实现中我们的重点也是在ValueAnimator和ObjectAnimator中读者可以结合上述知识内容来消化本例的动画技术。附上代码:

ample.custom.animation;

import java.util.ArrayList;

ample.custom.R;

import android.animation.Animator;

import android.animation.AnimatorListenerAdapter;

import android.animation.AnimatorSet;

import android.animation.ArgbEvaluator;

import android.animation.ObjectAnimator;

import android.animation.ValueAnimator;

import android.app.Activity;

t.Context;

aphics.Canvas;

aphics.Paint;

aphics.RadialGradient;

aphics.Shader;

aphics.drawable.ShapeDrawable;

aphics.drawable.shapes.OvalShape;

import android.os.Bundle;

import android.view.MotionEvent;

import android.view.View;

import android.view.animation.AccelerateInterpolator;

import android.view.animation.DecelerateInterpolator;

import android.widget.LinearLayout;

public class BouncingBalls extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

setContentView(R.layout.bouncing_balls);

LinearLayout container = (LinearLayout) findViewById(ainer);

container.addView(new MyAnimationView(this));

}

public class MyAnimationView extends View {

private static final int RED = 0xffFF8080;

private static final int BLUE = 0xff8080FF;

public final ArrayList balls = new ArrayList();

AnimatorSet animation = null;

public MyAnimationView(Context context) {

super(context);

ValueAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", RED, BLUE);

colorAnim.setDuration(3000);

colorAnim.setEvaluator(new ArgbEvaluator());

colorAnim.setRepeatCount(ValueAnimator.INFINITE);

colorAnim.setRepeatMode(ValueAnimator.REVERSE);

colorAnim.start();

}

@Override

public boolean onTouchEvent(MotionEvent event) {

if (Action() != MotionEvent.ACTION_DOWN &&

return false;

}

// 初始化一个跳跳球

ShapeHolder newBall = X(), Y());

float startY = Y();

float endY = getHeight() - 50;

float h = (float)getHeight();

float eventY = Y();

int duration = (int)(500 * ((h - eventY)/h));

// 操作newBall的Y属性值

ValueAnimator bounceAnim = ObjectAnimator.ofFloat(newBall, "y", startY, endY);

bounceAnim.setDuration(duration);

bounceAnim.setInterpolator(new AccelerateInterpolator());

ValueAnimator squashAnim1 = ObjectAnimator.ofFloat(newBall, "x", X(),X() - 25f);

squashAnim1.setDuration(duration/4);

squashAnim1.setRepeatCount(1);

squashAnim1.setRepeatMode(ValueAnimator.REVERSE);

squashAnim1.setInterpolator(new DecelerateInterpolator());

ValueAnimator squashAnim2 = ObjectAnimator.ofFloat(newBall, "width", Width(),Width() + 50);

squashAnim2.setDuration(duration/4);

squashAnim2.setRepeatCount(1);

squashAnim2.setRepeatMode(ValueAnimator.REVERSE);

squashAnim2.setInterpolator(new DecelerateInterpolator());

ValueAnimator stretchAnim1 = ObjectAnimator.ofFloat(newBall, "y", endY, endY + 25f);

stretchAnim1.setDuration(duration/4);

stretchAnim1.setRepeatCount(1);

stretchAnim1.setInterpolator(new DecelerateInterpolator());

stretchAnim1.setRepeatMode(ValueAnimator.REVERSE);

ValueAnimator stretchAnim2 = ObjectAnimator.ofFloat(newBall, "height",Height(), Height() - 25);

stretchAnim2.setDuration(duration/4);

stretchAnim2.setRepeatCount(1);

stretchAnim2.setInterpolator(new DecelerateInterpolator());

stretchAnim2.setRepeatMode(ValueAnimator.REVERSE);

ValueAnimator bounceBackAnim = ObjectAnimator.ofFloat(newBall, "y", endY, startY);

bounceBackAnim.setDuration(duration);

bounceBackAnim.setInterpolator(new DecelerateInterpolator());

AnimatorSet bouncer = new AnimatorSet();

bouncer.play(bounceAnim).before(squashAnim1);

bouncer.play(squashAnim1).with(squashAnim2);

bouncer.play(squashAnim1).with(stretchAnim1);

bouncer.play(squashAnim1).with(stretchAnim2);

bouncer.play(bounceBackAnim).after(stretchAnim2);

ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);

fadeAnim.setDuration(250);

fadeAnim.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationEnd(Animator animation) {

}

});

AnimatorSet animatorSet = new AnimatorSet();

animatorSet.play(bouncer).before(fadeAnim);

animatorSet.start();

return true;

}

private ShapeHolder initBouncingBall(float x, float y) {

int red = (int)(Math.random() * 255);

int green = (int)(Math.random() * 255);

int blue = (int)(Math.random() * 255);

int color = 0xff000000 | red << 16 | green << 8 | blue;

int darkColor = 0xff000000 | red/4 << 16 | green/4 << 8 | blue/4;

// 实例化一个圆形

OvalShape circle = new OvalShape();

// 设置画笔的形状

ShapeDrawable drawable = new ShapeDrawable(circle);

Paint paint = Paint();

// 第一个,第二个参数表示渐变圆中心坐标,半径,圆心颜色,圆边缘颜色,渲染器平铺模式

RadialGradient gradient = new RadialGradient(37.5f, 12.5f, 50f, color, darkColor, Shader.TileMode.CLAMP);

// 给画笔设置著色器

paint.setShader(gradient);

ShapeHolder shapeHolder = new ShapeHolder(drawable);

shapeHolder.setX(x - 25f);

shapeHolder.setY(y - 25f);

shapeHolder.setPaint(paint);

balls.add(shapeHolder);

return shapeHolder;

}

@Override

protected void onDraw(Canvas canvas) {

for (int i = 0; i < balls.size(); ++i) {

ShapeHolder shapeHolder = (i);

canvas.save();

}

}

}

}

ample.custom.animation;

aphics.Paint;

aphics.RadialGradient;

aphics.drawable.ShapeDrawable;

aphics.drawable.shapes.Shape;

import android.view.View;

public class ShapeHolder {

private float x = 0, y = 0;

private int color;

private float alpha = 1f;

private Paint paint;

private ShapeDrawable shape;

private RadialGradient gradient;

public void setPaint(Paint value) {

paint = value;

}

public Paint getPaint() {

return paint;

}

public void setX(float value) {

x = value;

}

public float getX() {

return x;

}

public void setY(float value) {

y = value;

}

public float getY() {

return y;

}

public void setShape(ShapeDrawable value) {

shape = value;

}

public ShapeDrawable getShape() {

return shape;

}

public int getColor() {

return color;

}

public void setColor(int value) {

color = value;

}

public void setGradient(RadialGradient value) {

gradient = value;

}

public RadialGradient getGradient() {

return gradient;

}

public void setAlpha(float alpha) {

this.alpha = alpha;

shape.setAlpha((int)((alpha * 255f) + .5f));

}

public float getWidth() {

Shape().getWidth();

}

public void setWidth(float width) {

Shape s = Shape();

}

public float getHeight() {

Shape().getHeight();

}

public void setHeight(float height) {

Shape s = Shape();

}

public ShapeHolder(ShapeDrawable s) {

shape = s;

}

}

本文发布于:2024-02-01 12:27:21,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170676164336589.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:卡通片   效果   代码   高手   java
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23