java实现物体下落效果_手撸一个物体下落的控件,实现雪花飘落效果

效果图:

AAffA0nNPuCLAAAAAElFTkSuQmCC

圣诞登录页.gif

参考文章:

Android自定义View——从零开始实现雪花飘落效果

感谢原文作者,不仅实现了效果,并且写得非常详细,还做了优化。笔者参考原文作者的源码,做了一点修改,实现了效果并加入了项目中。不过都大同小异,下面笔者会将学习和制作中的难点和注意点分享给大家。

提炼与分享:

1. 如何实现简单的物体下落:@Override

protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if(fallObjects.size()>0){            for (int i=0;i

fallObjects.get(i).drawObject(canvas);

}            // 隔一段时间重绘一次, 动画效果

getHandler().postDelayed(runnable, intervalTime);

}

}    private Runnable runnable = new Runnable() {        @Override

public void run() {

invalidate();

}

};    public void drawObject(Canvas canvas){

moveObject();

canvas.drawBitmap(bitmap,presentX,presentY,null);

}    private void moveObject(){

moveX();

moveY();        if(presentY>parentHeight || presentXparentWidth+bitmap.getWidth()){

reset();

}

}    private void moveY(){

presentY += presentSpeed;

}    private void moveX(){

presentX += defaultWindSpeed * Math.sin(angle);        if(isAngleChange){

angle += (float) (random.nextBoolean()?-1:1) * Math.random() * 0.0025;

}

}    private void reset(){

presentY = -objectHeight;

randomSpeed();

randomWind();//记得重置一下初始角度,不然雪花会越下越少(因为角度累加会让雪花越下越偏)

}

首先是Y轴控制竖直下落,初始的Y轴坐标是通过屏幕高度取随机值-屏幕高度来确定的。这样物体会从不同的位置下落,在相同速度的情况下,也能在不同的时间进入屏幕。

然后是X轴,正常的雪花肯定不是竖直下落,也不是折线下落,而是弧形,View中采用的sin函数的-Pi到Pi之间的值绘制弧形。x轴的初始位置通过对屏幕宽度做随机值确定。

最后在物体到底屏幕底部,或者超过屏幕左右边界时,重置物体(reset方法)。需要重置的是y轴的点,以及物体的速度,当然还有我们模拟的风力,后面会单独说。

2. 为什么要使用Builder建造者模式

其实原文已经讲得很仔细了,我们物体会有大量的参数和对应的行为方法,为了提高代码的可读性,我们将物体提取出来,作为一个单独的类。而大量的参数采用普通的构造方法去构造,实在是不知道,传入的参数究竟代表什么。而建造者模式能够解决这个问题。FallObject.Builder builder = new FallObject.Builder(getResources().getDrawable(R.drawable.snowflake));

FallObject fallObject = builder

.setSpeed(8,true)

.setSize(80,80,true)

.setWind(5,true)

.build();        //初始化一个雪球样式的fallObject

((FallingView)findViewById(R.id.fallingView)).addFallObject(fallObject,60);//添加60个雪球对象

在这个项目中,我们将所有与下落物体相关的方法和属性全部封装在FallObject中,并且提供Builder内部类实例化。而我们的View则仅仅需要作为一个画布,提供添加下落对象的方法,重复的绘制物体即可。至于绘制的对象是要下落还是要旋转,都与View没有关系了。

3. 绘制图片并且控制其大小

绘制图片在View中是有提供方法的:canvas.drawBitmap(bitmap,presentX,presentY,null);从方法中可以看到,我们需要的是bitmap的图片,那么,我们在修改图片大小之前,还需要先将drawable转化为bitmap。/**

* drawable图片资源转bitmap

* @param drawable

* @return

*/

public static Bitmap drawableToBitmap(Drawable drawable) {

Bitmap bitmap = Bitmap.createBitmap(

drawable.getIntrinsicWidth(),

drawable.getIntrinsicHeight(),

drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888

: Bitmap.Config.RGB_565);

Canvas canvas = new Canvas(bitmap);

drawable.setBounds(0, 0, drawable.getIn

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值