越来越多的地方都会用到烟花效果了,而且很多游戏都会有类似通关之后的爆炸特效,今天来分享一下烟花爆炸的动效。升空的动画就不用写了,主要就写个view的位移,重点就是四散开来的爆炸。下面见见效果:
下面就来看如何处理的吧,将烟花爆炸的火花转变为bitmap,然后根据这个火花的个数,创建出多个bitmap,给每一个bitmap一个随机的角度,为后面的四散做准备:
private void init() {
Random random = new Random(System.currentTimeMillis());
// color = colors[random.nextInt(colors.length)];
// 给每个火花设定一个随机的方向 0-360
elements.clear();
Log.d("zxc118", "Firework init mode = " + mode + " count = " + count);
if (mode == 0) {
for (int i = 0; i < count; i++) {
color = bitmapColor[random.nextInt(bitmapColor.length)];
InputStream is = context.getResources().openRawResource(color);
Bitmap mBitmap = BitmapFactory.decodeStream(is);
elements.add(new Element(color, Math.toRadians(random
.nextInt(360)), random.nextFloat() * launchSpeed,
mBitmap));
}
} else {
float bitmapScale = 2;
if (srceenWidth > 0) {
bitmapScale = srceenWidth / screenWidthMeasure * bitmapScale;
}
for (int i = 0; i < count; i++) {
InputStream is = context.getResources().openRawResource(color);//小星星图片资源id
Bitmap mBitmap = BitmapFactory.decodeStream(is);
/* Bitmap shapeBitmap = Utils.drawShapeBitmap(mBitmap,
(int) (srceenWidth / screenWidthMeasure * starSize),
"star");*/
Bitmap shapeBitmap = imageScale(mBitmap, 35, 35);
elements.add(new Element(color, Math.toRadians(random
.nextInt(360)), random.nextFloat() * launchSpeed,
shapeBitmap));
}
}
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
timeCount = 1;
animatorValue = timeCount;
}
剩下就是爆炸,这个爆炸就是给火花一个随机的位置进行移动,然后通过不停的绘画,然后在屏幕上产生效果,当然这个中间会有不断的更新火花的位置,为这个火花下一次位置做准备。
* 开始烟花爆炸动画
*/
public void fire() {
animator = ValueAnimator.ofFloat(1, 0);
animator.setDuration(duration);
//从头开始动画
animator.setRepeatMode(ValueAnimator.RESTART);
animator.setInterpolator(new AccelerateInterpolator());
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
animatorValue = (Float) valueAnimator.getAnimatedValue();
Log.d("zxc55", "onAnimationUpdate animatorValue = " + animatorValue);
// 计算每个火花的位置
isStart = true;
for (Element element : elements) {
element.x = (float) (element.x
+ Math.cos(element.direction) * element.speed
* animatorValue + windSpeed * windDirection);
element.y = (float) (element.y
- Math.sin(element.direction) * element.speed
* animatorValue + gravity * (1 - animatorValue));
}
}
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
Log.d("zxc118", "onAnimationEnd clear animator");
listener.onAnimationEnd(Firework.this);
needRemove = true;
}
});
animator.start();
// if (mode == 0 && sounds != null) {
// sounds.playSound(9, 0);
// }
}
再来看看将这个火花绘制到画布上,和更新位置的代码吧。
public void draw(Canvas canvas) {
mPaint.setAlpha((int) (225 * animatorValue));
/*
* 有些情况小星星动画不能停止,强制结束
*/
n++;
if (n > maxTime) {
listener.onAnimationEnd(Firework.this);
}
Random random = new Random();
for (Element element : elements) {
float left = location.x + element.x/3;
float top = location.y + element.y/3;
// left=left-left*200/rangeSize;
// top=top-top*200/rangeSize;
mPaint.setAlpha(random.nextInt(225));
canvas.drawBitmap(element.bitmap, left,
top, mPaint);
}
/*
* 更新烟花位置
*/
if (n > 2 && !isStart) {
updateLocation();
}
}
public void updateLocation() {
animatorValue -= dif;
if (animatorValue < 0) {
listener.onAnimationEnd(Firework.this);
}
for (Element element : elements) {
element.x = (float) (element.x
+ Math.cos(element.direction) * element.speed
* animatorValue + windSpeed * windDirection);
element.y = (float) (element.y
- Math.sin(element.direction) * element.speed
* animatorValue + gravity * (1 - animatorValue));
}
}
大概也就这些,下面给出demo地址:https://download.csdn.net/download/greatdaocaoren/12538519