Android makes particle explosion effect

Source: Internet
Author: User
Tags transparent color

Android makes particle explosion effect
Introduction

When I was hanging out recently, I foundParticle Blast EffectAnd the effect is good.
But the code is not easy to expand, that is to say, if you want to provide different explosion effects, you need to modify a lot. So I performed some operations on the source code.ReconstructionTo separate the explosion process from the particle motion.
For the source code, you can refer to the following link
Link 1
Link 2

The above two sets of code have the same structure, but different effects (in fact, they are different in Particle Motion algorithms ).
This article will introduce the effect of particle explosion.Implementation MethodTo clarify the Implementation ideas for everyone.

The implementation result is as follows:


 

Class Design

The class design diagram is as follows:

Explain? Http://www.bkjia.com/kf/ware/vc/ "target =" _ blank "class =" keylink "> keys + keys/YvP7J + keys/tLW9zerV + keys + o6yxrNWotq + keys + vMbKscb3PC9zdHJvbmc + keys/ tM68xsqxo6y + zbj80MLL + release/release + o6yz6c/release + DQo8aDEgaWQ9" use of controls "> Use of controls

Controls are easy to use. To achieve different explosion effects, you mustPass in different participant factory factories to ExplosionFieldTo generate different particles.

ExplosionField explosionField = new ExplosionField(this,new FallingParticleFactory());

Then add the control that needs to explode.

explosionField.addListener(findViewById(R.id.text));explosionField.addListener(findViewById(R.id.layout1));

In this way, the explosion effect is added for the two controls. Note thatLayout1 represents a viewgroup, so we will add an explosion effect for each view in the viewgroup..
As we can imagine,In the ExplosionField constructor, you can generate different explosion effects by inputting different participant factory values.

 

Explosive implementation concept 1. Get the current control background bitmap

For example, imageview is used in the example. For this control, I provideToolTo obtain the Bitmap object of the background.

public static Bitmap createBitmapFromView(View view) {        view.clearFocus();        Bitmap bitmap = createBitmapSafely(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888, 1);        if (bitmap != null) {            synchronized (sCanvas) {                Canvas canvas = sCanvas;                canvas.setBitmap(bitmap);                view.draw(canvas);                canvas.setBitmap(null);            }        }        return bitmap;    }    public static Bitmap createBitmapSafely(int width, int height, Bitmap.Config config, int retryCount) {        try {            return Bitmap.createBitmap(width, height, config);        } catch (OutOfMemoryError e) {            e.printStackTrace();            if (retryCount > 0) {                System.gc();                return createBitmapSafely(width, height, config, retryCount - 1);            }            return null;        }    }

