Better way to include images in AS3 than embed? - actionscript-3

I am putting together a Flash game (using Flixel) and I have a lot of sprites whose images (.png format, mostly) I need to include in my game. I'm used to using code like:
[Embed(source = "../../lib/ship-0001.png")]private var _ship0001Sprite:Class;
in order to include an image file. Is there a way I can do this other than embed? I'd like to use a for loop if possible, grabbing every needed file by number. This way instead if having several lines for each ship type (to grab its sprite, icon, store view, etc), I can just change a variable (eg NUM_SHIP_TYPES) and add the files by number for the new ship.
Is embed the only way to do this where the files are included in the .swf, or is there another way I can do this? Or is there a way I can use a for loop with embed?

This may not be a popular answer. But it depends on preferences. I'm not trying to start a best practices discussion, just listing a possibility.
If you have multiple images for each ship. And its the same number of images per each ships then the below could be a possibility. Of not, then completely ignore what I suggest.
Have a folder for each one of your ship types and then a class file within that folder and place your images within that folder along side the class files..
package shipimages.ship1 { class Ship1Images {
[Embed(source="0001.png")] public var img0001:Class;
[Embed(source="0002.png")] public var img0002:Class;
[Embed(source="0003.png")] public var img0003:Class;
} }
.
package shipimages.ship2 { class Ship2Images {
[Embed(source="0001.png")] public var img0001:Class;
[Embed(source="0002.png")] public var img0002:Class;
[Embed(source="0003.png")] public var img0003:Class;
} }
But as I said, this is only beneficial in a small case scenarios but it does mean everything is more sub divided and if you were to make an Interface it could be easily done for factory pattern.

If you have lots of assets, the best way is to leave them as external files and use Loader to load them.
That way you can display a progress bar and, as you said, it also makes it easier to manage your assets.

Do you want to have the objects readily available within the same swf or do you want to load them externally. Would be the first question, that comes to my mind.
If you want to embedd images inside the swf : Add them all in an fla, create a swc from it and use them in your project. When you want to change something, change the fla. Regenerate the swc. Recompile.
If you want the images to be loaded on runtime, use UrlLoader, personally I prefer using LoaderMax, which is part of the greensock package. It gives you more options to work with loading. Here is an example to help you out : http://www.greensock.com/loadermax-tips/

Related

Need some help getting started with OOD in ActionScript 3

So being new to AS3 but not development in general, during a recent project that I just started I hit an immediate snag where my normal method of OOD is causing errors in AS3.
I created a layer in Adobe Flash called code just to keep everything separate and in frame one under actions I used the following code to get started:
var GameContainerSize:int = 400;
class GameInfo {
var GameID:int;
var HomeTeam:String;
var VisitingTeam:String;
function GameInfo()
{
}
}
This simple code immediately causes an error though
Scene 1, Layer 'Code', Frame 1, Line 4 1131: Classes must not be nested.
And my best guess is this is because the timeline and all code on it exists within a class already. So what should I be doing if I want to develop this program using class objects, or is this even possible in flash?
You can't define classes on the timeline. Each timeline is exported as a class, var and function declarations become members of the class, and frame code is moved to its own frame functions which are called when the timeline reaches that frame. Thus the error is saying "you can't put a class in a class" because the timeline already is a class.
To define classes you must use external .as files with package blocks:
// GameInfo.as
package {
public class GameInfo {
public var GameID:int;
public var HomeTeam:String;
public var VisitingTeam:String;
public function GameInfo(){ }
}
}
In Flash Pro you can link a class to a timeline (document or symbols). Such a class must extend Sprite or MovieClip.
You can also refer to any of your classes from any frame script. For example, you could put on frame 1 of your main timeline:
var gameInfo:GameInfo = new GameInfo();
Typical OOP would involve using external .as class files for almost everything, with only minimal function calls on your timeline frames, like stop() at the end of a timeline or calling a custom function you've added to the class linked to the timeline.
I created a layer
That's not ideal. The problem is that it will not get you any closer to understanding the code, because it isn't code. It's a feature of the flash authoring environment. You might as well spend a day with the drawing tool drawing something.
to keep everything separate and in frame one under actions
Organisation is important, but layers aren't the way to go. As each class definition goes into its own external file, you have to create additional files anyway if you want to create more classes. And you want to create more classes because having only one is horrible object oriented design. Being consistent here is important. That's why people in the comments suggested to use a document class and have no code on any frames. All code is organised in classes. No exceptions1.
Having said all that, I highly advice against using Adobe Flash to learn As3. There's too much obfuscation going on behind the scenes. If you want to learn how to code As3, use a code editor. (or plain text editor + compiler if you prefer). Learning what settings dialog has to be adjusted in order to get what you want is not going to get you any closer to understanding OOD in As3.
I also see package, is this kind of like a namespace and does it need to be named, if not what is its purpose?
No, packages are packages and namespaces are namespaces. Apples and oranges.
Packages are used to organize classes just like a structure of
folders is used to organize the .as fiels of those classes. In fact,
the package is pretty much exactly that folder structure, for example:
flash.display is for all display related classes
flash.events is for events
A namespace allows you to control access to members of a class. Namespaces are very rarely used in As3. Here's an article from grant skinner about namespaces. Personally, I never needed to use namespaces. If you are jsut getting started, you can very well ignore them for now.
That sounds perfect! except I cannot get it to launch on my Win10 machine. I may just end up outsourcing this at this ratio
flash develop is the alternative editor. It's free, fast and lightweight.
my normal method of OOD
You want to extend your definition of normal with
always explicitly specify the access control modifiers
member names start with small letters
public class GameInfo {
private var gameID:int;
private var homeTeam:String;
private var visitingTeam:String;
function GameInfo()
{
}
}
1admittedly, there are top level functions that are pretty much free floating functions without a class. If you want to do oop, this is not what you want. It's for the occasional independent utility function. Stick to classes for now.

