I am trying to load assets from an SWC into a SWF at compile time, in as3. I'm getting the information about which assets to load from a JSON file. I can do so statically, but when I try to define the names dynamically, I'm running into problems.
So for example I can do this:
onemech[+ tmpObj.id] = new mech3 as MovieClip;
And it loads the asset named mech3. But what I would like to be able to do is something like
var mechtype:String = "mech" + mechtypenumber;
onemech[+ tmpObj.id] = new mechtype as MovieClip;
Obviously, that doesn't work.
I looked around a bit and I found this here, which seems to be angling toward what I need, but I can't figure out how to apply what's said there to my specific situation.
For the record, I have control over both the JSON format and the naming schema within the asset SWC, if there's an easier solution there.
Thanks in advance for any assistance.
you just need something like this:
var s:Class = getDefinitionByName("Symbol") as Class;
addChild(new s());
Related
i am working on a project and i got stuck on this one thing, i got a bvh file with an animation which i put on a biped in 3dsmax then i export every frame in to a json file with the thee.js json exporter and then when it gets played i remove the old mesh and add a new one. This causes the model to upload multiple times, which ofcourse is not what i want.
I use the jsonloader and i wondered if there was a way to update only the geometry every frame? Also i made those seperate files because i dont use a skin and i dont have morphtargets because i use a bvh file in 3dsmax.
It would be awesome if someone could help me with this
Example: http://www.deschaatssport.nl/3dsportsvisualiser/versie3/?p=3# (press the play button)
Mathijs Jansen
Assuming your JSON exporter keeps the number and order of faces/vertices intact, you could do something like this:
Load the initial model as you do now
Set geometry.dynamic = true;
Load the rest of the JSON files with plain old AJAX (alternatively you could combine the frame JSON files to one file, whatever so you have access to all of them through your own code)
For each frame, loop the new frame vertex position array (found in the JSON for each frame) and overwrite the coordinates of your existing geometry vertices (geometry.vertices[i].x = myframevertices[i][0]; etc...)
Set geometry.verticesNeedUpdate = true; and render the frame.
Again I'm just assuming that each JSON file has the same amount and order of faces/vertices, and only the vertex positions change in each frame. I'm not completely sure if it works like that.
There has also been some (experimental?) work on BVH support with Three.js. You might have success searching around, I don't know if there is anything usable though. One related effort here: https://github.com/akjava/BVH-Motion-Creator
I have a question:
I have in Fla Library a object with the Class property like: com.tool.zoom linked to external as.
In timeline i call with:
mainApp.iniZoom("com.tool.zoom");
This fla is loaded in another FLA on I call iniZoom function.
It is posible? I get error 1007.
I hope you understand me, my english is not really good.
Thanks!
As I understand you, you are trying to instantiate a class exported from a FLA file. You select that object, do Export for Actionscript, and name class "com.tool.zoom", right? If so, you should use "new" clause like this:
var iniZoom:com.tool.zoom = new com.tool.zoom();
Obviously you need to have the AS file available at compile time.
Edit: given that you load the SWF, here is the solution that might work for you. Note you have to load all the classes you want to export from the SWF for your parent SWF to be available.
I am making an AS3 project in FB4. In our workflow, we have artists compile art into SWC files which the I then link as 'Referenced Libraries' in FB4.
Then I set the "Link Type" of the SWC files to "external" instead of merged into code. This should create SWFs corresponding to the SWC files in the output folder, right?
This doesn't seem to be the case. I am only seeing one SWF file: the main_app's.
I was trying to make it so that I can use a library manager to load the files dynamically.
I tried extracting the swfs manually, but it seems the main_app still compiles all the swcs to itself. I made sure the Link Type was set to external. The file size for the main_app between "external" and "merged to code" seem to be the same.
I've made a simple project in Flash Builder 4 and the only way I got the SWC->SWF happening is by creating a Flex Project instead of an ActionScript Project and selecting "Runtime shared library (RSL)" instead of "External". This is because the Flex framework have some classes that work out the loading of those libraries for you. It also automate the conversion (I should say extraction) process.
Now, if you don't want to create a Flex project just for this, you can extract the SWF yourself. The SWC file format is just a Zip containing a SWF and an XML file describing the content. You can then load dynamically this extracted SWF file using a Loader and setting the correct Application Domain. Here's a snippet of my sample project.
public class Web extends Sprite
{
public function Web()
{
//you will not be able to instantiate classes of your library until it's loaded
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest("library.swf"), new LoaderContext(false, ApplicationDomain.currentDomain));
}
protected function onLoadComplete(event:Event):void
{
//here you can create instances of classes defined in your library
new Asset();
}
}
You might think that's a pretty tedious job to unzip+copy every time your designers update the library. You could automate this process with a script or an Ant file. Unfortunately, unless I'm missing something, it looks like Flash Builder doesn't want you to extend your build process, so you will still need a bit of hand work or completely convert to Ant (or something similar) to build.
Good luck!
From the moment the SWC is added to your Library, you should be able to access the SWC's assets by directly calling their specific class names . There's no need to try to get a SWF and load it with the Loader class. This actually defeats the purpose of using a SWC in the first place!
Let's say that , in your SWC, you have a MovieClip with a class name of GraphicAsset, to create a new instance , you simply do this:
var mc:MovieClip = new GraphicAsset();
In FB4's folder structure , have a look at your SWC in the Referenced Libraries folder & check the default package, you should see a list of all your assets.
We have a very large SWF hosted in a website which is just a repository of hundreds of movies/symbols. We load this SWF at the beginning with the Loader class but then the client will access a very few of them at that moment.
Is it possible to tell the loader to download symbols only when they're needed? (as with applicationDomain.getDefinition(...)).
Thanks in advance.
Don't think so, you might need to load the whole swf before using getDefinition().
A workaround I can think of is splitting the swf into many different ones.
Either naming the swf's by the class they contain, or storing some swf filename/contained classes pairs in a text file/xml and using that to load resources by name.
Have a look at BulkLoader, it could save you some time.
If you're using the Flash IDE, I wrote a simple jsfl script that should make things
less tedious:
var doc = fl.getDocumentDOM();
var dir = 'file:///' + doc.path.substr(0,(doc.path.lastIndexOf('/')+1));
var lib = doc.library;
var code = 'var loader : BulkLoader = new BulkLoader("assets");\n';
var items = lib.items;
var iNum = items.length;
var path;
var name;
fl.outputPanel.clear();
for(var i = 0 ; i < iNum ; i++){
if(items[i].linkageExportForAS){
name = items[i].linkageClassName;
path = dir+name+'.swf';
items[i].exportSWF(path);
code += 'loader.add("'+(name+'.swf')+'", {id:"'+name+'"});\n';
}
}
fl.clipCopyString(code);
fl.outputPanel.trace('symbols exported as swfs, code is in your clipboard');
All it does is loops thought the library items, and for the symbols that are exported for actionscript, it exports a swf file(where the Class name is used as a filename), and generates a bulk-loader snippet.
Easiest way to get it into Flash is this:
Create a new Flash JavaScript
File (File > New > Flash
JavaScript File)
Paste the code
Save the file as ASSymbolsToFiles or something. It the file should
default to the Commands folder,
which means you could use it through
the Commands menu. You can also
set a keyboard shortcut, if needed.
The generated code might not be perfect, but it gives you an idea, and it should be readable enough for easy tweaks.
HTH,
George
You cannot load parts of a swf, however, you could generate several smaller swfs instead of the big one. For that to be doable you need to know how to include and exclude classes in swfs so you can build one or multiple base swfs that contain shared classes, and a whole bunch of 'extension' swfs that only contain a few classes and are using the shared classes from the base swfs.
This can be achieved by using the command-line options of mxmlc (the actionscript/mxml compiler shipped with the free flex sdk) -- I don't know if it is possible using the Flash IDE.
Of course this will make your loading a bit more complex, but it will save a lot of bandwidth.
I don't think that is possible. However you can use JSFL to export all symbols from your library to separate SWF file's.
To do this, save the following as "ExportSymbols.jsfl"
//prompt user for directory to export symbols to
var dir = fl.browseForFolderURL('Select export folder');
//get all the library items
var symbols = fl.getDocumentDOM().library.items;
for ( var i=0; i<symbols.length; i++ ) {
var symbol = symbols[i];
var name = symbol.name;
var linkageClassName = symbol.linkageClassName;
if ( linkageClassName != "" ) {
var filename = dir + "/" + linkageClassName + ".swf";
symbol.exportSWF(filename);
fl.trace("Exported '" + name + "' to '" + filename + "'");
}
}
Then, in Flash choose Command > Run Command... and browse to the ExportSymbols.jsfl file.
That script will prompt you for an export directory and then will export all symbols that have a linkageClassName specified as separate SWF files.
Hope that helps.
If it's just a repository of symbols, why don't split it?
Btw i'm sure that it is not possible, since to know where the symbol is (in bytes), you have to download the whole container.
I found it is very useful to load a swf into AS as class (what Embed metadata did). However, I am in trouble to do exact the same thing to content that is not load in compile-time (Loader and URLRequest). How can I do that?
If you want to load a specific class to instantiate it there are two ways. One is to use the getDefinitonByName() method and the other is to import the class normally from a SWC but excluding the SWC at compilation.
In both cases you need to make sure the SWF containing the class is loaded when you attempt to instantiate it.
Example:
1/ Create a library.fla with your assets
2/ Export library.swf (tick export .swc if you want to use the 2nd solution)
3/ In another document load library.swf
4/ When library .swf is loaded try :
var MyClass:Class = getDefintionByName("Ball");
var ball1:MovieClip = new MyClass();
var ball2:MovieClip = new MyClass();
If you want to use the SWC method just add the library.swc to your classpath and make sure you exclude it from you when you compile (just check your environnement's documentation, or let me know what you're running). Then proceed the same way as previously by preloading the library.swf before instantiating. The nice thing is that you will be able to write : new Ball(); transparently...