Skip to main content
SiUsPlauTancat
Known Participant
December 28, 2016
Answered

A waving flag effect?

  • December 28, 2016
  • 3 replies
  • 3766 views

Hi,

is there a way to create a waving flag effect from the image loaded with an UIloader in ActionScript 3?

How can I do that? I found a lot of topics like this, but i can not understand well.

Thanks so much,

This topic has been closed for replies.
Correct answer kglad

save it to a aether/utils/ subdirectory of the directory used to save your fla

3 replies

SiUsPlauTancat
Known Participant
December 30, 2016

As file

kglad
Community Expert
kgladCommunity ExpertCorrect answer
Community Expert
December 30, 2016

save it to a aether/utils/ subdirectory of the directory used to save your fla

kglad
Community Expert
Community Expert
January 2, 2017

Now looks like ok but still i have problem...

C:\Dropbox (Crionet)\RS & BJ\AS v3.0\Wave Flag\classes\FlagWaving.as, Line 24, Column 381017: The definition of base class AbstractImageLoader was not found.

C:\Dropbox (Crionet)\RS & BJ\AS v3.0\Wave Flag\classes\FlagWaving.as, Line 46, Column 391020: Method marked override must override another method.

i'm a newbie i never used package in AS3....


this fixes that code so it has no dependencies.  to use it, import the FlagWave class and call the constructor passing a path/filename bitmap to load and the wind rate.  eg,

import FlagWave;

var flagWave:FlagWave = new FlagWave('z_bitmaps/kg.png',30);

addChild(flagWave);