Creating MovieClip 'components' that don't add to file size in Flash AS2/AS3

I want to create a re-usable Flash MovieClip (component maybe?) that can be dragged and dropped from the library onto the Flash IDE stage (for an example, a "stop all movieclips timer component").
I've created some attractive vector icon graphics for visual reference, so that when it's dragged onto the stage, the developer can visually see the component on the stage, similar to what Google does with it's DoubleClick components. It's not important for these icon graphics to be seen at runtime however, and I'd like their visual portions to not be compiled at runtime to save on filesize.
I'm often asked to create visually rich Flash units in extremely small file sizes. So basically I want my movieclip icon components to not add to filesize (except for the code portion), not compile and render visually but still have the code within them run.
How can I achieve this? Would creating them as components do anything for my issue? Is this even do-able?
Components are definitely the best way to achieve visually represented imported code, however it would be much easier, more compatible and more reliable to just use an imported code library...
Make a seperate .as file, put it in com/mycompany/animation in your swf folder (or use a global classpath), and add this code:
package com.mycompany.animation {
class MyTimerUtils {
public static function stopAllClipsAfterTime(ms){
setInterval(MyTimerUtils.stopAllClips, ms);
}
public static function stopAllClips(){
//etc
}
}
}
Then when you want to use it in a project, just put this code on frame 1 of your main timeline:
import code.mycompany.animation.MyTimerUtils;
MyTimerUtils.stopAllClipsAfterTime(3000); // 3 seconds
What could be easier? If another developer wants to know if a piece of code is implemented they need only look at the first few lines of code.

Actionscript 3 getDefinitionByName not seeing classes

