package { import aeon.AnimationLoop; import aeon.animators.Tweener; import aeon.events.AnimationEvent; import aether.effects.common.CompositeEffect; import aether.effects.common.OverlayImageEffect; import aether.effects.shaders.ShaderEffect; import aether.effects.shaders.WrapToSphereEffect; import aether.effects.texture.TextureEffect; import aether.effects.transformations.TranslateEffect; import aether.textures.natural.EarthTexture; import aether.textures.natural.StarsTexture; import aether.utils.ImageUtil; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.GradientType; import flash.display.Shape; import flash.display.Sprite; import flash.geom.Matrix; [SWF(width=550, height=400, backgroundColor=0x000000)] /** * Demonstrates the use of the aether and aeon libraries to create complex composite effects. * This uses generated textures and a shader effect from aether to draw a planet onto a starfield. * The aeon library is then used animate the rotation of the planet in an endless loop. */ public class graphic_flex_image_effects_07_Flex_Planet extends Sprite { private const IMAGE_WIDTH:uint = 360; private const IMAGE_HEIGHT:uint = 288; private const PLANET_RADIUS:uint = IMAGE_HEIGHT/2; /** * Constructor. Pretty much handles it all. */ public function graphic_flex_image_effects_07_Flex_Planet() { // draw starfield and add it to stage var stars:BitmapData = new StarsTexture(stage.stageWidth, stage.stageHeight, 0).draw(); addChild(new Bitmap(stars)); // transparent bitmap data will hold planet texture var planet:BitmapData = new BitmapData(IMAGE_WIDTH, IMAGE_HEIGHT, true, 0x00000000); // make second bitmap data same size as first, then draw gradient that will be used for // lighting effect on planet var gradientOverlay:BitmapData = planet.clone(); gradientOverlay.draw(getGradientOverlayShape()); // draw Earth texture into planet bitmap data new TextureEffect( new EarthTexture(IMAGE_WIDTH, IMAGE_HEIGHT) ).apply(planet); // saved data since undistorted data will have to be referenced each frame var savedgraphic_flex_image_effects_07_Flex_PlanetData:BitmapData = planet.clone(); // path to .pbj file; if you have different directory structure YOU MUST UPDATE PATH!!!! ShaderEffect.shaderFilePath = "../../assets/"; // shader will wrap texture around sphere shape var shaderEffect:WrapToSphereEffect = new WrapToSphereEffect(PLANET_RADIUS, IMAGE_WIDTH, IMAGE_HEIGHT); // combine spherical wrap and overlay gradient to planet texture for still planet new CompositeEffect( [ shaderEffect, new OverlayImageEffect(gradientOverlay) ] ).apply(planet); // add planet data to bitmap and then to the stage var bitmap:Bitmap = new Bitmap(planet); bitmap.x = 210; bitmap.y = 0; // slight rotation will make "planet rotation" more realistic bitmap.rotation = 30; addChild(bitmap); // tweener set up to interpolate values between 0 and width of image over 30 seconds var tweener:Tweener = new Tweener(null, {x:0}, {x:IMAGE_WIDTH}, 30000); // -1 for loop means it will go indefinitely new AnimationLoop(tweener, -1, // every time loop runs (each frame) this function will be called function (event:AnimationEvent):void { // copy the original, undistorted planet data var copy:BitmapData = savedgraphic_flex_image_effects_07_Flex_PlanetData.clone(); new CompositeEffect( [ // translate texture on x axis by current tweener value new TranslateEffect((event.target as Tweener).currentValue.x, 0, true), // reapply shader and overlay gradient to translated texture shaderEffect, new OverlayImageEffect(gradientOverlay) ] ).apply(copy); // copy the new translation onto old bitmap data so bitmap on stage can update // bitmap.bitmapData = copy; will also work ImageUtil.copyPixels(copy, planet); } ).start(); } /** * Draws a gradient shape to be used to overlay planet to create lighting effect. * * @return The shape drawn with the gradient. */ private function getGradientOverlayShape():Shape { var shape:Shape = new Shape(); var matrix:Matrix = new Matrix(); matrix.createGradientBox(IMAGE_HEIGHT, IMAGE_HEIGHT, Math.PI/4, 18); // white in the middle and black on the outside var colors:Array = [0xFFFFFF, 0xFFFFFF, 0, 0]; // only first and last colros have opacity var alphas:Array = [.1, 0, 0, .6]; var ratios:Array = [0, 60, 120, 255]; // -0.7 to offset focal point shape.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios, matrix, null, null, -0.7); shape.graphics.drawCircle(PLANET_RADIUS, PLANET_RADIUS, PLANET_RADIUS); shape.graphics.endFill(); return shape; } } }