rite, so I should do an addChild(LoadXML); and then LoadXML.name or something?
bigmac- 04-09-2008
Only if you want to get an error message... addChild adds display objects to the display list, so can only work with objects that descend from the DisplayObject class; that includes Sprite and MovieClip. To store a reference to the object, declare it as a variable:
var getxml:LoadXML = new LoadXML("mydata.xml");
fatbuoy1- 04-09-2008
Ah yes... so
var getXML:LoadXML = new LoadXML("portfolio.xml");
trace (getXML.portfolioData[0].title);
SHOULD work instead of giving me THIS error message?
TypeError: Error #1010: A term is undefined and has no properties.
at Untitled_fla::MainTimeline/frame1()
:D
bigmac- 04-09-2008
I would think that error message is fully expected. :D
But before getting to the error, I'll walk you through a debugging process on this message. When I get a message like this and don't know WHICH term is undefined, I start from the beginning. First, this:
var getXML:LoadXML = new LoadXML("portfolio.xml");
trace(getXML);
// Should yeild: [object LoadXML]
Then...
var getXML:LoadXML = new LoadXML("portfolio.xml");
trace(getXML.portfolioData);
// Should yeild: a blank line, which is the trace of an empty array
Then...
var getXML:LoadXML = new LoadXML("portfolio.xml");
trace(getXML.portfolioData[0]);
// Should result in an error, because the array has no contents so item[0] is undefined.
Why is the array empty? Becasue you're not waiting for the XML to load and parse before trying to access its contents. Remember that, it's an important step! So, remember how we made this loader object extend from EventDispatcher? We did that so that it could manage the XML object's loading and listeners, then just dispatch one event at the end of the elaborate XML load/parse process saying everything was finished. So, looking again at your basic class framework, it should flow like this:
public class LoadXML extends EventDispatcher
{
public var portfolioData:Array = new Array();
private var _externalXML:XML;
private var _loadURL:URLLoader;
// --------------------------------------------------
// Constructor
// --------------------------------------------------
public function LoadXML(xmlPath:String):void
{
var req:URLRequest = new URLRequest(xmlPath); // << Pass this in
_loadURL = new URLLoader();
_loadURL.load(req);
_loadURL.addEventListener(Event.COMPLETE, this.onXMLLoaded);
}
private function onXMLLoaded(evt:Event):void
{
_loadURL.removeEventListener(Event.COMPLETE, this.onXMLLoaded);
// PARSE XML DATA INTO MAIN DATA ARRAY
dispatchEvent(new Event(Event.COMPLETE));
}
}
You can then subscribe a listener to your LoadXML to find out when the load/parse process is finished and your data is ready for use.
fatbuoy1- 04-09-2008
would think that error message is fully expected.
Hah, I love how you just SEE these things!
Thanks, thats working now more or less, I say more or less because when I try
trace(getXML.portfolioData[0].slides[0].url);
It DOES give me the correct text, but it gives it four times... any ideas why?
fatbuoy1- 04-09-2008
How do you work out what classes you need to import at the beginning of the package? Like I'm trying to import the addChild() class, and I've tried
import flash.display.addChild;
import flash.display.DisplayObject.addChild;
import flash.display.DisplayObject;
and numerous other attempts but none of them work... how do you know the exact path?
bigmac- 04-09-2008
...Hang on there, professor. addChild() is a method of a class, NOT a class its self. You can't import a method, you need to import the class it pertains to. addChild() happens to be a member of the DisplayObjectContainer class, so is available on everything that extends from DisplayObjectContainer (including DisplayObject, InteractiveObject, Sprite, and MovieClip). Again, get in the habit of looking stuff up in Flash documentation... every page begins with a document header that spells out the property / method / class inheritance model. But I'm not sure what you're using addChild() on... post code blocks so I can follow along.
As for the redundant data issue, I'd have to see the full code in context (one line snippits are hard to place). However, I do remember that you hadn't flushing your data holder during a loop... so you may be compounding your data entires.
bigmac- 04-09-2008
Hah, I love how you just SEE these things!
LOL... yeah, the automatic assumption is that you're an ultra tech-dork who reads code like Shakespeare when you can "see" those things. However, truth be told it's just logic. Once your learn to rationalize logic flows, there isn't a whole lot of mystery in code. It's a lot like doing a crossword puzzle or playing Sadoku.
fatbuoy1- 04-09-2008
But I'm not sure what you're using addChild() on... post code blocks so I can follow along.
Ok, so I've got a class that creates my basic photo shape, Photo(), I have a class that loads the XML file and parses it into an array, and i'm going to make a class (called Image) that will take the appropriate array data, put it into a URLLoader and display the image.
What I want is a class (im calling it NewSlide) that will create an instance of Photo, place an instance of Image(with the right image) on top of it, and throw it onto the stage (so there will be an element of tweening).
So heres what I have so far for NewSlide. I guessed it should extend from the DisplayObjectContainer class?
package com.carmstrong.portfolio{
import com.carmstrong.portfolio.Photo;
import flash.display.DisplayObjectContainer;
public class NewSlide extends DisplayObjectContainer{
public var photo:Photo = new Photo();
// --------------------------------------------------
// Private members
// --------------------------------------------------
// --------------------------------------------------
// Constructor
// --------------------------------------------------
public function NewSlide():void {
super();
addChild(photo);
}
// --------------------------------------------------
// Init / uninit
// --------------------------------------------------
// --------------------------------------------------
// Event handlers
// --------------------------------------------------
}
}
Im just building it gradually, so the first step is to try and get it to create an instance of Photo(). However, this is giving me the error
ArgumentError: Error #2012: NewSlide class cannot be instantiated.
at Untitled_fla::MainTimeline/frame1()
fatbuoy1- 04-09-2008
get in the habit of looking stuff up in Flash documentation
Oh I have, its EXTREMELY helpful, surprisingly so! Its the first program help that I have ever actually found USEFUL.
Oh and btw, I read that Dont Make Me Think! book the other day (they had it in the uni library). Very interesting read, thanks :D
bigmac- 04-10-2008
Two things:
1) You need to be careful about extending from the lower-level DisplayObject Classes. DisplayObject and DisplayObjectContainer are base classes that provide a very raw framework for polymorphisms into the extended display classes like Sprite and MovieClip. You can't actually place a generic DisplayObject onto stage... it isn't evolved enough to BE displayed. So, for all intents and purposes the only two display classes that you should ever extend are Sprite and MovieClip... and the only reason to extend MovieClip is if you need the timeline.
2) Why don't you place the Image object directly within the Photo class and write all control scripts on Photo?
bigmac- 04-10-2008
I was working on something this morning that I thought you might find helpful as an example. We've had quite a bit of discussion about static versus instance classes... you seem to be getting the hang of using instances. So what is a static class? Here's an example (it's AS2)
import flash.external.ExternalInterface;
import com.threespot.wnyc01.data.JSInterface;
class com.threespot.wnyc01.options.ShareSites
{
public static var DIGG:String = "Digg";
public static var DELICIOUS:String = "Del.icio.us";
public static var REDDIT:String = "Reddit";
public static var FACEBOOK:String = "Facebook";
public static var NEWSVIEW:String = "Newsvine";
public static var TECHNORATI:String = "Technorati";
public static var STUMBLE:String = "Stumble";
public static var list:Array = new Array(DIGG, DELICIOUS, REDDIT, FACEBOOK, NEWSVIEW, STUMBLE);
public static function share(site:String, link:String, title:String):Void
{
var submit:String = "";
link = (link != undefined) ? link : "";
title = (title != undefined) ? title : "";
switch(site)
{
case DIGG:
submit = "http://digg.com/submit?phase=2&url="+link+"&title="+title;
//+"&bodytext="+shareDescription+"&topic=political_opinion";
break;
case DELICIOUS:
submit = "https://secure.del.icio.us/login?url="+link;
break;
case REDDIT:
submit = "http://reddit.com/submit?url="+link+"&title="+title;
break;
case FACEBOOK:
submit = "http://www.facebook.com/share.php?u="+link;
break;
case TECHNORATI:
submit = "http://www.technorati.com/search/"+link;
break;
case NEWSVIEW:
submit = "http://www.newsvine.com/_tools/seed?popoff=0&u="+link+"&h="+title;
break;
case STUMBLE:
submit = "http://www.stumbleupon.com/submit?url="+link+"&title="+title;
break;
default:
break;
}
if (submit == "")
{
return;
}
else if (ExternalInterface.available)
{
ExternalInterface.call(JSInterface.SHARE, submit);
}
else
{
getURL(submit, "_blank");
}
}
}
This is a class that manages a social networking "share" form... you know how a lot of news sites have sharing options that let you fire off a story into Facebook or Digg? Well, this is just a Flash utility I've put together to manage those submissions. The key word there was "utility". I don't need any instances of all this data, as it's not really a object per say that needs to exist within the program. It's just a collection of data about these sites and a utility method to control submission. So, everything here is static and available through the class to any other object within the application that wants to use it. Can you think of a static class that you use constantly? How about Math? You know how all math methods are called as "Math.round(x);", etc? That's because you're calling static methods of the Math class.
So, just keep this in mind. Static classes are a great way to organize methods that lots of different objects will share.
fatbuoy1- 04-10-2008
Why don't you place the Image object directly within the Photo class and write all control scripts on Photo?
I guess that would make sense, perhaps im trying to over-specialise my classes.
I take it my LoadXML class would be an example of a static class then? No visible presence as such, its just there to store data for other objects?
Whats it like going back to AS2?
bigmac- 04-10-2008
Why don't you place the Image object directly within the Photo class and write all control scripts on Photo?
I guess that would make sense, perhaps im trying to over-specialise my classes.
I take it my LoadXML class would be an example of a static class then? No visible presence as such, its just there to store data for other objects?
Whats it like going back to AS2?
No, your LoadXML is very much an instance class... You need to create an instance to handle the specific load operation, then add a listener to the instance to find out when it has finished. If you made your LoadXML a static utility class, then you could only have one load operation in effect at a time (because a second load operation would overwrite the first). Here's the big distinction: a Static class has no constructor. It doesn't need one because it is never instanced.
As for over-specializing your classes... actually, you're on the right track. That's not a bad idea. To separate the drawing of your photos from the dynamic motion of your photos is an excellent approach, and very sound OOP theory (which aims to compartmentalize common logic so that individual bugs and breaks will stay confined to a small area and not affect other unrelated aspects of the program). However, you're making a very elaborate composition if the motion control is an object that HAS a photo which HAS an image. The motion control should still apply directly to the photo, so create a new MotionSlide class that extends Photo. That will keep your photo script in tact, then just add another layer of logic onto it. It's kinda like layers of an onion... Your objects can grow with layer after layer of unique logic applied to them. In the case of the Lassie Room engine, I think the final Room class is built on top of ScrollControl > LayeringControl > FilterControl >Sprite.
As for going back to AS2? Painful. Particularly because of the absence of the EventDispatcher model. MovieClips are also a pain to work with. AS3 is substantially easier in a lot of ways, because all you have to learn is OOP theory. In AS2, you had to learn OOP theory along with all the exceptions where AS2 didn't follow the model. In that respect, you could think of learning AS2 like the difficulty of learning English (where you have to sort out "their", "there", and "they're"; etc.)
fatbuoy1- 04-10-2008
post code blocks so I can follow along.
Ok, so at the moment I have a LoadXML class to parse the XML data into an array.
package com.carmstrong.portfolio{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.URLLoader;
import flash.net.URLRequest;
public class LoadXML extends EventDispatcher {
public var portfolioData:Array=new Array ;
private var _externalXML:XML;
private var _loadURL:URLLoader;
// --------------------------------------------------
// Constructor
// --------------------------------------------------
public function LoadXML(xmlPath:String):void {
super();
var req:URLRequest=new URLRequest(xmlPath);
_loadURL = new URLLoader();
_loadURL.load(req);
_loadURL.addEventListener(Event.COMPLETE,onXMLLoaded);
}
// --------------------------------------------------
// Private methods
// --------------------------------------------------
// --------------------------------------------------
// Event handlers
// --------------------------------------------------
private function onXMLLoaded(evt:Event) {
_loadURL.removeEventListener(Event.COMPLETE, this.onXMLLoaded);
trace("XML Loaded");
var i:Number=0;
//Load list of example images
var xmlData=new XML(evt.target.data);
// specify a node name to read as a list
var projectList:XMLList=xmlData.project;
// Iterate through the list of image nodes
for each (var projectNode:XML in projectList) {
// extract each node's data
var t:String=projectNode.title;
var d:String=projectNode.description;
var slidesList:XMLList=projectNode.slides.slide;
var slidesData:Array=new Array ;
for each (var slidesNode:XML in slidesList) {
var u:String=slidesNode.url;
var st:String=slidesNode.title;
var c:String=slidesNode.caption;
slidesData.push({url:u,title:st,caption:c});
}
// Add data elements as a new Flash object in array
portfolioData.push({title:t,description:d,slides:slidesData});
dispatchEvent(new Event(Event.COMPLETE));
}
}
}
}
Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.