View Full Version : FAO Glos - Flash Help!
John
21st January 2007, 20:16
Hi Glos,
I wonder if you can help me. I'm trying to load an exported movieclip using the attachMovie method, but for some reason it just doesn't seem to be working.
Here is my code - you can ignore everything else except what's in bold:
function processXMLData(success)
{
if (success)
{
var rootNode=this.firstChild;
var titleNode=findNode(rootNode, "title");
title=getValue(titleNode);
}
else
{
title="Denied";
}
barName = "bar1";
this.Frame.attachMovie("barStick", barName, this.Frame.getNextHighestDepth());
this.Frame[barName]._height = 400;
this.Frame[barName]._x = 1;
this.Frame[barName]._y = 100;
}
//Ignore this function
function findNode(node, nodeName)
{
if (node.nodeName==nodeName)
return node;
for (var i=0; node.childNodes && i
{
var foundNode=findNode(node.childNodes[i], nodeName);
if (foundNode!=null)
return foundNode;
}
return null;
}
//Ignore this function
function getValue(node)
{
if (node && node.firstChild)
return node.firstChild.nodeValue;
return "";
}
//LoadXMLData
var xmlData = new XML();
xmlData.ignoreWhite = true;
xmlData.onLoad=processXMLData;
xmlData.load("example.xml");
stop();I've basically exported the movieclip but I just can't get it to appear on the stage when I run this... I wondered if have you any ideas why?
Thanks very much!
GlosRFC
21st January 2007, 21:46
Can you post your fla? And also what version of AS you're using - AS1 or AS2? I suspect it's AS1.
The code you've posted has a syntax error
for (var i=0; node.childNodes && i
A for loop requires three items:
the initial state, e.g. var i=0
a condition to check against, e.g. node.childNodes && i
and then finally a step, e.g. i++
The for loop must also be enclosed in brackets ()
So in your example, the for loop begins by setting the variable i to 1. It then checks to see if node.childNodes AND i are the same. If they are both equal to 1 it will then execute the statement contained in the curly brackets. If they're not, it will apply the increment and check again. But in your code there is no increment so the for loop is continually checking against the same statement and it won't break out.
As far as the bold code is concerned it looks okay initially but it won't run at all unless the function processXMLData evaluates successfully. I think this (allied to the for loop syntax error) is the primary reason why it's not working.
I'm also assuming that you're using Flash Player 7 or higher because the attachMovie.getNextHighestDepth method won't work in previous versions. Again, this could stop it working if you're targetting earlier versions of the player.
You also seem to be using linkage to an object in your library? If so, then the syntax is fine. Frame is also an instance name? Again, I'm guessing so because there is no method or property called Frame unless it's one you've defined yourself. So you might also want to trace the values of the expression Frame[barname] to see that the output is correctly evaluating to what you expect. In other words, do you actually have an instance called Framebar1? If you don't, then don't expect anything to be displayed.
Hope that helps.
John
21st January 2007, 23:25
Thanks for your reply Glos.
I'm a little bit confused as to what you say about me having instance names, as there aren't any instance names defined in my FLA (not that you were to know that). I have a layer called "Frame" and a layer called "Layer 1", so the line "this.Frame..." refers to such.
I think I'm using AS 2.0, but I'm not absolutely sure... I'm using Flash Studio 8.0.
As for the FOR loop - I have a feeling, for some bizarre reason, it got pasted wrongly here, and is constructed as you have described in your post. I'll paste the code again below so you can see what I mean.
Edit - I've deleted the code from here - it isn't pasting the FOR loop properly.
Oh yeah, I have a movieclip called "barTemplate" in my library, which has linkage to an identifier named "barStick".
I have a feeling having described all this that it makes it even more difficult to figure out! Attached is the FLA file, I'm trying to pull data from the XML file as you can see (which works), so I'll post that too.
Thanks again for your help.
GlosRFC
21st January 2007, 23:51
Okay...I can see a problem straight off as you can't target layers! You can only target instances that appear in your library or on your stage.
GlosRFC
22nd January 2007, 00:15
I've had a look at your fla and you're running AS2 (you can check which version by looking in your Publish settings or checking the Properties Inspector window of your movie clip). And I see that you have included two components so getNextHighestDepth probably won't - you have to use the Depth Manager class for these.
It also seems to be reading the initial XML node fine. If I delete the XML file I get "Denied" in the textbox as per your code. If I reinstall the XML I get "Testing" which is the Title element in the XML file.
So it all seems to be working fine but it can't target Framebar1 because it doesn't know what "Frame" is. In your Actionscript Editor window you can target instances by clicking on the third symbol from the left which looks like a rifle scope sight. This opens another window showing you all of the existing library instances that are on your stage and what name you've given them. The only two instances that appear are the textbox and the movieclip Flash. Neither of these have been given an instance name. Note that an instance name in Flash is different from giving the object a name in your library. For example, you can have one object called John but 3 copies of it on your stage with instance names John1, John2, and John3. This means that you reduce filesize because there is only one "real" object that exists, yet you can still reference them individually.
The barTemplate follows this example but, because it doesn't technically exist as it's not on your stage, it's given an instance name "barStick" via a linkage method instead.
I'm not sure what your code is trying to achieve - is it some kind of barchart that should appear beneath the textbox? If so, you probably need to target the movieclip Flash. However, if I trace the output of this.Flash[barName] it comes up with undefined which tells me that Flashbar1 isn't being attached successfully.
I'll explain what *should* be happening with your attachmovie command:
It starts be looking for the movie that you want to attach. In this case, it's looking for a movie with the instance name of "barStick". This is actually the symbol in your library called barTemplate which has the linkage identifier "barStick". It then gives this movie a unique instance name, in this case the value of barName, which is "bar1". It then adds this to the next highest depth of your movie. Ordinarily it will simply place this movie at the 0,0 coordinates so the following code tells it to move the newly attached instance to a different position, an x value of 1 and a y value of 100. It also resizes the movieclip so that it's 400 pixels in height.
Now barName is a static variable so the contents never change - it will always be called "bar1". So if you're trying to create movies that draw a barchart, it won't work - every attached movieclip must have a unique name otherwise they'll simply be overwritten.
John
22nd January 2007, 00:37
Thanks once again Glos, I'll have a look at it again tomorrow as it's starting to make my brain hurt and I've got an early start tomorrow.
I'll try what you have suggested and give each element an instance name, referencing it correctly, and try and make the movieclip 'Flash' appear that way. Bit of a confusing name too, which I will change, although this is only a bare-bones test for the real thing I'm about to make... (yep, a complete bar chart).
Thanks again!
GlosRFC
22nd January 2007, 00:47
Flash uses a concept called "instantiation" in order to be more efficient. But what does instantiation actually mean? Quite simply, it's a way of creating multiple instances of a single object, such that each one can be controlled individually.
When you use Flash for the first time this can appear complex but it's relatively simple. When you create a movieclip it appears in your Library with a name. Flash defaults to calling them Symbol1, Symbol2, and so on but you can give them almost any name you want, so long as it's not a reserved Flash word.
So let's assume that you have created a movieclip symbol which you call John. It doesn't really matter what the symbol is, or what it's called, but it now exists in your library. But the symbol won't appear until you drag an instance of it onto your stage. If you do this and test your movie you will now see that your movieclip appears. That's all well and good, but what if you want another copy of John to appear later in your movie? You could draw an identical symbol and call it Mathare but this would actually increase the size of the Flash file. It's also makes your Flash file more complicated as you have to remember whether you should be using the symbol called John or editing the symbol called Mathare. So it would make much more sense to reuse the symbol John as much as possible.
And that's where instantiation comes in. Say you copy the symbol John onto your stage twice but now you want one of the Johns to grow in size? How do you tell Flash which one to target? If you look in the Property Inspector window you will see an item called Instance Name and therein lies the secret. Highlight one John symbol and give it the instance name Mathare. Then highlight the other John symbol and give it the instance name Vegy.
Now you can use Actionscript to target the two different instances. For example, to make the Mathare instance double in size, you would issue the Actionscript code:
Mathare._height = _height * 2;
Mathare._width = _width * 2;
To make Vegy shrink you would use:
Vegy._height = _height / 2;
Vegy._width = _width / 2;
The Mathare symbol will grow and the Vegy symbol will appear to shrink. But they are both instances of the same library symbol called John! By giving them different instance names, you're telling Flash to treat them as different entities, which means that you can now target them properly.
Instantiation can also be used on symbols that don't exist on the stage. To do this you have to apply an actionscript linkage by again giving it a unique name. So if you want to use a symbol from your library called Susanwells, you would give it a linkage name such as Piggy. Flash will now know to load the symbol Susanwells into memory and you can then target it in a similar method to that shown above, e.g.
Piggy._height = _height * 10;
Although I've given the symbols different instance names, there's also no reason why they can't be the same - so long as each individual instance that you create has a different name. I find it useful to give all symbols in my library a name that I find easy to understand. Then, if I'm only creating a single instance, I will give it the same instance name. So I will have a John in my library and place an instance on stage that I will also call John. But, if I know that I'm going to be using multiple instances of the same symbol, I will give them names such as John1, John2, John3, etc. Appending numbers to the instance names also makes it a lot easier for targetting purposes. For example, I can use a simple loop to create however many Johns that I want to appear on the stage.
Hope that's useful for you John.
John
22nd January 2007, 01:09
Very much so Glos! :D Big, big thanks to you.
I've closed the Flash stuff down now but tomorrow I'll definitely have a play with creating several instances of the same movieclip and changing their properties independently.
Let's say though, I have a bar chart measuring the highest temperatures for each month of the year. Is it just a case of creating 12 instances of one movieclip on the stage, feeding the XML values in, provided movieclip has a different instance name? E.g. mc_jan, mc_feb, mc_mar, etc?
I'm struggling with how to get Flash to adjust the height of a movieclip based on a particular value in the XML file, that's the only thing, really, that I need to get my head around before I can duplicate this for each entry in the bar chart... if that makes sense... so that each entry is displayed accordingly... but that's the bit that I'll have fun with.
Anyhow, thanks once again Glos for posting the above, it's extremely helpful. :)
GlosRFC
22nd January 2007, 01:20
Yes, it really is as simple as that although you have two different ways of achieving the same effect. A good Flash coder will look for the most efficient method of the two.
You can have a single symbol that represents say one unit of your chart. You can then create however many instances of this symbol as you want and position them on stage accordingly. So if your data says 10 units, you create 10 instances and place them on the stage. Obviously, with this method, you also need to target each of their _x and _y properties so that they fit on top of each other. This method is easier if you only want to display a single item of data, say a bar for one individual month. You also know that the data points are always a given size.
The alternative method is similar to the way you've described. Again you have just the one library symbol and create 12 monthly instances. But this time you adjust the _height property according to your data for each of those months. This method would be better if you wanted to compare months side by side. It's also more efficient as you only have 12 instances on the stage. With the former method, you will have as many instances as you have data points.
Reading XML correctly is actually one of the most complicated things as Flash doesn't display any of the data until you tell it to. And if you can't see it, you don't know what it is or what it's called. So, if I were you, I'd put a lot of trace commands into your XML code so that it pops up in the Output Window - this makes it a lot easier to keep tabs on what's happening.
For an initial Flash project, you've bitten off quite a bit, so good luck with it.
P.S. I'll see if I can come up with something too. You want a barchart that shows 12 monthly results for two people, correct?
John
22nd January 2007, 20:57
Hi Glos,
Have replied to you by PM.
P.S. I'll see if I can come up with something too. You want a barchart that shows 12 monthly results for two people, correct?
That would actually be a grand example, yeah. :)
I'm trying to make attachMovie work as we speak... thinking of making a new FLA and starting afresh.
GlosRFC
23rd January 2007, 00:30
Just in case you didn't master the attachMovie command, here's a very quick example - it's in 2004MX format so you should be able to open it easily enough.
Strange that we can't upload zip files...damn webmaster is hopeless :splapme
GlosRFC
23rd January 2007, 01:13
Just having a play...random colours, calculation of max/min and median, etc. The data is read in as paired values from a text file, e.g.
January=28&February=43&March=30&April=60&May=44&June=30&July=18
&August=25&September=42&October=34&November=30&December=25
Roll over the columns to see the respective data. Refresh page to generate new colours.
http://www.pi.pwp.blueyonder.co.uk/test/barchart.html
John
23rd January 2007, 01:38
Now you're just showing off! :D
Very nice indeed, I'm slowly progressing with mine. I've got the data read in from the XML file (yay!) and have it displaying successfully (yay!) only Pete (my housemate) thought it would be a good idea that we used a circle rather than a square, so of course at present my bar chart is more like an oval chart, but it works and I'm getting more and more used to Flash coding again, with Pete's help.
As for your bar chart, I haven't a clue how you did the easing on the bars but it looks very funky indeed. Also not sure how you did the random colour effect, but again that looks rather flash, please do excuse the terrible pun.
I've been looking at your 'on MouseOver' effect on the bars, thinking you'd made loads of different movieclips for loads of different colours, before it struck me - you've used alpha tweens! Nice.
As for drawing things from your XML data such as the average (with red line) and the median etc, is that relatively simple to do?
Thanks for the attachMovie FLA - crystal clear on how that works now... I think. I'm still stumped as to why my other (now old) one isn't working but I don't have to worry about that any more!
GlosRFC
23rd January 2007, 01:39
And an XML-driven line chart. All the data is included within the XML file including all colours for lines and background, data min/max sizes, datasets and variable names.
http://www.pi.pwp.blueyonder.co.uk/test/linechart.html
I particularly like the results of this graph :D
GlosRFC
23rd January 2007, 02:03
Bar charts don't look very good when they're round...a pie chart does though :wink
The random colour effect is precisely that:
my_color = random(15000000);
color = new Color(mcBar);
color.setRGB(my_color);
As for the easing, there are a number of ways to achieve that, of which manually tweening is the most timeconsuming and processor-intensive. In this case it's just a formula that scales the movieclip between the minimum (0) and maximum (60) values and making the scaling progessively smaller each time until it coincides with the actual value.
And you're right - an alpha tween is calculated and applied to each bar in turn as you mouse over them.
As for the max/min/med values, those are simply formulas again. The data is stored in an array called values so you work out the length of the array first. This tells you how many items you have in the array. Then you loop through the array retrieving each value in turn. Next calculate if the value is greater than the maximum value that you've stored in memory. If it is, you replace the maximum with the current value.
You use the same technique for the minimum value but add in a check to see if the minimum value exists or not. Obviously you can't predeclare the minimum value using 0, for example, or none of your values would ever be less! At the same time you add all of the retrieved values together and then divide this by the number of items in the array - which you've already calculated. This is your average.
limit = _root.dummy.values.length;
for (a = 0; a < limit; a++) {
current_value = Number(_root.dummy.values[a]);
average_value += Number(_root.dummy.values[a]);
if (current_val > max_value) {
max_value = current_val;
}
if (min_value == undefined || current_value < min_value) {
min_value = current_value;
}
}
average_value /= limit;
No reason why the data stored in your array(s) can't be treated the same way.
The problem with your original attachMovie command is the targetting. Because you've tried to target a layer rather than an instance, Flash doesn't know what you're trying to do. It's even harder when you're dynamically adding instances to the stage using Actionscript as you don't have any visual reference you can refer to when you're editing your FLA. And neither is the targetting icon much use as it will only point to items that already exist. The best advice is to test your movie and then press CTRL+L as this will show you all of the objects on your stage including the depth and target path.
John
23rd January 2007, 03:09
Blimey! I think I'm actually making this harder for myself than it really is... I seem to be under a false illusion that things have to be complex in order to function, to work, to do their job properly... but a simple breaking down of the code makes it much easier to understand. One thing that is a brainteaser though is sometimes when I load up your bar chart, the first few bars are one colour and then there's a sudden change to another colour (e.g. five bars are green and then it jumps to purple) and yet sometimes I get a seamless blend all the way through.
Easing the bars is something I'll play around with when I reach that stage with mine... it can't be too difficult, can it? I'm sure Google will be my friend.
I'm pleased I understand your array bits too. It's a case of looking through the whole array of values, and checking to see if the current value you have is higher/lower than the max/min value you have... and then returning either your initial value you had, or a value from the array, dependant upon the calculations. I think. :)
You use the same technique for the minimum value but add in a check to see if the minimum value exists or not. Obviously you can't predeclare the minimum value using 0, for example, or none of your values would ever be less! What if you had negative values in your chart though, say for UK January weather temperatures? (:helper) I guess you could then predetermine a set value of 0, and then check whether this is less than the lowest value in the series. Would it then would work in much the same way as checking a maximum value would?
I'll remember to use that handy CTRL+L shortcut as of now, thanks for that. :)
Right then Glos, that's me done and dusted for another evening, so no rush in responding to my labyrinth of queries immediately. :wink Although before I go I'll point you to a Flash book I got myself recently:
http://www.amazon.co.uk/Foundation-ActionScript-Animation-Making-Things/dp/1590595181
It's come in handy for some fun stuff so far, not really related to what I'm doing here although it will come into good use for other things.
I know you love your Flash, but I really do appreciate the time you've spent going through and explaining things to me over the last couple of days, not to mention the little FLA you made me earlier, which helped massively, mainly for mental healing and personal proof that the attachMovie command does in fact work if you do it correctly (a note to self!) You've been a great help! :spinning
GlosRFC
23rd January 2007, 07:07
The colour coding isn't perfect but that's because I was lazy. Colour values in Flash are expressed in hexadecimal but, as you can see from my example, I've just used a random decimal value! That's why it appears to skip a few shades. But it works - as you say sometimes it's best if things aren't over-complicated.
I thought you might query negative numbers but you can't always guarantee that you'll get any. You mention January weather as an example but have we dropped below zero on any day so far this month? So if declare a variable, minimum_value = 0, and then tried to compare this with your dataset for the month so far, it will always return 0 - even if the actual minimum temperature has been 1 degree. By not declaring the variable to start with you ensure that it will be populated - with negative or positive numbers, whichever is the lowest - but, because the variable doesn't actually exist when it compares against the first value, you have to check to see if it's undefined.
The code example essentially says IF the minimum_value is EQUAL TO undefined OR the current_value is LESS THAN the minimum_value, then swap the minimum_value with the current_value.
If none of our conditions are met, then skip on to the next value in the array.
So as you can see, when we check our first value (whether that's -20 or +100), the minimum_value is undefined so the condition is satisfied and minimum_value is populated. When we next encounter a value which is lower (-21 or +99) the condition is satisfied again so the minimum_value is replaced.
Going back to your first comments about complexity, it's a lot easier to write out on paper what you want to achieve in a similar fashion. It's called pseudo-code and it really does help you understand your code, keeps it simple and easy to debug, and makes it more efficient and accurate in the long run. Why not try it with the graph SWF you're trying to create. Just write out every step that you want it to achieve in simple sentences - you can then amend/delete these sentences, and/or shuffle them around into the right order, before you convert them into AS code.
Looks like a good book. I've a few FoD ones myself that have proved useful. One that describes every aspect of Actionscript that you might like to consider is http://www.amazon.co.uk/ActionScript-Flash-MX-Definitive-Guide/dp/059600396X/sr=1-8/qid=1169530878/ref=sr_1_8/203-7024146-2486358?ie=UTF8&s=books which is THE guide to all of Actionscript's syntax for every conceivable command. And it's also worth checking out Keith Peter's website for a host of example experiments http://www.bit-101.com/
John
23rd January 2007, 22:48
Looks very good anyhow Glos, even if it ain't perfect!
I try to avoid using pseudo-code as I like to get down with the real stuff as soon as possible, but I'll give that a stab and see if I can translate it into ActionScript code any easier than I would if I just thought about things in my head.
There are some snippets of help in the book I got on colour and manipulating it so I'll have a look at that.
In order for me to use it as a guide and nothing more, would you be able to post the FLA files for the charts you created? I won't pinch your code but I just want to see how you have created certain elements, and I can play about with them and see the effects. Hope this isn't too big an ask. :)
Haven't touched any Flash tonight as I've a bad headache but I'll look at it again tomorrow.
Thanks again.
GlosRFC
24th January 2007, 18:57
Sure. PM an address and I'll send it along.
John
24th January 2007, 19:58
PM sent on its way.
Powered by vBulletin™ Version 4.0.5 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.