The above method, in short, isCopy the Bitmap object of the control and return it.
We know that,Bitmap can be regarded as a pixel matrix. The vertices above the matrix are color pixels, so we can obtain the color and position of each vertex (not necessarily each, assembled into an object Particle, so that the Particle represents a colored dot.

2. Convert the background bitmap into a Particle Array

After obtaining Bitmap, we hand it over to the participant factory for processing and generate Particle arrays based on Bitmap.

public abstract class ParticleFactory {    public abstract Particle[][] generateParticles(Bitmap bitmap, Rect bound);}

For example, let's look at a simple implementation class, which is also the first factory class in gif images with falling effects.

Public class fallingparticipant lefactory extends participant factory {public static final int PART_WH = 8; // default small ball width and height public Particle [] [] generateParticles (Bitmap bitmap, Rect bound) {int w = bound. width (); // scene width int h = bound. height (); // scene height int partW_Count = w/PART_WH; // horizontal number int partH_Count = h/PART_WH; // vertical number int bitmap_part_w = bitmap. getWidth ()/partW_Count; int bitmap_part_h = bitmap. getHeight ()/partH_Count; Particle [] [] participant = new Particle [partH_Count] [partW_Count]; Point point = null; for (int row = 0; row <partH_Count; row ++) {// row for (int column = 0; column <partW_Count; column ++) {// column // obtain the color int color = bitmap where the current particle is located. getPixel (column * bitmap_part_w, row * bitmap_part_h); float x = bound. left + fallingparticipant factory. PART_WH * column; float y = bound. top + fallingparticipant factory. PART_WH * row; participant [row] [column] = new FallingParticle (color, x, y, bound) ;}} return participant ;}}

WhereThe Rect bound represents the width and height of the original View control..
According to eachParticle Size, AndControl width and heightThen we can calculate how many particles constitute the background of the control.
We get the color and position of the position where each particle is located for particle production, which is FallingParticle.

3. generate an explosion site and start the explosion animation process.

Site required for ExplosionThat is, the place where the particles are drawn. We add an ExplosionField covering the full screen to the current screen as the explosion site.

Public class ExplosionField extends View {... /*** add full-screen ExplosionField */private void attach2Activity (Activity) {ViewGroup rootView = (ViewGroup) activity to the activity. findViewById (Window. ID_ANDROID_CONTENT); ViewGroup. layoutParams lp = new ViewGroup. layoutParams (ViewGroup. layoutParams. MATCH_PARENT, ViewGroup. layoutParams. MATCH_PARENT); rootView. addView (this, lp );}...}

After the explosion site is added, we respond to the Click Event of the control and start the animation.
FirstAnimation

/*** Brute-force cracking * @ param view causes this view to be cracked */public void explode (final View view) {// prevent repeated click if (explosionAnimatorsMap. get (view )! = Null & explosionAnimatorsMap. get (view ). isStarted () {return;} // to correctly plot the particle final Rect rect = new Rect (); view. getGlobalVisibleRect (rect); // obtain the coordinate int contentTop = (ViewGroup) getParent () of the view relative to the entire screen ()). getTop (); Rect frame = new Rect (); (Activity) getContext ()). getWindow (). getDecorView (). getWindowVisibleDisplayFrame (frame); int statusBarHeight = frame. top; rect. offset (0,-contentTop-statusBarHeight); // remove the status bar height and title bar height. // shake the animation ValueAnimator animator = ValueAnimator. ofFloat (0f, 1f ). setDuration (150); animator. addUpdateListener (new ValueAnimator. animatorUpdateListener () {Random random = new Random (); @ Override public void onAnimationUpdate (ValueAnimator animation) {view. setTranslationX (random. nextFloat ()-0.5f) * view. getWidth () * 0.05f); view. setTranslationY (random. nextFloat ()-0.5f) * view. getHeight () * 0.05f) ;}}); animator. addListener (new AnimatorListenerAdapter () {@ Override public void onAnimationEnd (Animator animation) {super. onAnimationEnd (animation); explode (view, rect); // explosion animation}); animator. start ();}

Vibration animation is very simple, that is, on the x and y directions, random displacement is generated, so that the original control can be moved.
At the end of the animation, an animation explosion was called, and the animation began to explode.

Private void explode (final View view, Rect rect) {final ExplosionAnimator animator = new ExplosionAnimator (this, Utils. createBitmapFromView (view), rect, mParticleFactory); explosionAnimators. add (animator); explosionAnimatorsMap. put (view, animator); animator. addListener (new AnimatorListenerAdapter () {@ Override public void onAnimationStart (Animator animation) {// zoom out and transparent animation view. animate (). setDuration (150 ). scaleX (0f ). scaleY (0f ). alpha (0f ). start () ;}@ Override public void onAnimationEnd (Animator animation) {view. animate (). alpha (1f ). setDuration (150 ). start (); // explosionAnimators are removed from the animation set at the animation end. remove (animation); explosionAnimatorsMap. remove (view); animation = null ;}}); animator. start ();}

Animation explosion firstHide the original control.
Let's look at the specific implementation of the explosion animation.

Public class ExplosionAnimator extends ValueAnimator {... public ExplosionAnimator (View view, Bitmap bitmap, Rect bound, fig factory) {mParticleFactory = participant factory; mPaint = new Paint (); mContainer = view; setFloatValues (0.0f, 1.0f ); setDuration (DEFAULT_DURATION); mParticles = mParticleFactory. generateParticles (bitmap, bound);} // the most important method is public void draw (Canvas canvas ){ If (! IsStarted () {// stop return when the animation ends;} // All Particle Motion for (particle [] Particle: mParticles) {for (particle p: Particle) {p. advance (canvas, mPaint, (Float) getAnimatedValue () ;}} mContainer. invalidate () ;}@ Override public void start () {super. start (); mContainer. invalidate ();}}

The implementation is simple, that is, generating a particle Array Based on the factory class.
The essence is a ValueAnimator, which is counted from 0 to 1 in a certain period of time.
Then a draw () method is provided to callThe advance () method of each particle is used.And input the number of the current count (a decimal number ).
In the advance () method, the draw () method and caculate () method are actually called.

The above implementation,In fact, it is a fixed process. After the explosion site is added, we start to count from 0 to 1. In this process, the particles will draw their own positions based on the current time, therefore, the position of a particle is determined by itself and has nothing to do with the process.
That is to say, we only need to use different algorithms to draw the position of the particle, thus realizing the separation of flow and particle motion.

4. How to exercise? Particles are the clearest

For example, in a gif image, the falling particles are moving like this.

Public class FallingParticle extends Particle {static Random random = new Random (); float radius = fallingparticipant factory. PART_WH; float alpha = 1.0f; Rect mBound;/*** @ param color * @ param x * @ param y */public FallingParticle (int color, float x, float y, rect bound) {super (color, x, y); mBound = bound ;}... protected void caculate (float factor) {cx = cx + factor * random. nextInt (mBound. width () * (random. nextFloat ()-0.5f); cy = cy + factor * random. nextInt (mBound. height ()/2); radius = radius-factor * random. nextInt (2); alpha = (1f-factor) * (1 + random. nextFloat ());}}

The caculate (float factor) method calculates the next position of a particle based on the current time.
We can see that in this particle, cy is increasing in the vertical direction, and cx is also increasing or decreasing randomly in the horizontal direction, thus forming a falling effect.
After calculating the current position, the particle will be drawn by itself.

Protected void draw (Canvas canvas, Paint paint) {paint. setColor (color); paint. setAlpha (int) (Color. alpha (color) * alpha); // The transparent color is not black canvas. drawCircle (cx, cy, radius, paint );}


 

How to expand?

From the code structure, we can see that,The explosion process is irrelevant to the specific motion of particles.And most importantly, we wantImplement your own caculate () method to determine the Particle Motion Form.
Different particles can be produced by the corresponding factory, so the explosion characteristics should be extended,You only need to define a particle class and the factory that generates the particle class.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.