About embeding assets(images) in AS3 project - actionscript-3

I am using flex sdk 4.5.1 and flash develop to compile my AS3 project. I have small images, about 12KB which is silly to load them using Loader class, so embeding is better solution.
However when this line at the top of my Main class is uncomented i get blank swf
[Embed(source = "../assets/gui/play1.png", mimeType = "image/png")]
private var PlayUpImg:Class;
(when i comment it out, the compilated swf is ok)
What could be the error. Why do I get the blank swf?
I am working on pure AS3 project in FlashDevelop

You could try embing the png image as arbitrary binary data by using the "application/octet-stream" mimetype. Then you would use a Loader object's loadBytes() method to load the png image's binary data. The following is an example of this:
package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
[SWF(width="256", height="256", backgroundColor="#FF0000")]
public class Main extends Sprite
{
[Embed(source = "assets/ie9.png", mimeType = "application/octet-stream")]
private var IE9:Class;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}// end function
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var loader:Loader = new Loader();
loader.loadBytes(new IE9());
addChild(loader);
}// end function
}// end class
}// end package
[UPDATE]
I know this answer has already been accepted but here's an extra added bonus.

You need to add the image to the Displaylist:
package
{
import flash.display.Bitmap;
import flash.display.Sprite;
public class Main extends Sprite{
[Embed(source = "../assets/gui/play1.png", mimeType = "image/png")]
private var PlayUpImg : Class;
public function Main()
{
var myImage : Bitmap = new PlayUpImg();
addChild( myImage );
}
}
}

Related

AS3 debugger stops responding while trying to load image into sprite using Loader

I'm trying to create a simple Menu in AS3. There is a sprite called startButton, which when pressed will call the function startGame, and that's it! But, not so easy. I'm using flashdevelop IDE so I'm trying to call a loader to get a .png image file for the spite startButton. But, it doesn't work. There are no error messages, the debugger just does not respond. Any help? Here is the code for both files
Main code:
package {
//Other Files
import Menu;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.ui.Mouse;
public class Main extends Sprite {
//Game values
public static var gameWidth:int = 750;
public static var gameHeight:int = 750;
public function Main() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
addChild(Menu.startButton);
Menu.startButton.addEventListener(MouseEvent.CLICK, startGame);
stage.addEventListener(Event.ENTER_FRAME, update);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
}
//Function starts game
public function startGame(evt:MouseEvent):void {
removeChild(Menu.startButton);
}
//Updates every 60 seconds
public function update():void {
trace("Updated");
}
}
}
And Menu Image code:
package {
//Other files
import Main;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
public class Menu extends Sprite {
public static function imageLoaded():void {
startButton.addChild(loader);
//initizlize values for startButton Bitmap
startButton.x = (Main.gameWidth / 2) - (startButton.width / 2);
startButton.y = (Main.gameHeight / 2) - (startButton.height / 2);
}
//create startButton Bitmap
public static var startButton:Sprite = new Sprite();
public static var loader:Loader = new Loader();
loader.load(new URLRequest("lib/menustartbutton.png"));
loader.addEventListener(Event.COMPLETE, imageLoaded);
}
}
By the way, I wait for the loader to successfully load the image before working with it, just in case the image takes more time and it draws errors.
The problem is that you misuse static. all static methods/properties are initialized before the classes themselves. As a result static can receive values but they cannot run any code. Running code has to happen after all classes are ready to go which is not the case when static is initialized. In your case startButton and loader are created correctly but the next line never runs 'loader.load'.
Don't misuse static, you are obviously trying to use static to make you code writing and life easier but at the end because you are misusing it you will always end up with more problems.

AS3 Architecture : How to tween a single instance of an object on multiple calls?

