Last time I wrote a demo for simulating snow in Android.
It basically simulates the effect of falling snow, but it does not actually "snow ". Because only a few snowflakes are generated at a time. So I want to improve it.
The method I intended to improve is:
Define a snowflake class and inherit runnable. As long as it is started in the control class, the snowflake will automatically fall. When it falls under the screen, it will return to the top of the screen and fall again ......
This design is because I used to play a SWT game to allow items to draw and control their own lifecycles. This should be the first response to object-oriented design ......
However, a problem occurs because in Android, the display of the interface is controlled by the view. If you want the view to pass your canvas to the snowflake, in this way, it is better to let all the interface display be handed over to the view for processing.
After Continuous experiments, I found that my own design was not accessible ...... The reason is that you are not familiar with Android 2D. So I downloaded some materials online for learning.
--------------------------------- Split line, the content source internet ---------------------------------------------------------
In Android, display is basically handled by view. Here, we do not have to mention two classes: Android. View. View and Android. View. surfaceview.
Surfaceview is a display class derived from the view base class. Its direct sub-classes include glsurfaceview and videoview. It can be seen that Gl, video playback, and camera cameras generally use surfaceview.
What are the advantages of surfaceview?
Surfaceview can control the surface format, such as the size and position of the display on the screen. The most important thing is to provide the surfaceholder class, which is obtained using the getholder method.
Canvas lockcanvas (), canvas lockcanvas (rect dirty), void removecallback (surfaceholder. callback callback), void unlockcanvasandpost (canvas) controls graphics and painting, while in surfaceholder. you can override the following method in the callback of the callback interface:
When using surfaceview, you usually need to create, destroy, and monitor the changes. This requires surfaceholder. callback.
Class xxxview extends surfaceview implements surfaceholder. callback {public void surfacechanged (surfaceholder holder, int format, int width, int height) {}// you can check its name for its meaning, when the surface size changes, the public void surfacecreated (surfaceholder holder) {}// same as above is triggered during creation. Generally, the drawing thread is called here. Public void surfacedestroyed (surfaceholder holder) {}// same as above. It is triggered when the image is destroyed. Generally, the drawing thread is stopped and released here .}
For surface-related applications, the android underlying layer also provides GPU acceleration. Therefore, surfaceview is generally used in highly real-time applications rather than directly built from view, in addition, glsurfaceview in Android 3D OpenGL is also implemented in this class.
The most essential difference between surfaceview and view is that surfaceview can be re-painted in a new separate thread, and view must be updated in the main thread of the UI.
Updating the screen in the main UI thread may cause problems. For example, if you update the screen too long, your main UI thread will be blocked by the function you are painting. Then, messages such as buttons and touch screens cannot be responded.
When surfaceview is used to update the screen in a new thread, it will not block your main UI thread. But this also brings about another problem, that is, event synchronization. For example, if you touch the screen, you need to process the thread in surfaceview. Generally, you need an event queue design to save the touch event. This is a little more complicated because it involves thread synchronization.
Based on the above, the game features are generally divided into two categories.
1. passively update the image. For example, you can use view for chess. Because image update relies on ontouch for update, you can use invalidate directly. In this case, this touch and the next touch take a longer time and will not be affected.
2. Actively update. For example, a person is always running. This requires a separate thread to repeatedly repaint the state of the person, to avoid blocking the main UI thread. Obviously, the view is not suitable and needs surfaceview for control.
3. The surfaceview class in Android is a dual-buffer mechanism. Therefore, when developing a game, try to use surfaceview instead of view, which is more efficient and provides more comprehensive surfaceview functions.
--------------------------------------------- Split line ---------------------------------------------
So I wrote a simple demo to keep an object moving on the screen (I use a flower. Select surfaceview
@Overridepublic void surfaceCreated(SurfaceHolder holder) {SH = this.getHeight();SW = this.getWidth();th.start();}
Here we reload the surfacecrate method to get the screen height and width, start the drawing thread ...... This is because the interface is actually drawn only when surfacecreate is executed. If the screen height and width are obtained in the constructor, it can only be 0;
Public void draw () {canvas = SFH. lockcanvas (); If (canvas = NULL) {// when you press the return key, return exception is returned;} canvas. drawrect (0, 0, SW, sh, P); // screen painting canvas. save (); canvas. drawbitmap (BMP, BMP _x, BMP _y, P); log. V ("debug", BMP _x + "|" + BMP _y + "|" + speed_x + "|" + speed_y); canvas. restore (); SFH. unlockcanvasandpost (canvas );}
This method will be repeatedly called by the thread, so that the object can be moved. Where
Canvas. drawrect (0, 0, SW, sh, P); // screen Flushing
Cleans up the images left by the previous drawing to make the objects "dynamic ".
To prevent the user from clicking the "back" button and the thread is still being drawn, a null pointer exception is reported. Therefore, before each painting, check whether the canvas is empty.
private void path() {if (bmp_x >= SW - 20) {speed_x += 1;if(speed_x>15){speed_x = 3;}speed_x = -speed_x;} else if (bmp_x <= 20) {speed_x -=1;if(speed_x<-15){speed_x = -3;}speed_x = -speed_x;}if (bmp_y >= SH - 20) {speed_y+=5;if(speed_y>15){speed_y = 3;}speed_y = -speed_y;} else if (bmp_y <= 10){speed_y -=5;if(speed_y<-15){speed_y = -3;}speed_y = -speed_y;}bmp_x += speed_x;bmp_y += speed_y;}
The Path Method controls the speed and direction of object movement ......
Code: Click to open the link