High imitation ink weather day sunny days

Source: Internet
Author: User

Brief introduction

Always interested in the beautiful scene of ink weather, while there is time, oneself high imitation of one of the scenes, other scenes, is similar, is mainly written object of AI is logic.

Look at the effect first, the dynamic effect of the pit, too vague


High

Code Analysis

Take a look at the code structure.

This uses the Surfaceview instead of the view, in fact this weather scene drawing is more like the game development, uses the surfaceview will be more flexible.

    Public Scenesurfaceview (context context, AttributeSet Attrs) {        Super (context, attrs);        Surfaceholder = Getholder ();        Surfaceholder.addcallback (this);         Setfocusable (true);        Setfocusableintouchmode (true);        This.setkeepscreenon (TRUE);}
This is the construction method, the realizationSurfaceholder.callbackto listen for events

    @Override public    void surfacecreated (Surfaceholder holder) {        log.d ("Weather", "surfacecreated");        if (Renderthread = = null) {            renderthread = new Renderthread (Surfaceholder, GetContext ());            Renderthread.start ();        }}
InsurfaceCreate a callback, we generate aRenderthreadthreads are designed to do logic and draw.

    @Override    protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {        width = getmeasuredwidth (); C7/>height = Getmeasuredheight ();        Super.onmeasure (Widthmeasurespec, heightmeasurespec);        LOG.D ("Weather", "onmeasure width=" + width + ", height=" + height);        if (renderthread! = null) {            renderthread.setwidth (width);            Renderthread.setheight (height);}        }
Record the width and height of the measurement

    @Override public    void surfacedestroyed (Surfaceholder holder) {        log.d ("Weather", "surfacedestroyed");        Renderthread.getrenderhandler (). Sendemptymessage (1);}
Destroy the time to send a message, specifically what to do, the following

Below is the renderthread Source code