I am new to actionscript and am having a trouble displaying a single instance of an object, using FlashDevelop.
I have a main.as in which I am displaying an image as background. Then I display a rectangle containing some text that tweens as the mouse hovers a target (appearing/disappearing on the stage). The rectangle is in a class TextBox.as .
I know my code is quite messy because it creates a new instance of the rectangle everytime I reach the target (calling the tween). But if I try to switch it around it gives me errors. Also I cannot seem to remove my rectangle (with removeChild()) once it is created, it cannot find the child.
Could anyone indicate me what is the architecture I should use so that only one instance of the rectangle is created?
Here's a bit of my code:
//IMPORT LIBRARIES
import Classes.TextBox;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import com.greensock.TweenLite;
// Setup SWF Render Settings
[SWF(width = "620", height = "650")]
public class Main extends Sprite
{
//DEFINING VARIABLES
[Embed(source="../lib/myimage.jpg")]
private var picture:Class;
private var myTween:TweenLite;
//CONSTRUCTOR
public function Main():void
{
addChild(new TextBox);
addChild(new picture);
addEventListener(MouseEvent.MOUSE_OVER, appear);
}
//ROLLDOWN FUNCTION
public function appear(e:MouseEvent):void
{
trace("Appear");
var text:TextBox = new TextBox();
addChild(text);
addChild(new picture);
if (picture) {
removeEventListener(MouseEvent.MOUSE_OVER, appear);
//addEventListener(Event.COMPLETE, appearComplete);
myTween = new TweenLite(text, 1, { y:340 , onComplete:appearComplete, onReverseComplete:disappearComplete} );
}
}
Thanks in advance.
i dont know what tweening you want to achieve but you should reuse your textbox instance, e.g.:
import Classes.TextBox;
import com.greensock.TweenLite;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
[SWF(width = "620", height = "650")]
public class Main extends Sprite {
[Embed(source="../lib/myimage.jpg")]
private var pictureClass:Class;
private var picture:Bitmap;
private var textbox:TextBox;
public function Main():void {
if (stage)
init();
else
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
picture = new pictureClass();
textbox = new TextBox();
addChild(picture);
addChild(textbox);
addEventListener(MouseEvent.MOUSE_OVER, tween);
}
public function tween(e:MouseEvent):void {
removeEventListener(MouseEvent.MOUSE_OVER, tween);
TweenLite.to(textbox, 1, { y:340, onComplete:reverse } );
}
private function reverse():void {
TweenLite.to(textbox, 1, { y:0, onComplete:tweenComplete } );
}
private function tweenComplete():void {
addEventListener(MouseEvent.MOUSE_OVER, tween);
}
}

Can't embed assets in a SWF file when content is less than 4 bytes long

I am trying to compile a SWF file, using the mxmlc compiler from Apache Flex SDK 4.10.0. The program simply loads and shows text from a file called asset1.txt.
Here is my code:
package
{
import flash.events.Event;
import flash.display.Sprite;
import flash.text.TextField;
import mx.core.ByteArrayAsset;
[SWF(width="20", height="20", backgroundColor="#ff00fa")]
public class Main extends Sprite
{
[Embed("asset1.txt", mimeType="application/octet-stream")]
private static var asset:Class;
public function Main()
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
var assetBytes:ByteArrayAsset = ByteArrayAsset(new asset());
var assetString:String = assetBytes.readUTFBytes(assetBytes.length);
removeEventListener(Event.ADDED_TO_STAGE, init);
var tf:TextField = new TextField();
tf.text = assetString;
addChild(tf);
}
}
}
The problem is that when the text contained in asset1.txt is less than 4 bytes long, all bytes from the embedded file are replaced by null bytes, otherwise everything works. For example, the text file is correctly embedded in the SWF when it contains "abcd" or "abcde", but not when it contains "ab" or "abc". Any idea?
Maybe is a bug of the version of Flex, Im using Flex 4.6 and test your code and is running just fine, try with a different version of the compiler. Hope that helps

gotoAndPlay in embedded movieclip

