android利用图片实现烟花效果

今天突然想做一个烟花播放的效果,用粒子系统来做好像挺麻烦的。想用cocos2d-x,后来想想没必要,就想做一个自定义view,然后可以添加到程序的任何地方。在网上找了一下资料。正好有人写了,搞下来觉得不错,于是便优化一下加点注释。

 

工程目录如下

 

 

FireWorkActivity代码很简单如下

package com.firework;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

import com.fireview.FireworkView;

public class FireWorkActivity extends Activity {
	/** Called when the activity is first created. */

	// EventListener mListener = new EventListener();

	static final String LOG_TAG = FireWorkActivity.class.getSimpleName();
	static int SCREEN_W = 480;// 当前窗口的大小
	static int SCREEN_H = 854;

	FireworkView fireworkView;

	// get the current looper (from your Activity UI thread for instance

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
//		if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
//			setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//		}
		fireworkView = new FireworkView(this);
		setContentView(fireworkView);

	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		if (fireworkView.isRunning()) {
			fireworkView.setRunning(false);
		}
	}
	

}


关键还是看FireworkView这个自定义视图

 

package com.fireview;

import java.io.InputStream;
import java.util.Vector;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.view.MotionEvent;
import android.view.View;

import com.dot.Dot;
import com.dot.DotFactory;
import com.dot.LittleDot;
import com.firework.R;

/**     
 * 类名称:FireworkView   
 * 类描述:继承android的View,实现烟花效果
 * 创建人:anan   
 * 创建时间:2012-12-16 下午1:02:36   
 * 修改人:anan  
 * 修改时间:2012-12-16 下午1:02:36   
 * 修改备注:   
 * @version        
 * */
public class FireworkView extends View {

	final String LOG_TAG = FireworkView.class.getSimpleName();

	public static final int ID_SOUND_UP = 0;
	public static final int ID_SOUND_BLOW = 1;
	public static final int ID_SOUND_MULTIPLE = 2;
	final static int TIME = 5; // 圈数

	/**画面中的烟花数*/
	private Vector<Dot> lList = new Vector<Dot>();

	LittleDot[] ld = new LittleDot[200];
	private DotFactory df = null;

	boolean running = true;

	Bitmap backGroundBitmap;

	Context mContext;

	public static SoundPlay soundPlay;

	public FireworkView(Context context) {
		super(context);
		df = new DotFactory();
		new MyThread().start();
		mContext = context;
		backGroundBitmap = ReadBitMap(mContext, R.drawable.night);
		backGroundBitmap = resizeImage(backGroundBitmap, 480, 800);
		initSound(mContext);

	}

