Pages

Advertisement

Friday, August 10, 2007

Dynamic Snowflakes

A simple example would be to create 50 snowflakes with drawing commands. Each snowflake is kept inside its own new movie clip. Each snowflake is also a little different because we will use random numbers to determine the number of spikes and their length.

  1. Create a new Flash movie.

  2. Edit the script on the first frame. We'll add a bunch of functions there. The first one is a function that creates a snowflake. It accepts the number of this movie clip as the on parameter. For instance, snowflake number 1 will be called snowflake1 and be at level 1.

    The function creates a new movie clip. Then it sets the line style for drawing. A random number of spikes and a random length for those spikes are chosen. The function then uses simple trigonometry to draw lines from the center of the snowflake.

    function createSnowflake(n) {
    // create a new movie clip
    this.createEmptyMovieClip("snowflake"+n,n);
    mc = this["snowflake"+n];

    // set the line syle to hairline, white, semi-transparent
    mc.lineStyle(0,0xFFFFFF,50);

    // pick random number of spikes and their radius
    numSpikes = Math.round(Math.random()*5)+5; // 5 to 9
    spikeRadius = Math.random()*5+5; // 5 to 9

    // create each spike as line from center to point on circle
    for(var i=0;i<numSpikes;i++) {
    mc.moveTo(0,0);
    spikeAngle = 2.0*Math.PI*i/numSpikes;
    x = spikeRadius*Math.cos(spikeAngle);
    y = spikeRadius*Math.sin(spikeAngle);
    mc.lineTo(x,y);
    }

    // return reference to this movie clip
    return(mc);
    }


  3. The last function creates one snowflake, but we want to create many. The initSnowflakes function creates a number of snowflakes by calling the createSnowflakes function a number of times. It also sets a random location for the snowflake and random values for speed, drift, and rotate. These three variables will be used later to make the snowflake move.

    function initSnowflakes(n) {
    // remember number of snowflakes
    numSnowflakes = n;

    // create each snowflake
    for(var i=0;i<numSnowflakes;i++) {

    // create snowflae
    mc = createSnowflake(i);

    // set position
    mc._x = Math.random()*550; // 0 to 550
    mc._y = Math.random()*400; // 0 to 400

    // set movie clip variables
    mc.speed = Math.random()*3+3; // 3 to 6
    mc.drift = Math.random()*2-1; // -1 to 1
    mc.rotate = Math.random()*18-9; // -9 to 9
    }
    }


  4. The moveSnowflakes function loops through each snowflake and moves it according to its speed, drift, and rotate. If the snowflake moves off the sides or bottom of the stage, it will be reset to the other side or to the top. This keeps all the snowflakes falling constantly.

    function moveSnowflakes() {
    // loop through snowflakes
    for(var i=0;i<numSnowflakes;i++) {

    // move ad rotate the snowflake
    mc = this["snowflake"+i];
    mc._y += mc.speed;
    mc._x += mc.drift;
    mc._rotation += mc.rotate;

    // bring back to top
    if (mc._y > 400) mc._y = 0;

    // one side to another
    if (mc._x < 0) mc._x = 550;
    if (mc._x > 550) mc._x = 0;
    }
    }


  5. The frame script ends by calling initSnowflakes to make 50 snowflakes.

    // create 50 snowflakes
    initSnowflakes(50);
    stop();


  6. There also needs to be regular calls to moveSnowflakes. This will be done by a small movie clip. Create a shape and convert it to a movie clip. Move it off the stage. Then attach this script to it:

    onClipEvent(enterFrame) {
    _root.moveSnowflakes();
    }


  7. The snowflakes will be white. So if you leave the background color of your movie white, you won't be able to see them. Choose Modify, Document and change the color to black or a dark blue.



  8. Try your movie or the example movie 24snowflakes.fla. You can also play with the number of snowflakes and the range of values used to make each snowflake. Figure 24.7 shows one possible view of this movie as it runs.

    Figure 24.7. Fifty dynamically created snowflakes, all a little different from each other.

    graphics/24fig07.jpg

