1. week 1
  2. week 2
  3. week 3
  4. week 4
  5. week 5
  6. week 6
  7. week 7
  8. week 8
  9. week 9
  10. week 10
  11. week 11
  12. week 12
  13. week 13

Sunday, July 25, 2010

Summer 2010 week 11:
7/21/10: Wed, 12:25 - 3:25

Hi Everyone,

We are getting down to the end of the term. Only 3 weeks from Wednesday's class is the last day for us, so we haven't much time remaining.

For this week's posting, we will be doing two exercises, both of which synthesize many of the things that we've been working with over the last several weeks. The first one is to create buttons completely out of code and place them onto the stage of a document. The second is to start working on the music player, so we'll be going back and using some of the code learned a few weeks ago from the classes that pertained to our "music player" that played on the names of the songs. Now we have to add music and a few more things.

Carter-



  1. WEEK 11
    1. Classwork (7/14)
      • LINK    last week's class files
    2. Homework:
      • Exercise 1:    This applied example is a class that creates functioning buttons entirely with code, and it's based on our work with the graphics class this week, and with the display from last week. We will create a new custom class that creates a rectangle. This method is similar to the methods that create the circle, ellipse and rounded-rectangle of this week's class exercise.

        1. This class declaration will have 4 functions within it.
          1. Constructor—The first function is the main function. We have seen this type function before for as many times as we have created classes. The primary function of the class is always the one that actually generates or constructs, puts all things together to form the class object.
          2. Button Creator—The next function creates our button object with all of its most obvious properties, including the 4 button states; however, this button is an empty object and will not yet contain any graphics.
          3. Rectangle Creator—This function creates the rectangle graphic that will be inserted into the button above. We will use the graphics class to do this as we did this week in class to create the face.
          4. Label Text Creator—The last function creates the text-field that will go inside the button so that there is something to read that tells us the name of the button and gives us an idea of what will happen when you click on it.
        2. We must begin by creating a folder for the files we will be working with today. For this one little homework project, simply create a folder for the work and name it whatever you like. We will NOT be putting the .as and .fla files in separate folders.
        3. Next, open up a new .as file and save it into your new folder as CreateRectBtn.as.
        4. We'll start our coding by declaring a few variables which we will use to define the appearance of our rectangular button. We will do this when we instantiate our CreateRectBtn class. The resulting button will have the 4 states we normally associate with buttons: UP, OVER, DOWN, and HIT. When complete with this class, all that will remain is a listener to be attached to the button that will activate some function of your choosing.

          1. package {

            1. import flash.display.*; /* allows access to all properties of the display class built-in to Flash. Remember, the asterisk allows us to be non-specific as to which aspects of the display class we will to import, but rather import ALL of them */
            2. import flash.text.*; /* allows access to all properties of the text class built-in to Flash. */
            3. import fl.motion.Color; /* allows access to all properties of the Color class built-in to Flash. */

            4. public class CreateRectBtn extends Sprite { /* this tells us that the custom class that we are now creating will build upon, or extend the capabilities of the Sprite class that is built-in to Flash. Recall that the Sprite class is very similar to the Movieclip class, only it does not contain any timeline information, and therefore cannot have any animation within it */

              1. private var _w:Number;
              2. private var _h:Number;
              3. private var _lineWt:Number;
              4. private var _col:uint;
              5. private var _txtCol:uint;
              6. private var _txt:String;

            5. }

          2. }

        5. Save the file above again into the correct directory. The name you give the file should be the SAME NAME as the NAME OF THE CLASS.
        6. You will notice that we have six private variables above. As we did in the past, the first character in all of our private variables is the underscore (_) character. This gives us a visual cue as to whether it is public or private later on. Also, recall, that the values of private variables may NOT be altered in the instance of the class that is created in the .fla file.
        7. The first variable is going to be for the width, the second is for the height, the third is for the height, the fourth is for the button color, the fifth is for the text color, and the sixth is for the actual text that will serve as a label for the button. Notice that it is typed as STRING.

        8. The next step, as you may recall, is to add the constructor function. After the name of the constructor function as we did for our music player a few weeks ago, we listed the variables that are necessary for beginning our button. In this case, we need all six. When them come inside the parentheses as they do below, we call them parameters. That means that our six class variables above, are equivalent to the parameters of the constructor function below. Note, however, that the parameter names do NOT have the underlines in front of the names:

          1. package {

            1. import flash.display.*;
            2. import flash.text.*;
            3. import fl.motion.Color;

            4. public class CreateRectBtn extends Sprite {

              1. private var _w:Number;
              2. private var _h:Number;
              3. private var _lineWt:Number;
              4. private var _col:uint;
              5. private var _txtCol:uint;
              6. private var _txt:String;

              7. public function CreateRectBtn(w:Number, h:Number, lineWt:Number, col:uint, txt:String, txtCol:uint){
              8. }
            5. }

          2. }

        9. The next step is to connect the parameters to the variables:

          1. package {

            1. import flash.display.*;
            2. import flash.text.*;
            3. import fl.motion.Color;

            4. public class CreateRectBtn extends Sprite {

              1. private var _w:Number;
              2. private var _h:Number;
              3. private var _lineWt:Number;
              4. private var _col:uint;
              5. private var _txtCol:uint;
              6. private var _txt:String;

              7. public function CreateRectBtn(w:Number, h:Number, lineWt:Number, col:uint, txt:String, txtCol:uint){
                1. _w = w;
                2. _h = h;
                3. _lineWt = lineWt;
                4. _col = col;
                5. _txt = txt;
                6. _txtCol = txtCol;
              8. }
            5. }

          2. }

        10. Since this is our constructor function, we should construct our object; and as this class is intended for the creation of a button, we will call on the simpleButton object that is built-in to Flash. Therefore, let us start that 2nd function. This 2nd function, goes directly below the closeing curly bracket of the first constructor function.
        11. As mentioned above, this function is to generate and create a button with all of its 4 parts, the up, over, down, and hit states. Notice here on the first line of the function code down below that the return value is SimpleButton.
        12. This function, therefore, has a primary job of creating the button states which primarily means determining the colors of the various button states. We will use what's known as the Color class to do this. It is a class like any other that we have used, such as the display or the graphics classes that are built-in to Flash.
        13. The method that we will be using to set the color is known as interpolateColor(). What this method does is find a color in the middle of two other colors. Given two colors, the method calculates a color that is in between the two provided. A third item in the function (its 3rd parameter) tells how close to one or the other colors that the new interpolated color should be.
        14. For example, if your two colors were black and white, and then the 3rd parameter were 0.5, the new interpolated color would be EXACTLY IN THE MIDDLE between the black and white. It would be a middle gray. If your 3rd parameter, however, were 0.1, then the new interpolated color would be closer to the 2nd color and be a very light gray as a result. If it were 0.9, it would be closer to the first and thus a very dark gray.

          1. private function createBtn():SimpleButton {
            1. var ovCol:uint = Color.interpolateColor();
            2. var dnCol:uint = Color.interpolateColor();
          2. }

        15. The variable ovCol is the variable that will hold the color for the OVER state of the button; and the variable dnCol is the variable that will hold the color for the DOWN state of the button.
        16. Okay, great, so we have the interpolateColor() methods above, but we don't have the colors yet. That is because we have to provide colors to the method so that it can determine the color in between:

          1. private function createBtn():SimpleButton {
            1. var ovCol:uint = Color.interpolateColor(_col, 0xFFFFFF);
            2. var dnCol:uint = Color.interpolateColor(_col, 0x000000);
          2. }

        17. Above, we have the two colors. In both, notice, we used the _col variable. This is the original variable up at the top that we declared as part of the class to contain the color of the button. So, there is going to be an as yet undetermined main color for the button.
        18. Notice above also that for the ovCol, the over color, that we are trying to find a color in between the original color (_col), and a new color, 0xFFFFFF, which is white. That means that for the over color we will have a lighter version of the original color.
        19. Similarly, for the dnCol, the down color, we are trying to find a color in between the original color (_col), and another new color, 0x000000, which is black. This means that for the down color we will have a darker version of the original color.

        20. Next, we have to add the 3rd parameter that I mentioned above to tell whether we want the new interpolated color to be closer to the original color, or closer to the new color added. If I wanted 50% of the original and 50% of the new color, exactly in the middle, I'd use the value of 0.5; however, I want it to be closer to the 2nd color (either white or black), so I'll use a value of 30% for the 3rd parameter, which would be 0.3.

          1. private function createBtn():SimpleButton {
            1. var ovCol:uint = Color.interpolateColor(_col, 0xFFFFFF, 0.3);
            2. var dnCol:uint = Color.interpolateColor(_col, 0x000000, 0.3);
          2. }

        21. The next thing we need to add is the line of code that actually creates the button object. However, since that entails using a rectangle graphic, the moment after we create the button object, we will have to call upon another function to do the job of creating the actual graphics:

          1. private function createBtn():SimpleButton {
            1. var ovCol:uint = Color.interpolateColor(_col, 0xFFFFFF, 0.3);
            2. var dnCol:uint = Color.interpolateColor(_col, 0x000000, 0.3);

            3. /* The line below creates the button object as an instance of SimpleButton */
            4. var btn:SimpleButton = new SimpleButton()

            5. /* The lines below, create the different states of the button. After the equal sign (=) it calls on our next function that does the work of actually creating the rectangle shape */
            6. btn.upState = createRect();
            7. btn.overState = createRect();
            8. btn.downState = createRect();

            9. /* The line below makes the HIT state the SAME as the OVER state of the button */
            10. btn.hitTestState = btn.upState;

            11. return btn;
          2. }

        22. Even though we're not quite finished with this function, let's move on to the third one. Now that we have the colors for the different states of the button, what we have left to do here is to actually create the graphics to fit into the different states. To do that we'll just draw a rectangle in our next function, the createRect() function. Notice here on the first line of the function that the return value is SHAPE. We then proceed, as we did in class this week, to use the graphics class to draw the rectangle and color it with code. This function should be typed directly below the curly bracket of the 2nd function.
          1. The first line creates the shape object:
            1. var rect:Shape = new Shape();
          2. The next line indicates what style of line we are using. If you recall from class this week, this can take 3 parameters. These parameters indicate the line-weight (thickness), the color of the line, and the alpha value of the line. If there is no alpha value stated, the default value is 100%, or 1.0.
            1. rect.graphics.lineStyle(_lineWt, _col);
          3. The variable above, _lineWt, will have a numerical value to determine the thickness of the outline; and the variable, _col is the original color.
          4. The next line of code determines the fill color as we learned in class this week. It has two parameters, the color value and then the alpha value. So, what we have is the original color set to an alpha of 50% (0.5):
            1. rect.graphics.beginFill(col, 0.5);
          5. We then must actually draw the rectangle. We didn't use this method in class, but used similar ones, the rounded-rectangle, the ellipse, and the circle. The logic is the same. It takes 4 parameters: The first two numbers are the x/y coordinates, and the 2nd 2 numbers are the width and the height.
            1. rect.graphics.drawRect(0, 0, _w, _h);
          6. The next line ends the fill as we saw this week in class. It is a method that must be started and then stopped when desired:
            1. rect.graphics.endFill();
          7. The last line returns a value. This is the same thing that we saw back when we were doing the music player, but then we just returned numbers or text, numerical and string values. In this case, we are returning an object, an entire rectangle shape.
            1. return rect;
          8. Therefore, what we end up with is a shape with both an outline and a fill, and that is sent back to the previous function that we were working on:

          1. private function createRect(col:uint):Shape {
            1. var rect:Shape = new Shape();
            2. rect.graphics.lineStyle(_lineWt, _col);
            3. rect.graphics.beginFill(col, 0.5);
            4. rect.graphics.drawRect(0, 0, _w, _h);
            5. rect.graphics.endFill();
            6. return rect;
          2. }

        23. Now that we have the shape of the button drawn, let's return to the previous function. Its job is to create the button object with all of its 4 states. It also sets the colors of those states using the interpolateColor() method. What we haven't done is put those two things together: when creating the different states of the buttons, we haven't told the function which color should be used for which button state:

          1. private function createBtn():SimpleButton {
            1. var ovCol:uint = Color.interpolateColor(_col, 0xFFFFFF, 0.3);
            2. var dnCol:uint = Color.interpolateColor(_col, 0x000000, 0.3);

            3. var btn:SimpleButton = new SimpleButton()

            4. btn.upState = createRect(_col);
            5. btn.overState = createRect(ovCol);
            6. btn.downState = createRect(dnCol);
            7. btn.hitTestState = btn.upState;

            8. return btn;
          2. }

        24. So we have our first three functions almost completely done, but not quite: our constructor function, remember, is missing a few things. Recall, what we have done in that function so far is only declare our variables. This means we have only stated their names and what kind of variables they will be, such as numerical or string variables. We haven't constructed anything yet, and that's just what a constructor function should do. In truth, it should just trigger the beginning of the construction of the buttons in this case; and there are two things that it needs to trigger:
          1. The construction of the rectangular button; and
          2. The construction of a text box that goes inside that button.
        25. To handle the first of the two above tasks, we will simply call on our createBtn() function:
          1. var btn:SimpleButton = createBtn();
        26. The following is what this one line of code does:
          1. It creates a variable (var btn) which we've given the name of btn.
          2. Next, we have typed that variable as a SimpleButton, not as a String nor as a Number nor an integer, but as a simple button object (var btn:SimpleButton).
          3. The last piece in that line is to trigger our function, createBtn().
          4. What happens next is that declaring that variable activates, our createBtn() function. That function then goes to work to create the rectangular button.
          5. When it is done, it returns a value; but in this case, as mentioned, it returns NOT a simple value but an entire object, a button object.
          6. This completed button object then gets put inside the btn variable.
          7. This means that btn is the name of our simple button.
        27. After that, we have to add it as a child object onto the stage:
          1. var btn:SimpleButton = createBtn();
          2. addChild(btn);
        28. With our button complete, we now have to create a text field. A text field is a built-in object in ActionScript, so we just type our variable as a TextField.
          1. var txt:TextField
        29. In order to create this text field, however, we have to call upon another function, a function we have NOT yet created. Let's call it createTxt():
          1. var txt:TextField = createTxt();
        30. Like the button object above, we also have to add the text field object to the stage as a child:
          1. var txt:TextField = createTxt();
          2. addChild(txt);
        31. We will also add one last line to this function, and that is to make it so that it is NOT accessible to the mouse. What this means is that we don't want it clickable or selectable. The user will not be editing the text, neither adding to it nor subtracting from it. We don't want the user to interact with it at all, other than simply reading it as the name of the button. This is important because if this step is not taken, the cursor wil change to the I-beam text editing cursor when you mouse over the button. Moreover, the button will NOT be clickable where covered by the text field if we do not disable it:
          1. var txt:TextField = createTxt();
          2. addChild(txt);
          3. txt.mouseEnabled = false;
        32. The completed constructor function now looks like this:

          1. public function CreateRectBtn(w:Number, h:Number, lineWt:Number, col:uint, txt:String, txtCol:uint){
            1. _w = w;
            2. _h = h;
            3. _lineWt = lineWt;
            4. _col = col;
            5. _txt = txt;
            6. _txtCol = txtCol;

            7. var btn:SimpleButton = createBtn();
            8. addChild(btn);
            9. var tField:TextField = createTxt();
            10. addChild(tField);
            11. tField.mouseEnabled = false;
          2. }


        33. Finally, we must create the 4th and final function. As mentioned above in number 29 above, this is the createTxt() function that we call when we must create our text field for the button. Basically, it just goes about formatting a text field the same way we would do in the Properties panel. We start out by creating a TextField object. We follow that by creating a TextFormat object. Notice in the first line of code below that the return value is the whole text field.

          1. private function createTxt():TextField {
            1. var tField:TextField = new TextField();
            2. var format:TextFormat = new TextFormat();
          2. }

        34. Now, we give the text field a width and a height:

          1. private function createTxt():TextField {
            1. var tField:TextField = new TextField();
            2. tField.width = _w;
            3. tField.height = _h;

            4. var format:TextFormat = new TextFormat();
          2. }

        35. Next, we must format the text field with a font, a color, a font-size, a font-weight, and an alignment:

          1. private function createTxt():TextField {
            1. var tField:TextField = new TextField();
            2. tField.width = _w;
            3. tField.height = _h;

            4. var format:TextFormat = new TextFormat();
            5. format.font = "Verdana";
            6. format.color = _txtCol;
            7. format.size = 10;
            8. format.bold = true;
            9. format.align = TextFormatAlign.CENTER;
          2. }

        36. Now, we must apply our formatting instructions that are inside our format variable to our text field:

          1. private function createTxt():TextField {
            1. var tField:TextField = new TextField();
            2. tField.width = _w;
            3. tField.height = _h;

            4. var format:TextFormat = new TextFormat();
            5. format.font = "Verdana";
            6. format.color = _txtCol;
            7. format.size = 10;
            8. format.bold = true;
            9. format.align = TextFormatAlign.CENTER;

            10. tField.defaultTextFormat = format;
          2. }

        37. After that, we must put some actual text into the text field. To do that, we use the _txt variable that we declared at the beginning of this exercise. We will also prevent the user from selecting the text:

          1. private function createTxt():TextField {
            1. var tField:TextField = new TextField();
            2. tField.width = _w;
            3. tField.height = _h;

            4. var format:TextFormat = new TextFormat();
            5. format.font = "Verdana";
            6. format.color = _txtCol;
            7. format.size = 10;
            8. format.bold = true;
            9. format.align = TextFormatAlign.CENTER;

            10. tField.defaultTextFormat = format;
            11. tField.text = _txt;
            12. tField.selectable = false;

            13. return tField;
          2. }

        38. Excellent, we have completed the class for our use, which will be, first, to create a single button on the stage of an .fla file, and then, second, to create a series of buttons. So, make sure you save this file one last time, and then open up a new .fla file named button_test.fla. Make sure you save this into the same directory as the .as file this time. Doing this means we do not have to type anything into the document class space in the properties panel.
        39. In this new file, let's first create our button object instances:
          1. var btn:Sprite = new CreateRectBtn();
          2. addChild(btn);

        40. This is great, but you'll get errors if you try to save and test the movie. First, you should notice that the new object that we are creating is an instance of our the object that our class creates. How do you know that? Well, look at the first line and notice that the new object we are creating has the same name as our class, CreateRectBtn().
        41. Also, if you look back at your class definition file (the .as file), you'll see that there are six parameters in the constructor function: the width, the height, the line weight, the color, the text, and the text color. That means, we must put values between the parentheses of our object that coorespond to those 6 parameters, and we must make certain that we put them in the correct order:

          1. var btn:Sprite = new CreateRectBtn(90, 20, 2, 0x0066CC, "Play", 0x000000);
          2. addChild(btn);

        42. Those numbers mean that the width will be 90, the height will be 20, the line-weight of the stroke will be 2, the color will be 0x0066cc (a light blue), the text for the button will read Play, and that the color of the text will be 0x000000 (black).
        43. You can save and test this file if you like. If you typed all the code correctly, you'll see a single small blue button on the stage, but it will not have any functionality yet. In order to give it some, we have to add a listener and give it something to do. Let's start with a listener:

          1. var btn:Sprite = new CreateRectBtn(90, 20, 2, 0x0066CC, "Play", 0x000000);
          2. addChild(btn);

          3. btn.addEventListener(MouseEvent.CLICK, traceIt);

        44. Now let's add the function. From the listener you can probably surmise that the name of the function is traceIt, and that should also give you a good idea of what it's going to do:

          1. var btn:Sprite = new CreateRectBtn(90, 20, 2, 0x0066CC, "Play", 0x000000);
          2. addChild(btn);

          3. btn.addEventListener(MouseEvent.CLICK, traceIt);
          4. function traceIt(evt:MouseEvent):void {
            1. trace("click");
          5. }

        45. Great! Now that the button is there on the stage AND it also works, let's put 4 more onto the stage. To do that, all we need is a for-loop that loops around 5 times:

          1. for (var i:int = 0; i < 5; i++) {
            1. var btn:Sprite = new CreateRectBtn(90, 20, 2, 0x0066CC, "Play", 0x000000);
            2. addChild(btn);

            3. btn.addEventListener(MouseEvent.CLICK, traceIt);
          2. }

          3. function traceIt(evt:MouseEvent):void {
            1. trace("click");
          4. }

        46. Almost done, but if you tested the above file and it functioned, you don't get five buttons, you get one larger button...What really happened is that the five buttons are sort of on top of each other, so we have to separate them and position them horizontally with space in between. To do that, we will use the var i from the loop. Remember, this starts at 0 and counts up to 5.
        47. We canuse that number and multiply it times the width of the button. This means that for the first time throught the loop we will get 0 X 80, where the zero is the i value, and 80 is the width of the button. This comes out to 0, because anything multiplied by 0 results in 0!!
        48. If we use that as the X position, the first button will be positioned along the left margin at the zero position. Then, the 2nd time through the loop, we will get 1 X 80, where i now has a value of 1 and the width of course is still 80. This results in a value of 80, so the 2nd button will now be positioned at 80 in the X direction, directly to the right of the first.
        49. For the 3rd time through the loop, we will get 2 X 80, then the 4th time, 3 X 80, and the 5th time, 4 X 80. With each loop the buttons move over 80 pixels to the right. Great, so they'll line up side-by-side.

          1. for (var i:int = 0; i < 5; i++) {
            1. var btn:Sprite = new CreateRectBtn(90, 20, 2, 0x0066CC, "Play", 0x000000);
            2. addChild(btn);
            3. btn.x = i * btn.width;

            4. btn.addEventListener(MouseEvent.CLICK, traceIt);
          2. }

          3. function traceIt(evt:MouseEvent):void {
            1. trace("click");
          4. }
        50. And lastly, if you want to put space between the buttons, then simply add five pixels to the width:

          1. for (var i:int = 0; i < 5; i++) {
            1. var btn:Sprite = new CreateRectBtn(90, 20, 2, 0x0066CC, "Play", 0x000000);
            2. addChild(btn);
            3. btn.x = i * (btn.width + 5);

            4. btn.addEventListener(MouseEvent.CLICK, traceIt);
          2. }

          3. function traceIt(evt:MouseEvent):void {
            1. trace("click");
          4. }










No comments:

Post a Comment