In our our recent tutorial on clouds effect via BitmapData.perlinNoise and ColorMatrixFilter, we presented a nice clouds animation but very CPU intensive and not suitable for larger images or for mobile devices. Here we present a version that is extremely CPU efficient, runs very well on Android 2.2, and can be used to generate large images. In the two examples linked below we generate 500 by 380 animations. Click each screen shot or the corresponding text link to open a Flash movie.
Simpler and highly optimized animation:
An interesting two-layered effect:
- Download all source files corresponding to these effects: cloudsfast.zip
How is performance optimized
In our previous tutorial, Realistic White Clouds on Blue Sky in AS3 Flash, we presented a method for producing a continuously evolving picture of white clouds on a blue background, making use of Perlin noise and a ColorMatrixFilter. Although the effect was highly aesthetic, it suffered from high CPU usage due to the repeated Perlin noise computations. We present here a greatly improved method for producing moving clouds, with very light CPU usage, suitable for mobile devices.
This time we have also made the cloud effect easy to incorporate into your own designs, by keeping all the code in an external class called MovingClouds, which extends the Sprite class. The clouds are then a display object, and can easily be added to the Display List.
Creating an instance of the clouds is easy: simply use the constructor as follows:
var clouds:MovingClouds = new MovingClouds(w, h, scrollX, scrollY, useBackground, bgColor);
This creates a cloud display with width w and height h, which will scroll every frame by an amount scrollX in the x direction and scrollY in the y direction. These scroll amounts must be integers, but can be positive negative, or zero. If you wish to have a solid color background behind the clouds, set the Boolean variable useBackground to true, and set bgColor to the color you wish.
About the Code
Instead of repeatedly computing Perlin noise, which is CPU intensive, we have opted for one cloud image which is continuously scrolled. The cloud image is made to be larger than the final display, so that the repetition of the pattern is not noticeable.
To make the cloud image continuously scrollable, we make use of the "stitch" option during the Perlin noise generation. This option creates an image which seamlessly connects the bottom of the image to its top, and its left edge to its right.
Scrolling the image is accomplished using the scroll() method of the BitmapData class. However, this method does not have a built-in option for wrapping one side of the image around to the other, so we manually wrap the image.
Here is how we do the wrapping. When bitmap data is scrolled in the x and y directions, certain portions will be pushed outside of the boundaries of the bitmap. So we copy these portions to other rectangular bitmaps before scrolling, scroll the data, then copy the saved rectangles into the appropriate positions on the opposite sides. This is illustrated in the figures below: three rectangles called horizCutRect, vertCutRect, and cornerCutRect are copied and then moved to new positions horizPastePoint, vertPastePoint, and cornerPastePoint.
This continuous copying and scrolling of bitmap data is very efficient. In our previous example which used repeatedly computed Perlin noise, the cloud displays became very CPU intensive when large bitmaps and a high number of octaves were used for the Perlin noise. In this example, any number of octaves can be used, and the methods allow for a large display.
Layering the clouds
In our second example presented above, we create a very nice effect which suggests three dimensional clouds by simply layering one ScrollingClouds instance over another. We lower the alpha of the top layer, and also use a transparent background by setting the useBackground variable to false in the constructor.