Flash : Drawing Lines

Drawing Lines

Flash MX contains a simple set of drawing commands that allow you to create a wide variety of graphics from scratch. You can draw straight lines, curves, and even filled areas.

Drawing Straight Lines

Drawing a line with ActionScript is easy. First, you need to define the line style. The lineStyle command takes three parameters: the line thickness, color, and alpha. The color is expressed as an ActionScript hexadecimal number. So 0x000000 is black, 0xFFFFFF is white, and so on. The alpha parameter determines a line's transparency. A value of 100 makes an opaque line, whereas a value of 50 makes a line that is faded 50 percent, and graphics behind it can be seen.

lineStyle(3,0x000000,100);

graphics/bulb.gif

If you use the line size of 0, you get a hairline. A hairline is a thin line that remains 1 pixel wide even if the line is scaled up. This is in contrast to a 1-pixel line that gets thicker as the scale of the movie increases.


After you have set the line style, you use lineTo and moveTo to draw. Imagine an invisible pen on the screen. You can direct its tip to move around on the screen. As it moves, you can tell it to draw on the screen, or just move without drawing.

The moveTo command moves the tip of the drawing pen to a location on the screen. The lineTo command moves the pen from its current location to another location and leaves a trail. Here is some code that draws a line from 275,200 to 300,225:

moveTo(275,200);
lineTo(300,225);

graphics/book.gif

If you do not use a moveTo command before you use a lineTo command, the first line will be drawn from point 0,0 to the point specified in the lineTo command.

Here is a short program that draws 500 lines from random points on the stage. You can see its result in Figure 24.1.

Figure 24.1. These random lines were created by ActionScript.

graphics/24fig01.gif

// set line style
lineStyle(2,0x000000,100);

// draw 500 lines
for(var i=0;i<500;i++) {

// pick random start point
x1 = Math.random()*550;
y1 = Math.random()*400;

// pick random end point
x2 = Math.random()*550;
y2 = Math.random()*400;

// move to start point
moveTo(x1,y1);

// draw to end point
lineTo(x2,y2);
}

Check out the example movie 24lines.fla. You can play with the line size, color, and alpha. When you set the alpha to 50, it gives the impression that the lines are laying on top of and under each other. Check out 24coloredlines.fla to see a variation where the lines all draw as different colors.

Here is a simple script that draws a crossed pattern on the screen. It creates diagonal lines in each direction all the way across the screen.

// set line style
lineStyle(2,0x999999,100);

for(var x=-400;x<550;x+=10) {
// draw diagonal strip from left to right
moveTo(x,0);
lineTo(x+400,400);

// draw opposite strip
moveTo(550-x,0);
lineTo(550-x-400,400);
}

Figure 24.2 shows the results of this script. One interesting note is that the movie 24patterns.fla takes up only 186 bytes as an .swf file. However, if you were to create the lines by hand using Flash's drawing tools and make a movie with those lines, the file would be 4,179 bytes. So you can actually save file space by drawing patterns with ActionScript rather than including them in the Flash movie as normal graphics.

Figure 24.2. This pattern was created with ActionScript.

graphics/24fig02.gif


Drawing Curves

Whereas drawing lines is easy and straightforward, drawing curves is more of an art than a science. In addition to giving the destination position where the curved line draws to, you also give a control point. This control point directs the curve of the line.

For instance, the following code draws a curve from 150,200 to 400,200. The second pair of numbers in the curveTo command gives the destination. The first pair is the control point. In this case, the control point is at 275,275, which is a little below the center of the line. This causes the line to curve down toward the control point.

lineStyle(3,0x000000,100);
moveTo(150,200);
curveTo(275,275,400,200);