public class Renderthread extends Thread {private context context;    Private Surfaceholder Surfaceholder;    Private Renderhandler Renderhandler;     Private scene scene;        Public Renderthread (Surfaceholder Surfaceholder, Context context) {This.context = context;        This.surfaceholder = Surfaceholder;        Scene = new Scene (context);        Add Scene/actor SCENE.SETBG (Bitmapfactory.decoderesource (Context.getresources (), r.drawable.bg0_fine_day));        Scene.add (new Birdup (context));        Scene.add (new Cloudleft (context));        Scene.add (new Cloudright (context));        Scene.add (new Birddown (context));    Scene.add (new SunShine (context));        } @Override public void Run () {LOG.D ("Weather", "run");        Use Message Queuing Looper.prepare () on non-main threads;        Renderhandler = new Renderhandler ();        Renderhandler.sendemptymessage (0);    Looper.loop ();    } public Renderhandler Getrenderhandler () {return renderhandler; }    public class Renderhandler extends Handler {@Override public void Handlemessage (Message msg) {  Switch (msg.what) {case 0:if (scene.getwidth ()! = 0 && scene.getheight ()! =                    0) {draw ();                    } renderhandler.sendemptymessage (0);                Break                    Case 1:looper.mylooper (). Quit ();            Break        }}} private void Draw () {Canvas canvas = Surfaceholder.lockcanvas ();            if (canvas! = null) {Scene.draw (canvas);        Surfaceholder.unlockcanvasandpost (canvas);    }} public void setwidth (int width) {scene.setwidth (width);    public void setheight (int height) {scene.setheight (height); }}
Added the scene background in the construction method, up and down two birds, one cloud and the other sun.

Here in the run method generated a thread message queue, note the amount is not the main thread, in fact, you can also make a while Loop, like the general game processing, but if you use Message Queuing, it will be more lightweight and effective.

Let's see Renderhandler again.

The situation is divided into 2 kinds, one is to draw the one is exited, basically also on these 2 kinds.

Remember to call the exit in surfacedestroyed , right here, huh?

And then it's the most important draw method.

Drawing is done in Scene , take a look at the code

public class Scene {     private context context;    private int width;    private int height;     Private Bitmap BG;    Private list<actor> actors = new arraylist<actor> ();    private paint paint;     Public Scene (Context context) {        This.context = context;        Paint = new paint ();        Paint.setantialias (True);    }     public void SETBG (Bitmap bg) {        this.bg = bg;    }     public void Add (actor actor) {        actors.add (actor);    }     public void Draw (canvas canvas) {        canvas.drawbitmap (bg, new rect (0, 0, bg.getwidth (), Bg.getheight ()), new rect (0, 0, width, height), paint);        for (Actor actor:actors) {            actor.draw (canvas,width,height);        }}
You can draw a background map in the scene andActorList

What is the Actor, the object, like a bird, a cloud, rain, etc.

Public abstract class Actor {     protected context context;    Protected Matrix matrix = new Matrix ();     Protected Actor (Context context) {        This.context = context;    }     public abstract void Draw (canvas canvas, int width, int height);}
This is an abstract class,ContextYou can load a resource file,Matrixto describe the transformation of an object, an abstract methodDrawthat's our logic and our way of drawing.

Let's take a look at the bird code on the top.

public class Birdup extends Actor {private static final int[] IMGs = new Int[]{r.drawable.finedayup_1, R.drawable.fine Dayup_2, R.drawable.finedayup_3, R.drawable.finedayup_4, R.drawable.finedayup_5, R.drawable.finedayup_6,     R.drawable.finedayup_7, r.drawable.finedayup_8};    float Initpositionx;    float Initpositiony;    Boolean isinit;    List<bitmap> frames;    RECTF box;    RECTF Targetbox;    int curframeindex;    Long Lasttime;     Paint paint = new paint ();        Protected Birdup (Context context) {super (context);        frames = new arraylist<bitmap> ();        box = new RECTF ();        Targetbox = new RECTF ();    Paint.setantialias (TRUE);  } @Override public void draw (canvas canvas, int width, int height) {//logical processing//Initialize if (!isinit)            {Initpositionx = width * 0.117F;            Initpositiony = height * 0.35F;            Matrix.reset ();            Matrix.posttranslate (Initpositionx, initpositiony); for (iNT Res:imgs) {Frames.add (Bitmapfactory.decoderesource (Context.getresources (), res));            } box.set (0, 0, frames.get (0). GetWidth (), Frames.get (0). GetHeight ());            Isinit = true;            Lasttime = System.currenttimemillis ();        Return        }//Mobile Matrix.posttranslate (2, 0);        Border processing matrix.maprect (targetbox, Box);        if (Targetbox.left > width) {matrix.posttranslate (-targetbox.right, 0);        }//Get frame animated picture long curtime = System.currenttimemillis ();         Curframeindex = (int) ((curtime-lasttime)/500% 8);        Bitmap Curbitmap = Frames.get (Curframeindex);        Draw Canvas.save ();        Canvas.drawbitmap (Curbitmap, Matrix, paint);    Canvas.restore (); }}
The main logic isDraw, the note written also relatively clear, first initialize the operation, load resources, set the starting position, then the movement of each frame, and the boundary logic processing, is to run to the far right, and then pull him to the left, oh, the following is the processing of the bird animation, I here is -milliseconds to replace a piece, that is to see the bird animation, is actually isolated -milliseconds to change the effect of a picture, the following is only drawn, OK So Easyit!

Here is a special description of a method Matrix.maprect (targetbox, box); This method is more important, we will definitely use it in the future, what does it mean? Box This parameter is the original image size data, Targetbox is through Matrix the data generated after the matrix transformation.

Well, the bird below is actually the same as the logic above, but the starting position is different.

The clouds, and the bird logic is similar, but need to pay attention to a place, I magnified the Clouds 2 times

            Matrix.reset ();            Matrix.setscale (2f, 2f);            Matrix.maprect (Targetbox, box);            Matrix.posttranslate (Initpositionx-targetbox.width ()/2, Initpositiony-targetbox.height ()/2);
Here the initial position, I also according to enlarge the width and height of the treatment, we notice ah, first put the contraction and first set the position, out of the effect is not the same. You can try the effect on your own.

Now, let's take a look at our sunshine code.

Here's some key code, all the code can download on my GitHub .

        Rotating        matrix.maprect (targetbox, box);        Matrix.postrotate (0.5F, Targetbox.centerx (), Targetbox.centery ());        Transparency Change        if (alphaup) {            alpha++;        } else {            alpha--;        }        if (Alpha >= 255) {            AlphaUp = false;        }        if (Alpha <= 0) {            AlphaUp = true;        }        Paint.setalpha (Alpha);        Draw        Canvas.drawbitmap (frame, matrix, paint);
The main thing is to introduce the use of matrices for rotation operations and transparency operations. It is important to note that when rotating, the center point should be set.

Conclusion

Well, the code is about the same, the knowledge point has been a bit. Looking back, it's not that hard to achieve such an effect. Oh. Of course, the implementation is still relatively hasty, is simply a shelf and a scene, if interested in the words can add more object AI logic, more scenes. In fact, if the final optimization should be such a case, each scene an xml or other scripting Language bar, and then parse the XML to dynamically generate a scene. Of course it's not hard. If you really do the weather, you can do it.

Github Address

Https://github.com/wu928320442/MojiWeather

High imitation ink weather day sunny days

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.