I've worked around this with a hack for now, but would rather know if there's a right way to do it. I have a function that churns out MovieClips, which are tiles for a map that I then attach to the stage. It determines which class of tile to use based on a string variable, like this:
// symbolID holds our class name, determined by logic above
var newClass:Class = getDefinitionByName(symbolID) as Class;
var newtile:MovieClip = new newClass();
This works, but only if an instance of the class already exists somewhere else in the code. It could be anywhere-- in the document class, in some buried function of a helper class, it doesn't seem to matter. If not, Flashdevelop throws error 1065, "Variable (the variable) is not defined". I mention that I'm using Flashdevelop because it seems like it might be compiler-specific, but I'm not sure.
My hack fix is to do this:
var a:baseTile;
a as anotherTile;
a as aThirdTile;
and so on, which works, but definitely isn't ideal if I'm going to have hundreds of these tile classes eventually.
Edit: I should add that these movieclips are coming from a .swc file, which comes from Flash Professional.
You have to use the 'hack'.
getDefinitionByName() can only work with classes that exist at runtime. Unfortunately, if you don't make use of a class, it won't be compiled and won't exist at runtime.
Library symbols make getting around this a little easier. If you check the box that has them available automatically at a given frame, you can just make sure your getDefinitionByName() calls are done during or after that frame.
While SWC libraries can include specific classes to include in the build path, Flash compiler will not link unreferenced classes to a SWF; therefore, requires a linkage library.
Example linkage to retain classes:
/** linkage library */
private static const classA:ClassA;
private static const classB:ClassB;
private static const classC:ClassC;
Another option would be to load the classes from a RSL (Runtime Shared Library).
Basically yes, you need to have a strict reference of that class somewhere in your code. You can even make that reference "unreferenced" elsewhere. I have a hundred of classes like this, and I had to make a single Array of these classes, located somewhere inside the project. I have placed it aside the function that calls getDefinitionByName() to make sure the classes are available in that function.
private static const dummy:Array=[Rock01, Rock02,...,Gem01,Gem02,...];
So you can use such an Array listing all your tiles that you have in your project and want to be accessible by getDefinitionByName().

save picture to movieclip / sending sum picture at once

i have this apps: http://www.jungle-g.co.il/#/System/
Currently, when a user selects a product (eg shirt) He can make only one side of the shirt.
When the user wants to edit another side of the shirt, he will have to complete the booking of the first side and then invite the other side.
My problem is I can not find how to save the first image in the flash memory or in movieclipe.
My interview is to create a movieclip one for each side user edits only when the user decides to do the actual booking send all the pictures from the movieclip.
Is this possible? If not is there another way?
I did research on the topic and found no solution that I could use it.
I found the website: http://code.google.com/p/swfupload/
But I did not understand how it helps me in my case.
Thank you to all the helpers, I break my head for over a month on the case.
You can create a class to hold statics of your bitmapData.
package {
public class ShirtState
{
public static var ShirtFront:BitmapData;
public static var ShirtBack:BitmapData;
}
}
Say you have a shirt that you're editing one side of.
var shirtFront:MovieClip; //this is the shirt you are working with.
once you are done
var shirtFrontBitmap:Bitmap = new Bitmap(shirtFront.width, shirtFront.height);
shirtFrontBitmap.draw(shirtFront);
once you have the bitmap you can save it to your static class
ShirtState.shirtFront = shirtFrontBitmap.bitmapData;
you can then access it anytime in your app provided you don't reload it.
There are some caveats:
If you have a module application where individual swfs are loaded and unloaded by the DOM then you may want to use a LocalSharedObject to store your images. To do that you will have to convert the bitmap data to Base64 (I would anyways) and then store taht string in the local share object. Be mindful that object has a max file size (not sure what it is).
You don't necessarily have to store bitmaps of your shirt sides. You could create your application to create a Class for shirt and as long as an instance of it exists you can have access to both sides of the shirt.
I am not sure how you are building this app, but generally you wouldn't even need to use a static if everything is in the same context. The actual service call to deliver both sides of the shirt to a server for processing would be made at the absolute end.

Link symbol from loaded swf to custom class dynamically

I have a project where I load an external file with asset symbols (assets.swf) into the main swf and then add the symbols to the display when needed. I want the classes associated with each symbol to be linked to a custom class at runtime in the document class. I'd really like to avoid defining the custom classes in the assets fla through the symbol properties.
In AS2, this was possible with Object.registerClass as below:
Object.registerClass("assetID",AssetClass);
this.attachMovie("assetID", "asset_mc", 0);
So the symbol was independent of the class it is linked to at runtime.
In AS3, I'm seeing references to registerClassAlias but there is very little reliable documentation of it available online.
Does anyone know of a way of doing what I'd like to do with registerClassAlias or any other way?
thanks!!!
matt
First, you need to load your asset symbol and keep a reference to the loader.
assetsLoader.load(new URLRequest("assets.swf"));
When the loading is done you can retrieve your assets within the loaded SWF ApplicationDomain.
var assetClass:Class = assetsLoader.contentLoaderInfo.applicationDomain.getDefinition("MyAssetClass") as Class;
var asset:* = new assetClass();
Note: MyAssetClass should be defined inside assets.swf!
If you want further informations, you can read this article.