Figure 24.3 shows the result. There are horizontal grid lines at 200 and 275, and vertical grid lines at 150, 275, and 400. You can see that the line starts at 150,200 and ends at 400,200. In between, it curves out to 275,275 but never reaches that point. The example movie 24curve.fla includes the grid lines that are drawn with lineTo commands.

Figure 24.3. Ever see ActionScript smile at you?

graphics/24fig03.gif

Although you can control exactly where the curve starts and ends, you only have vague control over where the curve goes in between. However, by playing around with different values, you can get close to drawing what you want.

This code creates a square shape. The lines are drawn with the curveTo command, but the control points are placed right between the points so that the lines have no curve to them at all.

lineStyle( 1, 0x0000FF, 100 );
moveTo(200,200);
curveTo(250,200,300,200);
curveTo(300,250,300,300);
curveTo(250,300,200,300);
curveTo(200,250,200,200);

In Figure 24.4, you can see that the lines have no curve. The larger dots point out where the control points are located.

Figure 24.4. These curves form a square with straight sides.

graphics/24fig04.gif

Now, if we move the control points farther away from each side, we can bulge out the sides of the square to make it resemble a circle:

var bend = 42;
moveTo(200,200);
curveTo(250,200-bend,300,200);
curveTo(300+bend,250,300,300);
curveTo(250,300+bend,200,300);
curveTo(200-bend,250,200,200);

I used the variable bend so that the control point would be moved away from each side by the same amount. The top of the square's control point is moved up, the left side's control point is moved to the left, and so on. I can adjust how far the control point is from the original side by just changing the value of bend in one place. Doing so, I was able to experiment and determine that 42 is the value that made it look best. Figure 24.5 shows this version of the drawing, complete with marks for the four control points.

Figure 24.5. This circle was drawn with only four curves. The dots show the curve's control points.

graphics/24fig05.gif

The sample movie 24curvedcircle.fla contains both examples from Figures 24.4 and 24.5.

graphics/book.gif

Although drawing a circle is a great way to start playing with the curveTo command, the curveTo command is not the best way to draw a circle. Instead, you can get better results by drawing short lines from points along the circumference of a circle using the trigonometry from Hour 11, "Working with Numbers." You can see an example in the file 24bettercircle.fla.


Drawing Filled Areas

To draw a filled area, first you have to plan to draw a series of lines or curves that form a closed shape. Then all you need to do is issue a beginFill command before you start drawing and an endFill command when you are finished.

The beginFill command takes two parameters: the color of the fill and the alpha of the fill. In this example, a box is made out of a 3-pixel thick black line. The fill is red.

lineStyle( 3, 0x000000, 100 );
beginFill( 0xFF0000 );
moveTo(175,100);
lineTo(375,100);
lineTo(375,300);
lineTo(175,300);
lineTo(175,100);
endFill();

When an area is crossed by the line twice, it remains unfilled instead of being filled. This can create interesting gaps in your filled area. For instance, the following code draws a star with five points. The area at the center of the star remains unfilled. Look at Figure 24.6 to see the result.

Figure 24.6. The area double-crossed by the lines is not filled.

graphics/24fig06.jpg

lineStyle(3,0x000000,100 );
beginFill(0xFF0000);
moveTo(250,50);
lineTo(308,230);
lineTo(155,120);
lineTo(345,120);
lineTo(192,230);
lineTo(250,50);
endFill();

graphics/book.gif

There is a better way to make a star. The example movie 24betterstar.fla not only makes stars based on trigonometry but also allows you to set the number of points in the star at the start of the script. Create 5-, 7-, 11-, or 123-pointed stars.


Beat Box

 

Figure shows a simple beat box application. To focus on the sound portion of the ActionScript, I have used the CheckBox and PushButton components.

Figure 22.1. A simple beat box application that allows the user to play with music.

