仿消灭星星烟花爆炸效果
烟花效果,可以改变参数和图片改变烟花效果。
1.大烟花爆炸效果如下
2.小烟花爆炸效果如下
3.代码如下
3.1烟花粒子元素
import android.graphics.Bitmap;
public class Element {
public int color;
public Double direction;
public float speed;
public float x = 0;
public float y = 0;
public Bitmap bitmap;
public Element(int color, Double direction, float speed,Bitmap bitmap){
this.color = color;
this.direction = direction;
this.speed = speed;
this.bitmap = bitmap;
}
}
3.2烟花粒子控制类
import android.R.integer;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.AvoidXfermode.Mode;
import android.os.Handler;
import android.provider.MediaStore.Video;
import android.util.Log;
import android.view.animation.AccelerateInterpolator;
import android.widget.Toast;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import com.develop.GameSoundPool.GameSoundPool;
import com.develop.PopStars.R;
import com.develop.PopStars.Util.Utils;
public class Firework {
private final String TAG = this.getClass().getSimpleName();
final float screenWidthMeasure = 720;
private final static int BIG_DEFAULT_ELEMENT_COUNT = 200;//大烟花爆炸数量
private final static int MIDDLE_DEFAULT_ELEMENT_COUNT = 200;
private int BIG_DEFAULT_DURATION = 3000;
private final static float BIG_DEFAULT_LAUNCH_SPEED = 3;
private final static float BIG_DEFAULT_ELEMENT_SIZE = 8;
private final static int SMALL_DEFAULT_ELEMENT_COUNT = 8;//小星星爆炸数量
private int SMALL_DEFAULT_DURATION = 1300;//烟花持续时间
private final static float SMALL_DEFAULT_LAUNCH_SPEED = 18;//烟花分散速度
private final static float SMALL_DEFAULT_ELEMENT_SIZE = 8;//烟花颗粒大小
private final static float DEFAULT_WIND_SPEED = 6;
private final static float DEFAULT_GRAVITY = 6;
private Paint mPaint;
private int count; // count of element
private int duration;
private int[] colors;
private int color;
private float launchSpeed;
private float windSpeed;
private float gravity;
private int windDirection; // 1 or -1
private Location location;
private float elementSize;
GameSoundPool sounds;//烟花爆炸声音控制
private ValueAnimator animator;
private float animatorValue;
private ArrayList<Element> elements = new ArrayList<Element>();
private AnimationEndListener listener;
Context context;
private int mode = 0;
private float srceenWidth;
private float screenHeight;
//大烟花颗粒随机图片
private int bitmapColor[] = { R.drawable.light_blue,
R.drawable.light_yellow, R.drawable.light_green,
R.drawable.light_pink, R.drawable.light_red };
public void setMode(int mode) {
this.mode = mode;
}
public void setScreenSize(float width, float height) {
srceenWidth = width;
screenHeight = height;
}
public Firework(Location location, int windDirection, int mode,
Context context, GameSoundPool sounds, int color, float width,
float height) {
srceenWidth = width;
screenHeight = height;
this.color = color;
this.location = location;
this.sounds = sounds;
this.windDirection = windDirection;
this.context = context;
this.mode = mode;
colors = baseColors;
gravity = DEFAULT_GRAVITY;
windSpeed = DEFAULT_WIND_SPEED;
if (srceenWidth > 0) {
BIG_DEFAULT_DURATION = (int) (srceenWidth / screenWidthMeasure * BIG_DEFAULT_DURATION);
SMALL_DEFAULT_DURATION = (int) (srceenWidth / screenWidthMeasure * SMALL_DEFAULT_DURATION);
}
if (mode == 0) {// 大烟花
count = BIG_DEFAULT_ELEMENT_COUNT;
duration = BIG_DEFAULT_DURATION;
launchSpeed = BIG_DEFAULT_LAUNCH_SPEED;
elementSize = BIG_DEFAULT_ELEMENT_SIZE;
} else if (mode == 1) {//小星星爆炸
count = SMALL_DEFAULT_ELEMENT_COUNT;
duration = SMALL_DEFAULT_DURATION;
launchSpeed = SMALL_DEFAULT_LAUNCH_SPEED;
elementSize = SMALL_DEFAULT_ELEMENT_SIZE;
} else {
count = MIDDLE_DEFAULT_ELEMENT_COUNT;
duration = BIG_DEFAULT_DURATION;
launchSpeed = BIG_DEFAULT_LAUNCH_SPEED;
elementSize = BIG_DEFAULT_ELEMENT_SIZE;
}
init();
}
private float starSize = 15;
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");
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;
}
private float timeCount = 1;
private final float dif = 0.00816f;
float startTime;
private boolean needRemove =false;
public boolean getRemove(){
return needRemove;
}
boolean isStart = false;
/*
* 开始烟花爆炸动画
*/
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 setCount(int count) {
this.count = count;
}
public void setColors(int colors[]) {
this.colors = colors;
}
public void setDuration(int duration) {
this.duration = duration;
}
public void addAnimationEndListener(AnimationEndListener listener) {
this.listener = listener;
}
private final int maxTime = 38;
private int n =0;
public void draw(Canvas canvas) {
mPaint.setAlpha((int) (225 * animatorValue));
/*
* 有些情况小星星动画不能停止,强制结束
*/
n++;
if(n>maxTime){
listener.onAnimationEnd(Firework.this);
}
for (Element element : elements) {
canvas.drawBitmap(element.bitmap, location.x + element.x,
location.y + element.y, 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));
}
}
public void release() {
for (Element element : elements) {
if (element.bitmap != null && element.bitmap.isRecycled()) {
element.bitmap.recycle();
}
}
}
private static final int[] baseColors = { 0xFFFF43, 0x00E500, 0x44CEF6,
0xFF0040, 0xFF00FFB7, 0x008CFF, 0xFF5286, 0x562CFF, 0x2C9DFF,
0x00FFFF, 0x00FF77, 0x11FF00, 0xFFB536, 0xFF4618, 0xFF334B,
0x9CFA18 };
interface AnimationEndListener {
void onAnimationEnd(Firework mFirework);
}
static class Location {
public float x;
public float y;
public Location(float x, float y) {
this.x = x;
this.y = y;
}
}
}
3.3自定义粒子控件
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.EditText;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedList;
import com.develop.GameSoundPool.GameSoundPool;
public class FireworkView extends View {
private final String TAG = this.getClass().getSimpleName();
private LinkedList<Firework> fireworks = new LinkedList<Firework>();
private int windSpeed;
private TextWatcher mTextWatcher;
Context context;
GameSoundPool sounds;
private float srceenWidth;
private float screenHeight;
public FireworkView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
}
public FireworkView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
public FireworkView(Context context,GameSoundPool sounds) {
super(context);
this.context = context;
this.sounds =sounds;
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
srceenWidth = wm.getDefaultDisplay().getWidth();
screenHeight = wm.getDefaultDisplay().getHeight();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
return false;
}
public void lunchFireWork(float x, float y, int direction,int mode,int color){
final Firework firework = new Firework(new Firework.Location(x, y), direction,mode,context,sounds,color,srceenWidth,screenHeight);
firework.addAnimationEndListener(new Firework.AnimationEndListener() {
@Override
public void onAnimationEnd(Firework mFirework) {
fireworks.remove(mFirework);
mFirework.release();
}
});
fireworks.add(firework);
firework.fire();
invalidate();
}
public void removeAllFireWork(){
if(fireworks != null){
for (Firework obj:fireworks){
fireworks.remove(obj);
obj.release();
}
}
}
@Override
protected void onDraw(Canvas canvas) {
for (int i =0 ; i<fireworks.size(); i++){
fireworks.get(i).draw(canvas);
}
if (fireworks.size()>0)
invalidate();
}
}
使用方法
FireworkView 对象调用lunchFireWork(float x, float y, int direction,int mode,int color)方法
参数:x,坐标 y,坐标 direction,旋转方向 mode,烟花类型 color,粒子图片(资源id)
例如 fireworkView.lunchFireWork(100,100,0,0,0);大烟花
例如 fireworkView.lunchFireWork(x,y,0,1,color);小烟花
附加烟花图片
仿消灭星星烟花爆炸效果相关推荐
- Unity3D_(Shuriken粒子系统)制作简单的烟花爆炸效果
Unity中的粒子系统可以用于制作特效,如开枪火花效果,简单爆炸效果等.(毕竟程序员不是设计师,简单的特效都没有问题,要制作一些非常美观的特效还是需要多了解跟美术有关的知识.) 粒子系统实现一个简单的 ...
- 鼠标点击烟花爆炸效果
鼠标点击烟花爆炸效果 效果预览: 预览结果 一. 快速使用(引用我创建好的anime.min.js文件) <canvas class="fireworks"style=&qu ...
- JS实现鼠标点击处烟花爆炸效果
JS实现鼠标点击处烟花爆炸效果(面向对象版) 程序由网上开源"JS实现放烟花效果"代码改编,实现在鼠标点击处出现烟花爆炸效果. 改编前 源码link https://github. ...
- unity 彩带粒子_Unity3D_(Shuriken粒子系统)制作简单的烟花爆炸效果
Unity中的粒子系统可以用于制作特效,如开枪火花效果,简单爆炸效果等.(毕竟程序员不是设计师,简单的特效都没有问题,要制作一些非常美观的特效还是需要多了解跟美术有关的知识.) 粒子系统实现一个简单的 ...
- Shell 仿消灭星星游戏(2013-03-15)
前言 做一个小游戏练习 shell脚本的语法什么的.入门一般都是俄罗斯方块,不过也都有了,推箱子有用C写过,很简单,网上也有了,就做一个网上还没有人用 shell写过的吧.模拟 IPAD 上一个&qu ...
- 音视频开发系列(41)OpenGL ES粒子效果-烟花爆炸
通过该篇的实践实现如下效果 一.烟花爆竹场景和属性 在上一篇OpenGL ES粒子系统 - 喷泉的基础上 实现烟花爆炸效果. 在具体实践之前,先来想一想,烟花爆炸的场景和属性 场景:从中心点开始爆炸, ...
- 音视频开发之旅(16) OpenGL ES粒子效果-烟花爆炸
目录 烟花爆竹场景和属性 实践以及遇到的问题 资料 收获 通过该篇的实践实现如下效果 一.烟花爆竹场景和属性 在上一篇 音视频开发之旅(15) OpenGL ES粒子系统 - 喷泉 的基础上 实现烟花 ...
- ShaderJoy —— 烟花爆炸特效【GLSL】
效果视频 ShaderJoy --♡の烟花 效果图 烟花爆炸效果 稍加修改的效果
- android星星爆炸效果图,Android_Android仿开心消消乐大树星星无限循环效果,啥都不说先上效果图,这个是 - phpStudy...
Android仿开心消消乐大树星星无限循环效果 啥都不说先上效果图,这个是我项目里的效果: 下面的是我抽取出来的 demo 适配啥的我基本上都做好了没做其他的 ok 下面 说一下思路把 首先 说一下原 ...
最新文章
- 《I'm a Mac:雄狮训练手册》——1.12 开机快捷键
- boost::fusion::back_extended_deque用法的测试程序
- 微软大数据_我对Microsoft的数据科学采访
- c++ 一行输出八个数字_R语言笔记(三):数据输入与输出
- python调用远程js_python和js交互调用的方法
- Hadoop2.7.3完全分布式集群搭建(三节点)
- 瑞萨RH850F1L用户手册(UM)CAN接口部分中文翻译(Section 19 CAN Interface (RS-CAN))
- html yy直播,网页YY直播间进入方法 网页YY迷你版怎么用
- 车间和仓库可以一起吗_车间和仓库可以划分为一个防火分区吗
- 【kali技巧】kali配置ssh服务
- 百度API调用(六)——调用百度UNIT对话机器人
- MySQL如何删除一行数据
- 三星证实遭黑客入侵:Galaxy手机源代码泄露
- 高级前端工程师和低级前端工程师的区别
- vSphere 通过 vMotion 实现虚拟机热迁移
- 老闪创业那些事儿(40)——倒霉的光哥
- 有向图的强联通分量之:【求最长链】【求最长链的方案数(图论中的方案数DP)】【最长链和最大半联通子图 节点数相同】【最长链与最大半联通子图等价又不完全等价】
- 使用阿里云的oss对图片加水印并且字体大小自适应(阿里云oss暂不支持字体大小自适应)
- 为什么Git把SVN拍在了沙滩上?
- thinkpad8 x86 android,ThinkPad 8系统是什么?ThinkPad 8能升级安卓4.3吗?