Detailed explanation of rain and snow animation effect using surfaceview (kotlin syntax)

preface

Recently, I plan to do a wave of things to consolidate what I have learned recently. Without much to say, let's take a look at the final rendering:

It's lazy here... In the second picture, it's still raining... But this is not the key point

Snow.gif

Recorded MP4, converted to GIF. The first GIF sets the frame rate, so it seems that the frame loss may be serious, but it won't, because I also noticed the problem of drawing 60 frames in 1s. Reading this article requires some basic knowledge of view and some basic kotlin syntax. To be honest, in terms of knowledge, it has nothing to do with kotlin, as long as you understand the basic grammar.

Clarify ideas

Before you start, you should first sort out your ideas and analyze what scheme should be adopted to achieve this effect from the following aspects:

The above is my initial thinking about implementation, followed by code implementation analysis.

Code implementation analysis

Code structure diagram first:

Code structure

Weathershape is the parent class of all weather. Rain and snow are two concrete implementation classes.

Take a look at the code of the parent class:

Speaking of this code, well, I've experienced some refactoring... On the way to play with my classmates on Saturday, I refactored and extracted some operations that can be put into the base class. Although this is not flexible enough, subclasses can easily implement something that needs similar functions through inheritance, such as rain and snow here. By the way, I make complaints about the style of my notes. I can see that if you look carefully, you can see that the rain or snowflake patterns in GIF may have some differences. Yes, every drop of rain and snow has undergone some random changes.

The two more important attributes are isinuse and israndom. I originally wanted to use a container as the shape management class for unified management, but this will certainly make the use and reuse process more complex. Finally, I decided to use a simpler method to save a usage state and whether it is random in shape. Israndoma indicates whether the shape is random. Randomness will be reflected in the X coordinate of the shape in the current code. If the random ID is true, the X coordinate will be any value from 0 to screenwidth. So it's not random? In my implementation, the same type of shape will be divided into two types: one is constant group. It will have a relatively fixed x value, but it will also have a random offset of 10 ~ 15px. The other is the random group. The x value is random on the full screen. In this way, there will be raindrops (snowflakes) everywhere on the screen, but there will be differences in density. Initstyle is this random process. If you are interested, you can see the implementation~

Start and end are the upper left corner and lower right corner of shape. If you know about cavans API, you should know that most shapes can be drawn through the conversion and calculation of start and end.

Next, let's take a look at the specific implementation of the snow class:

As long as this class understands the calculation and drawing of the center of the circle, it basically has nothing. First, eliminate the interference item. At the beginning of the design, getacceleration was used to calculate the distance through acceleration. Later, it was found... Forget it, let's keep the speed constant... So it all returned 0f. Here, the WTC () function and drawwheninuse may make you look confused. What is the name of the function? Drawwheninuse knows the meaning of the name. What is WTC ()? WTC here is equivalent to an additional initialization. The function name of the full state should be wantochange (). These function call processes are as follows:

Draw (canvas) is a method of the parent class, initializing the Shape when the isInUse identifier is false, specifically calling the initStyle () method, while WTC () will be called at the end of initStyle () method. If you have any initialization you want to add, you can use this function. The drawwheninuse (canvas) method is a function that needs to realize dynamic rendering. Here, I did some initialization in the WTC () function, and recalculated the start, end and center of the circle according to the characteristics of the circle.

Next, let's see how we draw these personalized snow on the screen:

Init {} is the code block provided to us in kotlin for initialization. Some initialization operations are performed in init and the thread is started. If you look at the code executed in the thread, you will first judge an ID called canrun, which will be set to true when the surface is created, otherwise the thread will wait through an object. After the surface is created, the notify method will be called to restart the thread. The next step is to draw. There will be a timing action before and after drawing. Whether the calculation time is less than 16ms. If not, let thread sleep supplement the interpolation. Because the rendering speed of one frame of 16ms is enough, there is no need to draw too fast and waste resources.

Here you can see that I created a Java object object, mainly because kotlin itself does not support some concurrency primitives well. Any object in kotlin inherits from any. Any has no wait, notify and other methods, so black technology is used here... Java objects are created

The key code drawing in the code calls the drawrain (canvas) method of weathershapepool. Finally, take a look at this class:

This class is still relatively simple. It's just a simple container. It's called pool... At first, I wanted to manage recycling and reuse myself, so I called it pool. Later, I felt that this thing didn't need to be implemented so complex

In a word, it's not difficult for people to meet this thing, and my code is not perfect. If I have any mistakes or you have any good opinions, you can put forward them. It's best to comment by email or under the article.

Project address: https://github.com/ForgetAll/GankKotlin

Local download: http://xiazai.jb51.net/201709/yuanma/GankKotlin (jb51.net).rar

summary

The above is the whole content of this article. I hope the content of this article has a certain reference value for your study or work. If you have any questions, you can leave a message. Thank you for your support for programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>