graphics/22fig01.gif

  1. Open the movie 22beatboxnoscripts.fla.

  2. There are three columns of buttons. The first column is for the drum sounds. Select the first drum button and see that its Click Handler is set to buttonSound. In fact, each CheckBox and PushButton component has the Click Handler buttonSound.

  3. Where they differ, however, is their names. The drum check boxes are named drumSwitch1, drumSwitch2, and drumSwitch3. The three bass buttons are named bassSwitch1, bassSwitch2, and bassSwitch3. The three push buttons are named hitSwitch1, hitSwitch2, and hitSwitch3.

  4. This entire movie works with only two functions. The first is an advanced version of the playSound function from earlier in the hour.

    It uses four parameters. The first is a true or false value that determines whether the sound is supposed to start or stop. The second is the name of the variable to use as the sound object. The third is the name of the sound from the Library. The last parameter is whether the sound is supposed to loop.

    function playSound(startOrStop,varName,soundName,loop) {
    if (startOrStop) {
    this[varName] = new Sound();
    this[varName].attachSound(soundName);
    if (loop) {
    this[varName].start(0,9999);
    } else {
    this[varName].start(0,1);
    }
    } else {
    this[varName].stop(soundName);
    }
    }


  5. Each of the nine components in the movie calls soundButton. This calls playSound in one of nine different ways, depending on the component clicked. It uses getValue() in many cases to determine whether the check box has been clicked on or off.

    function soundButton(button) {
    if (button == bassSwitch1) {
    playSound(button.getValue(),"bassSound1","bassLoop1",true);
    } else if (button == bassSwitch2) {
    playSound(button.getValue(),"bassSound2","bassLoop2",true);
    } else if (button == bassSwitch3) {
    playSound(button.getValue(),"bassSound3","bassLoop3",true);
    } else if (button == hitSwitch1) {
    playSound(true,"hitSound1","hit1",false);
    } else if (button == hitSwitch2) {
    playSound(true,"hitSound2","hit2",false);
    } else if (button == hitSwitch3) {
    playSound(true,"hitSound3","hit3",false);
    } else if (button == drumSwitch1) {
    playSound(button.getValue(),"drumSound1","drumLoop1",true);
    } else if (button == drumSwitch2) {
    playSound(button.getValue(),"drumSound2","drumLoop2",true);
    } else if (button == drumSwitch3) {
    playSound(button.getValue(),"drumSound3","drumLoop3",true);
    }
    }

Panning Sound

You can also adjust the pan of a sound while the sound is playing. You can use this to make sounds appear to come from one side and travel to the other.

  1. Create a new movie.

  2. Import the sound 22airplane.wav from the CD-ROM.

  3. Set the sound's Linkage properties so that it exports with the movie and its linkage name is 22airplane.wav.

  4. Create a simple shape and convert it to a movie clip. Name it actions.

  5. The load handler attached to this movie clip starts the sound playing. It sets the pan to -100 so that the sound comes only from one side.

    onClipEvent(load) {
    // load sound
    thisSound = new Sound();
    thisSound.attachSound("22airplane.wav");

    // set initial pan
    thisSound.setPan(-100);
    // play three times
    thisSound.start();
    }


  6. The enterFrame handler looks at the position and duration properties of the sound object. These are both measured in milliseconds. By dividing these by each other and multiplying by 200, you get a value from 0 to 200. Subtract 100 to get a value from -100 to 100. Then, set the pan to this value:

    onClipEvent(enterFrame) {
    // get value from -100 to 100 based on position
    pan = 200*thisSound.position/thisSound.duration - 100;

    // set pan
    thisSound.setPan(pan);
    }

    The result is that the sound starts on one side, coming completely out of one speaker. Then the sound travels to the other side as setPan is used to set the pan to values between -100 and 100. The sound should end with a pan of 100.


Try the movie 22airplane.fla to see this in action.

Playing a Sound

Unfortunately, there is no simple way to play a sound. You will have to import the sound, write several lines of code, and then write several more lines of code to play the sound in anything but the standard way.

Linking and Playing Sounds