I am working on an Air 2.6 project with an embedded SWF.
I am using the following embed code:
[Embed(source = "../../assets/click_feedback.swf", symbol="sub_circle")]
[Bindable]
public static var click_feedback:Class;
And the following code to get an instance of the click_feedback class:
private var cfb:MovieClip = new Assets.click_feedback() as MovieClip
The problems are:
The asset sub_circle has a frame labeled 'respond'. However, it just plays non stop whether or not the label is called with gotoAndPlay.
And, at the end of the animation, there is an Event.COMPLETE called, which is not being picked-up by my code.
I have tested the sub_circle asset in CS5 where I built it, and, in that environment it does not animate until 'respond' is called, and the event it triggers can be heard by my script.
Is this the correct way to handle embedded assets from an SWF?
Embedding of separate symbols from swf in general isn't a good idea:
It slows the compilation of your project, because of compiler must transcode swf format.
Embedding delete ALL AS code from timeline (I didn't check, but may be it remove labels as well, and it can be the reason of your issue).
I recommend embed the hole swf file and loads its bytes in runtime, a little more code to handle the async loading, but much more freedom and flexibility in use:
you safe all as3 code
you can choose ApplicationDomain where to load classes
you can easily switching from Embedding to runtime swf loading by url at any time, if you want to separate the as code and art/sounds assets.
organize your assets to library with the AssetsManager (with api like load(ByteArray or URL), getSkin(name):DisplyObject)
Code example adapted for your assets:
package
{
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.utils.ByteArray;
[SWF(width="800", height="200", backgroundColor="0x8B8B8B")]
public class astest extends Sprite
{
[Embed(source="../../assets/click_feedback.swf", mimeType="application/octet-stream")]
private static const common_art:Class;
private var loader:Loader;
private var domain:ApplicationDomain = ApplicationDomain.currentDomain;
public function astest()
{
init();
}
public function init():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
var loaderContext:LoaderContext = new LoaderContext(false, domain);
loaderContext.allowCodeImport = true;
loader.loadBytes(new common_art() as ByteArray, loaderContext);
}
private function onLoaded(event:Event):void
{
var clip:MovieClip = getSkin("sub_circle") as MovieClip;
addChild(clip);
}
private function getSkin(name:String):DisplayObject
{
if(domain.hasDefinition(name))
{
var clazz:Class = domain.getDefinition(name) as Class;
return new clazz() as DisplayObject;
}
return null;
}
}
}

Flash Builder 4.6 Mobile Flex AS3: How to communicate with embedded SWF

I have a Flash Barcode scanner (camera) and want to use it in a mobile project to scan QR-Codes. It would be nice that it is possible to re-use this SWF and embedded it into a mobile Flex application. The SWF is made in Flash CS5.
So far, embedding (and add it to the stage and showing it) is successful but how do i communicate with the SWF? For example calling a function of it or by using events.
Here is a code snippet:
[Embed(source="../cam/cam.swf")]
private var cam:Class;
....
....
public const EVT_SNAPSHOT : String = "onSnapShot";
public var camera : Object;
public function onInit(e:Event) : void
{
this.camera = new cam();
this.camera.addEventListener(Event.ADDED_TO_STAGE, this.cameraInit );
this.stage.addChild( this.camera as DisplayObject );
}
private function cameraInit(e:Event):void
{
trace( 'Added to stage' );
this.stage.addEventListener( EVT_SNAPSHOT, this.cameraDoScan ); // does not bind?
trace( this.camera.hasOwnProperty('getAppInfo') ); // shows 'false'
}
private function cameraDoScan(e:MouseEvent):void
{
trace('MouseClick!');
}
Does anyone know to communicate with this 'thing'?
The most functional way to use external swf module is to load it into current ApplicationDomain, so you will have access to all classes contained in this loaded swf:
package
{
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.utils.ByteArray;
import flash.utils.getDefinitionByName;
public class astest extends Sprite
{
[Embed(source="/../assets/art.swf", mimeType="application/octet-stream")]
private static const art:Class;
public function astest()
{
var artBytes:ByteArray = new art() as ByteArray;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onArtLoaded);
loader.loadBytes(artBytes, new LoaderContext(false, ApplicationDomain.currentDomain));
}
protected function onArtLoaded(e:Event):void
{
var domain:ApplicationDomain = ApplicationDomain.currentDomain;
if(domain.hasDefinition("welcome_view"))
{
var moduleClass:Class = domain.getDefinition("welcome_view") as Class;
var module:Object = new moduleClass();
//module.moduleFunction();
addChild(module as DisplayObject);
}else
{
trace("loaded swf hasn't class 'welcome_view'");
}
}
}
}