ActionScript: The Definitive Guide by Colin Moock Unconfirmed error reports are from readers. They have not yet been approved or disproved by the author or editor and represent solely the opinion of the reader. This page was updated July 25, 2007. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification UNCONFIRMED errors and comments from readers: (1) Paragraph 8 of Foreword; You've confused 'tantamount' (equivalent in effect) with 'paramount' (foremost in importance) {50} text under "Scenario 5"; Due to the order of execution of code across timelines, Scenario 5 requires three frames, not two. The text should read: Suppose we create a new movie with three keyframes. On frame 1, we place a clip instance, ball. On the ball timeline, we create a variable, radius. Frame 3 of our main timeline is blank (the ball instance is not present there). From frame 2 of the main movie timeline, we can find out the value of radius using this code: trace(ball.radius); Now the question: If we move that line of code from frame 2 to frame 3 of the main timeline, what appears in the Output window when our movie plays? Answer: Nothing appears. When the ball clip is removed from the main timeline on frame 3, all its variables are destroyed in the process. [134] last paragraph..last sentence; "...For more information on simulating arrays with set, see chapter 2." info on set() doesn't seem to be explained in chapter 2...?? [177] 2nd example, the Scope Chain: firstName = "christine"; function getName (firstName) { trace(firstName); } getName("Kathy"); When running this function in a movie clip, the output window should show the value "Kathy" replace "christine" as the value for the getName Function. So far, I've tried call the function from the same frame in the movie clip, and from the main timeline and the value in the output window is always "christine". ***Response from the book's editor:*** The author replies: "The reader is doing something wrong. In my opinion there's no error in the text." I've also tested the example in the book following the instructions as provided and have found no error. I concur that the reader must be doing something wrong. Most likely, the reader has omitted the firstName parameter from the function declaration, such as this: function getName () { trace(firstName); } In such a case, the function would display "Christine" in all cases because any parameter passed in would be ignored. If that isn't the cause of the reader's problem, maybe he has the function defined in multiple places or is testing the *movie* whereas he should be testing the *scene*. (210) example on top of the page; when tryin out the script it failed to do the duplicateMovieClip() function so had to change 2 things in order to get it working: 1. in the 4th last line of code the Number() function is startin with a lower-case instead of a capital: nextStarNumber = Number(_name.substring(4, _name.length)) + 1; 2. the movie clip instance name changed from star to star0 I can't tell if i was doing somethin wrong or if it was a typo from the book but with these changes i was able to get it working. {178} 6th Non-Code Paragraph and the Code that follows it.; The paragraph that begins with "In this situation..." attempts to offer a solution to the previous code that was "a misguided use of the scope chain." In the previous misguided code, the second comment ("// CODE ON clipA's TIMELINE") suggests that we are to put the _root.rotate() function invocation on a clip whose instance name is "clipA". However, in the "fixed" solution code that follows, the function invocation ("_root.rotate(clipA, 30);") would only work FROM THE MAIN TIMELINE, not from "ON clipA's TIMELINE", because clipA can only refer to itself by the absolute path "_root.clipA" or by the relative path "this". By excluding where the reader is suppose to place the "fixed" solution code, the author has misguided the reader (in my opinion) in this instance; which is a departure from the rather well written work that the reader has come to expect based on the author's previous 177 pages. If the "fixed" solution code was meant to be placed on the instance "clipA", then the code should have read: _root.rotate(_root.clipA, 30); or _root.rotate(this, 30); [188] 1st paragraph after the tip; Can you explain this paragraph a bit more? or maybe give me another example? I don't quite understand how "Function properties offer the benefits of local variables without expiring between function invocations" in that duplicate movie clip example. I tried replacing makeClip.count with just count: count=0; function makeClip(theClip) { count++; theClip.duplicateMovieClip(theClip._name+count, count); } makeClip(square); and it gives the same result. Any help would be appreciated with this. {226} The 2nd paragraph of code should read: onClipEvent (mouseUp) { this.buttonDown = false; this.gotoAndStop("up"); if (hitTest(_root._xmouse, _root._ymouse, true)) { this.gotoAndStop("over"); } updateAfterEvent(); } to behave correctly with multiple movieclips and to encounter drag out of mc 'button' ***Response from the book's author:*** There is no error in the code. The reader is expanding it to work in a more complex situation, which is great, but the code works in the single-button situation for which it's intended. {238} 2nd Paragraph beginning "When invoked with..."; The author states that when invoked with no arguments, push() appends an empty element to an array and is functionally eqivalent to array.length++ Tests show this not to be the case. An empty push() statement does NOT increase the length of the array whereas array.length++ DOES. (276) Example 12-9. Walking the Prototype Chain; In Example 12-9 (Walking the Prototype Chain), the line after the "objectInClass" function definition that reads: myObj = new Rectangle(); should be changed to: myRect = new Rectangle(); because the lines of code that follow this instanciation depend on an instance of the Rectangle class called "myRect", not "myObj". [294] The 1st bullet of the section titled "How clips generated via duplicateMovieClip() are added to the stack"; The book directly states that: "If the instance's seed clip was created manually (or was duplicated using duplicateMovieClip() from a clip that was created manually), then the new instance is placed in the stack above _root." This is only the case when the seed clip is a movie clip who's _parent is _root. If the seed clip is a movie clip nested within another movie clip, then this quoted logic fails because the objects on the _root level that are in higher layers would obscure the duplicated inner movie clips. An example: 1) Make a 2 layer Flash piece. 2) In the top layer, draw a square. 3) In the bottom layer, draw a square that is lower and to the right of the previous square such that the top layer square's lower- right corner and the bottom layer square's upper-left corner overlap. 4) Select the bottom layer's square that you just drew and press F8 then Enter (in that order) twice in order to make a movie clip that is nested within a movie clip (the names of the movie clips are not important). 5) Double-click this outer movie clip instance in the bottom layer that you created in the previous step. Then right click the inner movie clip and select "Actions" from the contextual menu that pops up to get into the Object Actions panel. 6) In the Object Actions panel, type the following: onClipEvent (load) { _root.i++; if (_root.i < 2) { this.duplicateMovieClip("duplicatedThis"+_root.i, _root.i); _parent["duplicatedThis"+_root.i]._x = this._x - 50; _parent["duplicatedThis"+_root.i]._y = this._y - 50; } } NOTE: It is not good practice to use _root.i++ without defining it as a number first, but I'm doing it here for the ease of implementing this example. 7) Press CTRL+ENTER to Test Movie (play this Flash piece). Notice how the square from the top layer still obscures the square in the bottom layer and ALSO OBSCURES (OVERLAPS) THE DUPLICATED MOVIE CLIP AS WELL. You will see that when the manually created seed clip (the inner movie clip) is duplicated using duplicateMovieClip(), the new instance is placed in the stack above _parent (NOT ALWAYS _root). {320} in the updateClock function, 4th line from the bottom; I think the divisor should be 12, not 24: was: hourHand._rotation = 360 * dayPercent + hourPercent * (360 / 24); should be: hourHand._rotation = 360 * dayPercent + hourPercent * (360 / 12); that's because the 360 degrees are spread amongst 12 hours on the clockface, not 24. this really is a fantastic book, very helpful. (320) Chapter 13: Movie Clips/Applied Movie Clip Examples/ Building a clock with clips/End of page, in the function updateClock(); In the function updateClock(), the _rotation property of the hourHand movie clip is set like this: hourHand._rotation = 360 * dayPercent + hourPercent * ( 360 / 24 ) ; Since the turn of a clock is divided into 12 hours (and not 24), shouldn't we have: hourHand._rotation = 360 * dayPercent + hourPercent * ( 360 / 12 ) ; instead of the assignment above? If I'm right, this error also appears page 322. {359} second last code block; The second last code block reads: title._gotoAndPlay("fadeout"); No underscore is used before the gotoAndPlay() method. the text should read: title.gotoAndPlay("fadeout"); {347} Bitwise Operations Applied, Example 15-3, the line containing the code var hasCDplayer = (0<<1) should be var hasCDplayer = (1<<1) If zero is left shifted 1 bit, it is still zero, if 1 is shifted 1 bit, it becomes 2. The desired value is 2. I did not find this indicated on the errata page. [369] Chapter 16, Building a smart clip with a customised interface, Creating a custom interface .swf file; The explanation to create a custom interface are a little bit fuzzy. Wouldn't it be possible to insert a very simple example, so that the reader can understand the basics of how customised interfaces for smart clips work in practice? Yet the author sends us back to a sample in the code depot (The Playhead Control), this is perhaps a little bit impressive for the beginner. Furthermore, it is never specified that parameter values from the exchange clip (xch) can only be retrieved *after* the first frame of the swf interface (see Flash 5 Studio, 1st edition, Friends of ED, Chapter 2, page 80). [377] Example 17-1; I just found out that example 17-1 on page 377 didn't work for me because the perl source didn't produce the right header under win32 apache 1.3.22 . This shouldn't happen to an o'reilly book, because until today you had the status of a perl competence centre to me. I used the following echo.pl instead, which worked: ===========CUT==================== #!perl use CGI; $q = new CGI; $e = "output="; foreach $key ($q->param) { $value = $q->param($key); $e .= "$key:$value\n"; } chomp($e); print $q->header({"Content-Type"=>"application/x-www-urlform-encoded"}); print $e; ===========CUT==================== (427) line after separator bar; "Array.toString" should not be italicized. [473] last lines of 472/first of 473; I think this needs more explanation: [quote]: "Note that scenes are flattened into a single timeline during movie playback. That is, if scene 1's timeline contains 20 frames, and scene 2's timeline contains 10 frames, then we can send the playhead to frame 5 of scene 2 using gotoAndPlay(25); [end of quote] This works, I tried it. But when I use gotoAndPlay(_root.targetvar); on a frame in a scene between other scenes, and targetvar = 175, then the main timeline moves to frame 175 OF THAT SCENE and not to the 175th frame of that movie. (598) second line after second separator bar; There should not be a space in "get Version". [589] String.split() Method arguments description; Text is currently "The character or series of characters at which to break string when forming elements of an array." To comply with reality, the text should read "The character at which to break string when forming elements of an array." Consistent misbehaviour occurs with stringB.split(stringA) when stringA is more than one character - in that case, split() simply seems to return stringB instead of an array. For example: stringB = 'The split() method is broken as documented, orThe documentation is broken'; testArray = stringB.split(''); trace(testArray[0]); , where the trace() will return "The split() method is broken as documented, orThe documentation is broken". Minor syntax adjustments do not seem to matter. If '' is replaced with '@' or anything else unique to stringB, split() works as documented.