	public static void initSound(Context context) {
		soundPlay = new SoundPlay();
		soundPlay.initSounds(context);
		soundPlay.loadSfx(context, R.raw.up, ID_SOUND_UP);
		soundPlay.loadSfx(context, R.raw.blow, ID_SOUND_BLOW);
		soundPlay.loadSfx(context, R.raw.multiple, ID_SOUND_MULTIPLE);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		canvas.drawBitmap(backGroundBitmap, 0, 0, null);
		synchronized (lList) {
			for (int i = 0; i < lList.size(); i++) {
				lList.get(i).myPaint(canvas, lList);
			}
		}
		invalidate();
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			Dot dot = null;
			int rand = (int) (Math.random() * 99);
			
			dot = df.makeDot(mContext, rand, (int) event.getX(),(int) event.getY());
			synchronized (lList) {
				lList.add(dot);
				soundPlay.play(ID_SOUND_UP, 0);
			}
		}
		return super.onTouchEvent(event);
	}

	public boolean isRunning() {
		return running;
	}

	public void setRunning(boolean running) {
		this.running = running;
	}

	public Bitmap ReadBitMap(Context context, int resId) {
		BitmapFactory.Options opt = new BitmapFactory.Options();
		opt.inPreferredConfig = Bitmap.Config.RGB_565;
		opt.inPurgeable = true;
		opt.inInputShareable = true;
		// 获取资源图片
		InputStream is = context.getResources().openRawResource(resId);
		return BitmapFactory.decodeStream(is, null, opt);
	}

	public Bitmap resizeImage(Bitmap mBitmap, int w, int h) {
		Bitmap BitmapOrg = mBitmap;
		int width = BitmapOrg.getWidth();
		int height = BitmapOrg.getHeight();
		int newWidth = w;
		int newHeight = h;
		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;

		Matrix matrix = new Matrix();
		matrix.postScale(scaleWidth, scaleHeight);
		Bitmap tmp = Bitmap.createBitmap(BitmapOrg, 0, 0, width, height,
				matrix, true);
		return tmp;
	}

	/**     
	 * 类名称:MyThread   
	 * 类描述:重绘线程
	 * 创建人:anan   
	 * 创建时间:2012-12-16 下午1:06:50   
	 * 修改人:anan  
	 * 修改时间:2012-12-16 下午1:06:50   
	 * 修改备注:   
	 * @version        
	 * */
	class MyThread extends Thread {
		// 用于控制烟火在空中滞留的时间
		int times = 0;

		public void run() {
			Dot dot = null;
			while (running) {

				try {
					Thread.sleep(100);
				} catch (Exception e) {
					System.out.println(e);
				}

				synchronized (lList) {
					// 防止画面的烟花个数多于50个
					while (lList.size() > 50) {
						System.out.println("当前数目超过50");
						for (int i = 0; i < 10; i++) {
							lList.remove(i);
						}
					}
//					// 自动添加烟火
//					if (lList.size() <= 2) {
//						Dot tmp = null;
//						int rand = (int) (Math.random() * 99);
//						Random random = new Random();
//						tmp = df.makeDot(mContext, rand, random.nextInt(480),
//								50 + random.nextInt(300));
//						lList.add(tmp);
//					}
				}

				for (int i = 0; i < lList.size(); i++) {
					dot = (Dot) lList.get(i);
					if (dot.state == 1 && !dot.whetherBlast()) {
						dot.rise();
					}
					// 如果是whetherBlast()返回的是true,那么就把该dot的state设置为2
					else if (dot.state == 1 && dot.state != 2) {
						dot.state = 2;
						soundPlay.play(ID_SOUND_BLOW, 0);
					} else if (dot.state == 3) {

					}
					// 规定,每个爆炸点最多是TIME圈,超过就会消失
					if (dot.circle >= TIME) {
						// 在空中滞留一秒才消失
						if (times >= 10) {
							dot.state = 4;
							times = 0;
						} else {
							times++;
						}
						// dot.state = 4;
					}
				}
			}
		}
	}
}


其他代码不贴了。其实原理就是用canvas绘制图片,在烟花上升的时候不断的切换五张图片,然后烟花爆炸的时候也切换图片。整个数据都放到list中维护,用到的无非是基本的2d图形绘制

 

效果图

 

 

 

下载地址

http://download.csdn.net/detail/yunji3344/4895463

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的烟花效果程序的实现方法: 1. 创建一个新项目并在 activity_main.xml 文件中添加一个 FrameLayout 作为根布局。 ``` <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> ``` 2. 创建一个自定义 View 类 FireworkView 并继承 View。在这个类中,我们将实现烟花的绘制和动画效果。 ``` public class FireworkView extends View { private Paint mPaint; private int mRadius; private int mX, mY; private int mWidth, mHeight; public FireworkView(Context context) { super(context); init(); } public FireworkView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(); } private void init() { mPaint = new Paint(); mPaint.setColor(Color.RED); mRadius = 10; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawCircle(mX, mY, mRadius, mPaint); if (mRadius < 100) { mRadius += 5; invalidate(); } else { ((ViewGroup)getParent()).removeView(this); } } public void setStartPosition(int x, int y) { mX = x; mY = y; } } ``` 3. 在 MainActivity 中添加以下代码以实现烟花效果: ``` public class MainActivity extends AppCompatActivity { private FrameLayout mContainer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContainer = (FrameLayout) findViewById(R.id.container); mContainer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { FireworkView fireworkView = new FireworkView(MainActivity.this); Random random = new Random(); int x = random.nextInt(mContainer.getWidth()); int y = random.nextInt(mContainer.getHeight()); fireworkView.setStartPosition(x, y); mContainer.addView(fireworkView); } }); } } ``` 这里我们在 FrameLayout 上设置一个点击事件,每次点击时都会在随机位置添加一个 FireworkView。在 FireworkView 的 onDraw 方法中,我们使用 Canvas 绘制一个圆形,并不断地增加它的半径,直到达到一定大小后将自身从父布局中移除。这样就可以实现一个简单的烟花效果了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值