The first thing you need to do before playing a sound with ActionScript is to link it. Import the sound into the Library, select Linkage from the Library panel's menu, and set the sound to export with the movie. You can also assign a different linkage name to the sound, but Flash starts you off with the same name as the Library element, which is the same name as the file.

graphics/bulb.gif

If you are working with a movie that has a lot of sound, it is a good idea to set the default sound compression to Raw in the Publish Settings. When you test your movie, Flash will not take the time to compress the sound. This way, you can test your movie as quickly as possible. Then, change the default sound compression setting to what you really want before publishing a copy for the Web.

For instance, if you import the file mysound.wav, it will appear in the Library as mysound.wav. When you set its Linkage properties so that it exports with the file, it will be assigned the linkage name mysound.wav, but you can change that to anything you want. It is this linkage name that you will use to refer to the sound in your code.

To play a sound, you have to perform at least three steps. The first step is to create a new sound object:

mySound = new Sound();

Then, you need to attach the sound in the Library to this sound object:

mySound.attachSound("mysound.wav");

Finally, you have to tell the sound object to play the sound:

mySound.start();

Here is a simple button handler that plays a sound from the Library:

on (release) {
mySound = new Sound();
mySound.attachSound("poof.wav");
mySound.start();
}

You can find this simple example in the movie 22playsound.fla. You can find a slightly more sophisticated approach in the movie 22playsoundfunction.fla. In this movie, a function called playSound is placed in the main timeline. This function includes all the code you need to play a simple sound.

function playSound(soundName,balance) {
var mySound = new Sound();
mySound.attachSound(soundName);
mySound.start();
}

By using this function, you can simplify your ActionScript so that you can play a sound with only one line. Here is a button script that uses this function:

on (release) {
playSound("poof.wav");
}

The start Command

The start command in the previous example can be used in a few different ways. You can add up to two additional parameters to it to alter the way the sound plays.

The first parameter you can add is an offset. This starts the sound somewhere in the middle, rather than at the beginning. For instance, this line starts the sound off 1000 milliseconds, or 1 second, into the sound:

mySound.start(1000);

The second parameter the start command can take is the number of loops. For instance, if you want to start the sound off at 1 second and loop it three times, you would do this:

mySound.start(1000,3);

If you want to start the sound at the beginning and loop it three times, just use 0 as the offset:

mySound.start(0,3);

The companion command to start is stop. If you are playing a long sound, you can issue a stop command at any time to halt the sound in its tracks. You must supply the sound name again as a parameter. Otherwise, the stop command stops all sounds playing.

mySound.stop("poof.wav");

Adjusting Volume

You can alter a sound both before and during playback with a variety of commands. All these commands somehow alter the volume of the sound, in both speakers together or separately.

The setVolume command is the simplest of these adjustments. By setting the volume to a number from 0 to 100, you can raise, lower, or silence a sound:


mySound.setVolume(50);


The example movie 22playsoundvolume.fla features a Play button and four different volume buttons. The top one sets the volume to 0, the next one to 10, the next to 50, and the bottom button to 100. The Play button plays a sound 100 times so that you can have the chance to adjust the volume while it plays.

You can click a button during playback to adjust the volume. Note that adjusting the volume of a specific sound does not affect the volumes of other sounds being played at the same time. This means that you can have separate controls for different sounds—such as background music and instance sounds.


Sound Properties

Sound objects have two properties that you should know about. The first is duration. This is the how long the sound is, in milliseconds.

The sibling property to this is position. This is the location of the current bit of sound being played, in milliseconds.

For instance, if a sound has a duration of 3000, it is 3 seconds long. If the position of the sound is 1500, the sound is right in the middle of being played.

The example movie 22tracksound.fla demonstrates using position and duration to show the playback of a sound visually.

After starting a sound, a movie clip script positions a movie clip named mark at a position along the width of a movie clip named bar.

onClipEvent(enterFrame) {
// how far along is the sound (0.0 to 1.0)
percentPlayed = thisSound.position/thisSound.duration;

// how wide is the bar
barWidth = _root.bar._width;

// set the mark
_root.mark._x = _root.bar._x + barWidth*percentPlayed;
}