package {

    import flash.display.BitmapData;

    import flash.display.BitmapDataChannel;

    import flash.display.BlendMode;

    import flash.display.GradientType;

    import flash.display.Shape;

    import flash.events.Event;

    import flash.filters.DisplacementMapFilter;

    import flash.filters.DisplacementMapFilterMode;

    import flash.geom.ColorTransform;

    import flash.geom.Matrix;

    import flash.geom.Point;

    import flash.display.Loader;

    import flash.net.URLRequest;

    import flash.display.Bitmap;

    import flash.display.Sprite

    /**

     * Demonstrates the use of Perlin noise and a displacement map to animate an image

     * of a flag waving in the wind. In order to limit the amount of displacement,

     * a gradient is drawn into the displacement map using medium gray.

     */

    public class FlagWave extends Sprite{

        // controls how fast flag will flap

        private var WIND_RATE: Number;

        private var loader:Loader= new Loader();

        private var _loadedBitmap:Bitmap;

        private var _gradient: BitmapData;

        private var _flag: BitmapData;

        private var _perlinNoise: BitmapData;

        private var _perlinOffsets: Array;

        private var _perlinSeed: int;

        /**

         * Constructor. Sends path of asset to super class to load.

         */

        public function FlagWave(urlS:String,windRate:Number=30){

            loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadCompleteF);

            loader.load(new URLRequest(urlS));

            WIND_RATE = windRate;

          

        }

        public function kill():void{

            removeEventListener(Event.ENTER_FRAME,animateFlag);

        }

        private function loadCompleteF(e:Event):void{

            _loadedBitmap = Bitmap(loader.content);

            init();

        }

        private function init(): void {

            makeFlag();

            makeGradientOverlay();

            makeNoise();

            addEventListener(Event.ENTER_FRAME, animateFlag);

        }

        private function makeFlag(): void {

            var stageWidth: Number = stage.stageWidth;

            var stageHeight: Number = stage.stageHeight;

            var bitmapData: BitmapData = _loadedBitmap.bitmapData;

            var bitmapWidth: Number = bitmapData.width;

            var bitmapHeight: Number = bitmapData.height;

            // settings for the size and position of pole

            var poleWidth: Number = 15;

            var poleHeight: Number = 250;

            var poleX: Number = 35;

            var poleY: Number = stageHeight - poleHeight;

            // draws a horizontal linera gradient for the pole

            var matrix: Matrix = new Matrix();

            matrix.createGradientBox(poleWidth, poleHeight);

            var pole: Shape = new Shape();

            pole.graphics.beginGradientFill(

                GradientType.LINEAR, [0x333333, 0x999999, 0xCCCCCC, 0xAAAAAA, 0x666666], [1, 1, 1, 1, 1], [0, 50, 160, 200, 255],

                matrix

            );

            pole.graphics.drawRect(0, 0, poleWidth, poleHeight);

            pole.graphics.endFill();

            pole.x = poleX;

            pole.y = poleY;

            addChild(pole);

            // point at top left of flag

            var point: Point = new Point(

                (stageWidth - bitmapWidth) / 2, (stageHeight - bitmapHeight) / 2

            );

            // draws two cords from pole to flag's left side

            var cord: Shape = new Shape();

            cord.graphics.lineStyle(2, 0x333333);

            cord.graphics.moveTo(poleX, poleY + 3);

            cord.graphics.lineTo(point.x, point.y);

            cord.graphics.moveTo(point.x, point.y + bitmapHeight);

            cord.graphics.lineTo(poleX, poleY + bitmapHeight + 20);

            // draws cord shape into bitmap data with flag, so that all can be distorted

            _flag = new BitmapData(stageWidth, stageHeight, true, 0x00000000);

            _flag.draw(cord);

            _flag.copyPixels(bitmapData, bitmapData.rect, point);

            _loadedBitmap.bitmapData = _flag;

            addChild(_loadedBitmap);

        }

        /**

         * Creates the bitmap data that will be used to draw into the displacement

         * map in order to limit the amount of distortion. This is accomplished by

         * drawing a gradient of medium gray going from full opacity to none over the

         * left side of the displacement map, preventing displacement on the left of the image.

         */

        private function makeGradientOverlay(): void {

            var width: Number = stage.stageWidth;

            var height: Number = stage.stageHeight;

            var matrix: Matrix = new Matrix();

            matrix.createGradientBox(width, height);

            var shape: Shape = new Shape();

            shape.graphics.beginGradientFill(

                GradientType.LINEAR, [0x7F7F7F, 0x7F7F7F], [1, 0], [20, 80],

                matrix

            );

            shape.graphics.drawRect(0, 0, width, height);

            shape.graphics.endFill();

            // draw gradient shape into bitmap data for use later

            _gradient = new BitmapData(width, height, true, 0x00000000);

            _gradient.draw(shape);

        }

        /**

         * Initializes Perlin noise properties that will be used in flame animation.

         */

        private function makeNoise(): void {

            _perlinNoise = new BitmapData(stage.stageWidth, stage.stageHeight);

            _perlinSeed = int(new Date());

            // only one octave requires only one point

            _perlinOffsets = [new Point()];

        }

        /**

         * Applies the Perlin noise to the bitmap data, offsetting the octave displacement

         * by the WIND_RATE each time this method is called.

         */

        private function applyNoise(): void {

            _perlinNoise.perlinNoise(

                200,

                200,

                1,

                _perlinSeed,

                false,

                true,

                BitmapDataChannel.RED,

                true,

                _perlinOffsets

            );

            // altering offset contributes to horizontal animation of flag

            (_perlinOffsets[0] as Point).x -= WIND_RATE;

        }

        /**

         * Redraws the flag with new distortion to create animated effect of flapping.

         */

        private function animateFlag(e:Event): void {

            // generate new Perlin noise

            applyNoise();

            var flag: BitmapData = _flag.clone();

            // copy the gradient overlay to limit the displacement

            _perlinNoise.copyPixels(

                _gradient,

                _gradient.rect,

                new Point(),

                _perlinNoise,

                new Point(),

                true

            );

            // displace original flag with new displacement map

            flag.applyFilter(flag, flag.rect, new Point(), new DisplacementMapFilter(_perlinNoise,new Point(),BitmapDataChannel.RED,BitmapDataChannel.RED,40,60));

            _perlinNoise.copyChannel(flag,flag.rect,new Point(),BitmapDataChannel.ALPHA,BitmapDataChannel.ALPHA);

          

            // overlay the displacement map for a lighting effect using darks and lights

            flag.draw(

                _perlinNoise,

                null,

                new ColorTransform(1, 1, 1, 0.5),

                BlendMode.HARDLIGHT

            );

            _loadedBitmap.bitmapData = flag;

        }

    }

}

////////////////////////////

p.s. call the kill() method to stop the animation of the flag

SiUsPlauTancat
Known Participant
December 28, 2016

From where can I download? And where do I have to copy it?

Thanks

kglad
Community Expert
Community Expert
December 28, 2016

from wherever you got that code.

SiUsPlauTancat
Known Participant
December 28, 2016

Yes I find it but I don't know where I have to copy it..

kglad
Community Expert
Community Expert
December 28, 2016
SiUsPlauTancat
Known Participant
December 28, 2016

I already tried with this code but i have problem with

import aether.utils.ImageUtil;

i got this error

Symbol 'Flagha', Layer 'Layer 1', Frame 1, Line 3, Column 251172: Definition aether.utils:ImageUtil could not be found.

and i can not understand why.

kglad
Community Expert
Community Expert
December 28, 2016

did you download ImageUtil?