im trying to get a tree made from words users type in but am lost at the part where the text boxes have to be right next to each other even if different length words are typed in. If anyone can explain how i can do this i will be extremely grateful.
im trying to get a tree made from words users type in but am lost at the part where the text boxes have to be right next to each other even if different length words are typed in. If anyone can explain how i can do this i will be extremely grateful.
I think you're going to have to be a bit more specific, but maybe you could giving them all an autoSize property and then run a for loop on them and slide them over to the last text boxes position plus it's width?
You need to be a lot more specific, and probably show a diagram. Also for things like these use fixed-width fonts, and embed those to your textbox.
is this on the right lines? im not sure how to create a parameter for the previous box length and implement it on the current ones position..PHP Code:myTextField.autoSize = "left";
for (var i:int = 0; i < guestList.length(); i++)
{
var nameElement:XML = guestList[i];
var myTextField:TextField = new TextField();
addChild(myTextField);
myTextField.text = nameElement;
myTextField.x = i*myTextField.width;
myTextField.selectable = false;
myTextField.border = true;
myTextField.autoSize = TextFieldAutoSize.LEFT;
var myFormat:TextFormat = new TextFormat();
myFormat.color = 0xAA0000;
myFormat.size = 24;
myFormat.italic = true;
myTextField.setTextFormat(myFormat);
}
Almost...
Code:
var xloc:Number = 0;
var paddingBetweenTextFields:Number = 10;
for (var i:int = 0; i < guestList.length(); i++)
{
var nameElement:XML = guestList[i];
var myTextField:TextField = new TextField();
addChild(myTextField);
myTextField.text = nameElement;
myTextField.x = xloc;
myTextField.selectable = false;
myTextField.border = true;
myTextField.autoSize = TextFieldAutoSize.LEFT;
var myFormat:TextFormat = new TextFormat();
myFormat.color = 0xAA0000;
myFormat.size = 24;
myFormat.italic = true;
myTextField.setTextFormat(myFormat);
xloc += myTextField.width + paddingBetweenTextFields; // remove padding if you don't want gaps between textfields.
}
Ur an absolute legend ImprisonedPride, couldnt get round that in my head, not almost - exactly. Though now i think my idea has to be made solely in flash, xml is too hard.
If you can imagine a path, that is made from words, going from left to right. Each user can either add a word to the path OR split the path by putting an alternative word instead of the last word. That is the whole concept, i've put a jpg to demonstrate what it would look like.
Any idea on how I would do this in flash? maybe with arrays? :scared:
looks to me like a "binary tree" than an array.
Oh well, for every string( sentence or word), store it as an object which has two properties in the least....the string itself, and the parent id (array slot) of its parent. (you can also do dynamic nested arrays I guess, but that would get too complex at length). and store these objects in a 1d array.
Next loop through the array, for each object, draw the first object string, check its children count using the parent ids, and draw them and rotate them however you want, though make sure the rotation is relative to the parent. It would be easier if you know how many max branches are possible.
For the current object, if you know the angle you rotated it (let's say parent.rotation+(60/maxbranch)), you can find the next child's position with something like
childx = (parent_tb.width+15)*Math.cos(parent_tb.rotation*M ath.PI/180);
childy = (parent_tb.width+15)*Math.sin(parent_tb.rotation*M ath.PI/180);
Why!? XML makes this so much easier...
Just needs a little rotation put in there, and you probably need to compare the longest child (right or left) and make the start (sx) that width so they don't overlap. I'd do it but I gotta run to class. This should get you started though. :)Code:var xml:XML = new XML(<xml>
<starter>
<value>There once was a</value>
<right>
<value>dog that had no owner.</value>
</right>
<left>
<value>man called</value>
<left>
<value>Bob</value>
<left>
<value>who thought a lot.</value>
</left>
</left>
<right>
<value>tom who liked actionscript.</value>
</right>
</left>
</starter>
</xml>);
var sx:int = 0;
var sy:int = 200;
traverse(xml.starter, sx, sy);
function traverse(node:XMLList, sx:int, sy:int) {
var o:* = drawNode(node.value, sx, sy);
sx = o.x;
var paths:int = 0;
var d:MovieClip = new dot();
d.x = sx+2;
sx += 4 + d.width;
d.y = sy+8;
stage.addChild(d);
if (node.left.length() == 1) {
trace("Going left");
traverse(node.left, sx, sy-15);
paths++;
}
if (node.right.length() == 1) {
trace("Going right");
traverse(node.right, sx, sy+15);
paths++;
}
if (paths>0) {
d.gotoAndStop(1);
} else {
d.gotoAndStop(2);
}
}
function drawNode(t:String, x:int, y:int):* {
var txt:TextField = new TextField();
addChild(txt);
txt.text = t;
txt.y = y;
txt.x = x;
txt.selectable = false;
txt.autoSize = TextFieldAutoSize.LEFT;
var myFormat:TextFormat = new TextFormat();
myFormat.color = 0x000000;
myFormat.size = 8;
txt.setTextFormat(myFormat);
return {x:x+txt.width};
}
sry about the paranoid posting.. got a close deadline at hand, will try this out after my lecture, seems like u really know ur stuff. thx so much
my cs4 is wayyy to slow cant handle it so reinstalling cs3...
could you possibly explain whats going on in that code? is the xml being created within the flash file and stored in the same directory?
Also throws up an error.. 1180: Call to a possibly undefined method dot.. im really not sure where this code goes and how it works
replaced dot with MovieClip and seems to work, however don't know where to go from here.. need to make rotation, also input boxes at the end of each line for the actual words.. it also has to be never ending =0 . ImprisonedPride whats goin on?
This should be really self-explanatory... I had to load a custom xml in since you didn't supply yours. It should also be obvious that since you aren't looking to make micro adjustments to the code to lay out your own xml in a similar way. Keep your XML loading the way you had it... but like I did with this line:Code:var xml:XML = new XML(<xml>
<starter value="There once was a">
<right value="dog that">
<right value="bit the mailman">
<right value="that he">
<right value="ran away"/>
<left value="cried"/>
</right>
</right>
<left value="had no owner"></left>
</right>
<left value="man called">
<left value="Bob">
<left value="who thought a lot"/>
</left>
<right value="tom who liked">
<right value="actionscript"/>
<left value="to flirt with">
<right value="loose women"/>
<left value="complete strangers"/>
</left>
</right>
</left>
</starter>
</xml>);
var sx:int = 0;
var sy:int = 200;
traverse(xml.starter, sx, sy, 0);
function traverse(node:XMLList, sx:int, sy:int, ri:int) {
var o:* = drawNode(node.@value, sx, sy, ri);
sx = o.x;
sy = o.y;
var paths:int = 0;
if (node.left.length() == 1) {
traverse(node.left, sx, sy-7, ri-22.5);
paths++;
}
if (node.right.length() == 1) {
traverse(node.right, sx, sy+7, ri+22.5);
paths++;
}
}
function drawNode(t:String, x:int, y:int, r:int):* {
var font:Verdana8pt = new Verdana8pt();
var format:TextFormat = new TextFormat();
format.font = font.fontName;
format.color = 0x000000;
format.size = 8;
var label:TextField = new TextField();
label.embedFonts = true;
label.autoSize = TextFieldAutoSize.LEFT;
label.antiAliasType = AntiAliasType.ADVANCED;
label.defaultTextFormat = format;
label.text = t;
var nr:Number = (r+label.rotation) * (Math.PI/180);
var nx:Number = x + ((label.width + 5) * Math.cos(nr) );
var ny:Number = y + 7 + ((label.width + 5)* Math.sin(nr) );
label.rotation += r;
label.x = x;
label.y = y;
addChild(label);
return {x:nx, y:ny, r:nr};
}
you'll need to send the first string node of the sentence to the traverse function when the xml finishes loading. Also, Verdana8pt is the name of a libary-font object. Embedding fonts is essential to retaining the text post-rotation. You'll need to embed the font you want in the library, and replace "Verdana8pt" with the linkage class ID of that font object.Code:traverse(xml.starter, sx, sy, 0);
Example output:
http://i35.tinypic.com/axxy5f.png
This is great, i got it all working but have accross an even more difficult issue.. basically, im trying to put a textbox at the end of each extra xml path and allow that to input data into the right place inside the xml?
-Edit-
need an explanation as to what a node is, and what all of these variables are: (node:XMLList, sx:int, sy:int, ri:int)
trying to load that same xml from above in an external file.. it comes up with undefined property xmlPHP Code:var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, loadXML);
loader.load(new URLRequest("data.xml?cachebuster=" + new Date().getTime()));
function loadXML(e:Event):void
{
var xml:XML = new XML(e.target.data);
ParseBooks(xml);
}
function ParseBooks(Myguests:XML):void {
var guestList:XMLList = Myguests.guest.name;
var xloc:Number = 0;
var paddingBetweenTextFields:Number = 1;
}
var sx:int = 0;
var sy:int = 200;
traverse(xml.starter, sx, sy, 0);
function traverse(node:XMLList, sx:int, sy:int, ri:int) {
var o:* = drawNode(node.@value, sx, sy, ri);
sx = o.x;
sy = o.y;
var paths:int = 0;
if (node.left.length() == 1) {
traverse(node.left, sx, sy-7, ri-22.5);
paths++;
}
if (node.right.length() == 1) {
traverse(node.right, sx, sy+7, ri+22.5);
paths++;
}
}
function drawNode(t:String, x:int, y:int, r:int):* {
var font:Verdana8pt = new Verdana8pt();
var format:TextFormat = new TextFormat();
format.font = font.fontName;
format.color = 0x000000;
format.size = 8;
var label:TextField = new TextField();
label.embedFonts = true;
label.autoSize = TextFieldAutoSize.LEFT;
label.antiAliasType = AntiAliasType.ADVANCED;
label.defaultTextFormat = format;
label.text = t;
var nr:Number = (r+label.rotation) * (Math.PI/180);
var nx:Number = x + ((label.width + 5) * Math.cos(nr) );
var ny:Number = y + 7 + ((label.width + 5)* Math.sin(nr) );
label.rotation += r;
label.x = x;
label.y = y;
addChild(label);
return {x:nx, y:ny, r:nr};
}
The way you have it now, the xml var only exists within the scope of the loadXML function. Move it outside the function as a public variable.
yeh i tried that but it didnt know what e was anymore
-_- declare the var outside, not initialise it outside.
var xml:XML; //declare outside
...
...
function loadXML(e:Event):void
{
xml = new XML(e.target.data); //assign value to it
ParseBooks(xml);
}