When a Sound Ends

You can use the duration and position of a sound to determine when a sound ends. They will be equal to each other. However, if a sound loops, the duration and position of a sound will be equal to each other for a moment at the end of each playback of the sound.

A better way to determine the end of a sound is to use the onSoundComplete listener.

This is a function triggered when the sound is finished playing.

mySound = new Sound();
mySound.attachSound("mySound.aif");
mySound.onSoundComplete = function () {
trace("sound done!");
}
mySound.start();

Setting the Balance

You can also direct the sound more to one speaker than the other with the setPan command. This is similar to the balance control on a stereo.

You can set the pan of a sound to a value from -100 to 100. If you set it to -100, all sound comes from the left speaker. Setting it to 100 means that all sound comes from the right speaker.

mySound.pan(-100);

The movie 22monopan.fla has a single-channel (mono) sound in it. When you click the button on the left, the sound plays completely from the left speaker. When you click the button on the right, the sound plays completely from the right speaker.

This is done by setting to the pan to -100 or 100 before playing the sound.


chm2web Web Online Help

Complex Loader

 

Although the simple loader may be all that you need, most large movies have something more elegant on the front end. Usually, there is a progress bar, as shown in figure

Figure 23.1. A progress bar, halfway through a load.

graphics/23fig01.gif

  1. Start a new movie.

  2. Draw a wide rectangle, complete with a border.

  3. Select the entire rectangle and turn it into a movie clip by choosing Insert, Convert to Movie Clip.

  4. Double-click on this new movie clip to edit it.

  5. Separate the rectangle's fill and border into two separate layers.

  6. Copy the rectangle fill and create a new layer to paste it into. This layer should have the border layer in front of it and the original rectangle behind it.

  7. Select the new rectangle and fill it a darker color. It should sit right on top of the lighter original rectangle.

  8. Now turn the darker rectangle into a movie clip by choosing Insert, Convert to Movie Clip. Give it any Library name you want, but give it the instance name bar in the Properties panel.

  9. Double-click on the dark rectangle movie clip to edit it. You'll need to reposition the rectangle so that the upper-left corner of the rectangle is at the movie clip's registration point (see Figure 23.2).

    Figure 23.2. The rectangle's upper-left corner is at the registration point.

    graphics/23fig02.gif

  10. Back in the main movie clip, create a fourth layer. Put a dynamic text field there. Link it to the variable displayText. Make it a nice big font, colored white.

  11. Go all the way back to the main timeline. Now we need to attach a script to the movie clip. It starts by setting up the bytesLoaded and bytesTotal variables.

    onClipEvent(load) {
    // initialize variables
    bytesLoaded = 0;
    bytesTotal = _root.getBytesTotal();
    }


  12. The enterFrame handler does most of the work. It monitors bytesLoaded and bytesTotal every frame. The variable percentLoaded is a value from 0 to 100. It is used in the text field but is also used to change the _xscale of the bar. Because the registration point is at the left, the left side of the bar stays in the same place, but the right side shrinks or grows according to _xscale.

    When the bytesLoaded equals bytesTotal, the display text is changed to a different message. The nextFrame command moves the movie forward to the next frame.



  13. The main timeline should be broken into three layers. The first layer has the loader bar movie clip that we have built. This stretches across the first two frames.



  14. Another layer has two separate key frames in frames 1 and 2. In frame 1 is a stop() command, but no other elements.



  15. The second frame of this new layer has a button. You can see it in Figure 23.3. The user clicks the simple button script to continue with the rest of the movie.

    Figure 23.3. The second frame of our loading movie allows the user to control when the rest of the movie begins.

    graphics/23fig03.gif

    on (release) {
    play();
    }


  16. The third layer of the movie contains the video—the large media piece that causes this movie to need a loading frame in the first place.