Adobe AIR getQualifiedDefinitionNames - actionscript-3

I have a problem with getQualifiedDefinitionNames, when I compile with AIR 20 I get
Main
gameBg_png$c19135a2672bad8837da970f47c7278f-30390368
and when I compile with Apach Flex 4.15.0 or Adobe Animate CC it returnes everything as expected!
Main
Main__gamebg
how to fix it with AIR, that it returned Main__gamebg class?
my sample code:
package{
import flash.display.MovieClip;
import flash.events.Event;
public class Main extends MovieClip {
[Embed(source="../assets/gameBg.png")]
public const _gamebg:Class;
public function Main() {
super();
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
var definitions:*;
if (this.loaderInfo.applicationDomain.hasOwnProperty("getQualifiedDefinitionNames")) {
definitions = this.loaderInfo.applicationDomain["getQualifiedDefinitionNames"]();
for (var i:int = 0; i < definitions.length; i++) {
trace(definitions[i])
}
}
}
}
}

http://forum.starling-framework.org/topic/getqualifieddefinitionnames-porblem?replies=5#post-90611
this trick works.
///////////////
// SomeImage.as
///////////////
[Embed(source="someimage.png")]
public class SomeImage extends Bitmap{
public function get dimensions(): String{
return width + "x" + height;}
}
/////////////
// MyClass.as
/////////////
public class MyClas{
public function foo(): void{
// Instantiate the bound class to get the embedded image
var someImage:SomeImage = new SomeImage();
// ... do whatever you'd like with someImage
trace("Dimensions: " + someImage.dimensions);
}
}

Related

How to load this into a Main class in AS3?

I'm learning some AS3 basics and would like to set up a native menu up the top of the window.
I found this menu example at Adobe: https://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118666ade46-7de7.html
How would I add this to my Main class so that the menu appears please?
The MenuExample class is in the same dir as Main
package {
import flash.display.*;
import MenuClass;
public class Main extends MovieClip {
private static var _instance:Main = null;
public function Main() {
_instance = this;
this.addEventListener(Event.ADDED_TO_STAGE, init);
}
public static function getInstance():Main { return _instance; }
public static function getStage():Stage { return getInstance().stage; }
private var Menu:MenuExample = new MenuExample();
private function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
//_menu = new MenuExample(stage); //correct way to do it
}
}
}
Thank you.

ADDED_TO_STAGE function never called

I have this class which should take a button from stage (xBtn).
package com.stx.utils {
import flash.display.MovieClip;
import flash.events.*;
public class STXbutonx extends MovieClip {
private var xBtn : MovieClip;
public function STXbutonx() {
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event=null) : void {
trace("int!"); //this is never called
xBtn = stage.getChildByName('ics') as MovieClip;
xBtn.addEventListener(MouseEvent.CLICK, onX);
removeEventListener(Event.ADDED_TO_STAGE, init);
}
private function onX(e:MouseEvent) : void {
trace("x Clicked!");
}
}
}
and in Document class I called like this :
import flash.display.MovieClip;
import com.stx.utils.*;
public class Main extends MovieClip {
var xx : STXbutonx;
public function Main() {
xx = new STXbutonx();
}
}
Why my init function is never called?
Thank you!
Because you never add it to the stage.
Change your Document class to
public function Main() {
xx = new STXbutonx();
addChild(xx);
}
Main holds the reference to the stage, adding a child to Main will add the child to the stage. Thus the event listener in STXbutonx will fire.
xBtn = stage.getChildByName('ics') as MovieClip; // now I have acces of undefined property stage...
You don't have access to the stage because STXButon is not on the stage, it is not an DisplayObject. To get around this, do this:
package com.stx.utils {
import flash.display.MovieClip;
import flash.events.*;
public class STXbutonx{
private var xBtn : MovieClip;
private var stage : Stage;
public function STXbutonx(stage:Stage) {
this.stage = stage;
init();
}
private function init() : void {
trace("int!");
xBtn = stage.getChildByName('ics') as MovieClip;
xBtn.addEventListener(MouseEvent.CLICK, onX);
removeEventListener(Event.ADDED_TO_STAGE, init);
}
private function onX(e:MouseEvent) : void {
trace("x Clicked!");
}
}
}
And of course
import flash.display.MovieClip;
import com.stx.utils.*;
public class Main extends MovieClip {
var xx : STXbutonx;
public function Main() {
xx = new STXbutonx(stage);
}
}

How can I dispatch event to another class in Action Script 3?

I've searched few docs and I couldn't find about dispatching event to another classes.
I'm trying to make like this.
'main' class has button.
'main','sub' class gonna trace "button is clicked" when button is clicked
I can trace that in 'main' class with dispatch event.
but 'sub' class is problem.
how can I dispatch event like that into 'sub' class?
Main class
package com
{
import flash.events.*;
import flash.display.MovieClip;
import com.sub;
public class main extends MovieClip
{
public static const BTN_CLICKED:String = "btn_Clicked";
public function main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
public function init(e:Event = null):void
{
var flashVars:Object = {};
removeEventListener(Event.ADDED_TO_STAGE, init);
if(parent != null && parent.parent != null)
{
flashVars = parent. parent.loaderInfo.parameters;
}
else
{
flashVars = this.root.loaderInfo.parameters;
}
//entry point
var subClass:sub = new sub;
subClass.init();
btn.addEventListener(MouseEvent.CLICK, onClick);
addEventListener(BTN_CLICKED, onbtnClicked, false, 0, true);
}
public function onClick(e:MouseEvent)
{
dispatchEvent(new Event(BTN_CLICKED));
}
public function onbtnClicked(e:Event)
{
trace("clicked");
}
}
}
Sub Class
package com
{
import flash.events.*;
import flash.display.MovieClip;
import com.main;
public class sub extends MovieClip
{
public function sub():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
public function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
//entry point
trace("sub class loaded");
}
}
}
You should relocate var subClass:sub to the main set of main class definitions, beside public static const BTN_CLICKED:String = "btn_Clicked";. Then, you can do subClass.dispatchEvent(...).
public class main extends MovieClip {
private var subClass:sub;
public function main() {
...
subClass=new sub();
addChild(subClass); // not just "init()", it's wrong
...
}
public function onClick(e:MouseEvent)
{
dispatchEvent(new Event(BTN_CLICKED));
subClass.dispatchEvent(new Event(BTN_CLICKED));
}
}

Actionscript 3 cannot access a property or method of a null object reference

I'm still really new about classes and stuffs. So, I tried making this and I got an error: Access of undefined property.
Why speedX and speedY var still error although I've defined it in public var in the main class?
Thanks!
EDITED: I've tried calling the variables from other class with main.speedX and main.speedY
But it got error : Cannot access a property or method of a null object reference.
at Ball/moveBall()
This is the Main code:
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Main extends MovieClip
{
public var speedX:Number = 5;
public var speedY:Number = 5;
public var speedMax:Number = 10;
private var ball:MovieClip = new Ball();
private var paddle:MovieClip = new Paddle();
public function Main()
{
paddle.addEventListener(Event.ENTER_FRAME, movePaddle);
addChild(ball);
addChild(paddle);
}
}
}
This is the Ball Movie Clip Code:
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Ball extends MovieClip
{ public var main:Main;
public function Ball()
{addEventListener(Event.ENTER_FRAME, moveBall);
main= new Main();
}
public function moveBall(e:Event):void
{
x += main.speedX;
y += main.speedY;
}
}
}
That's because your class Ball cannot access speedX and speedY inside the event callback. Why not add speedX and speedY to your Ball class directly instead ?
public class Ball extends MovieClip
{
public var speedX:Number;
public var speedY:Number;
public function Ball(sX:Number = 0, sY:Number = 0)
{
this.speedX = sX;
this.speedY = sY;
addEventListener(Event.ENTER_FRAME, moveBall);
}
public function moveBall(e:Event):void
{
x += speedX;
y += speedY;
}
}
Here's another possible solution where you would be passing main to ball to use the values of speed stored in Main.
public class Main extends MovieClip
{
public var speedX:Number = 5;
private var ball:MovieClip;
public function Main()
{
ball=new Ball(this);
addChild(ball);
}
}
and
public class Ball extends MovieClip
{
private var _main:Main;
public function Ball(main:Main)
{
_main=main;
addEventListener(Event.ENTER_FRAME, moveBall);
}
public function moveBall(e:Event):void
{
x += _main.speedX;
}
}
}

AS3 Preloader Timing

I did the following
package classes
{
// imports removed
public class Main extends MovieClip {
// vars removed
public function Main():void {
trace('--> Main Function started ...');
/**************************************
Preloader
**************************************/
var preLoader:PreLoader = new PreLoader(); // init
stage.addChild(preLoader); // to Stage
stage.loaderInfo.addEventListener(ProgressEvent.PROGRESS, preLoader.preloaderProgress); // calling the function
doThis();
}
}
With the PreLoader Class looking like this:
package classes {
// imports removed
public class PreLoader extends MovieClip {
public var totalBytes:uint;
public var loadedBytes:uint;
public function PreLoader() {
trace('--> PRELOADER Started ...');
this.addEventListener(Event.ADDED_TO_STAGE, addedHandler);
this.loaderBar.scaleX = 0;
}
private function addedHandler(e:Event):void {
trace('Adding Preloader ...');
totalBytes = this.stage.loaderInfo.bytesTotal;
trace('PL: Total ' + totalBytes + ' / ' + loadedBytes);
this.removeEventListener(Event.ADDED_TO_STAGE, addedHandler);
preloaderProgress(e);
}
public function preloaderProgress(e:Event):void {
trace('Progress...');
loadedBytes = this.stage.loaderInfo.bytesLoaded;
this.loaderBar.scaleX = loadedBytes / totalBytes;
this.loaderBar.alpha = 1 - this.loaderBar.scaleX;
if (totalBytes == loadedBytes) {
trace('Removing PreLoader ...');
this.parent.removeChild(this);
}
}
}
}
The Problem: The Preloader is not displayed BEFORE the inital SWF-file has finished loading. Even all the tracing outputs start when the main movie is finished - i did some profiling on 'slow connections'.
If you wonder: doThis() is loading data from a xml-file, from here everything is fine, tracing outputs are at the right time (but too late at all :D)
Thank you in advance!
Edit: Maybe the question is: Is there a way to determine when the main movie is starting to load?
Make sure that you don't have any content other than the preloader on stage in the first frame. Otherwise all that content will have to load before the preloader starts up.
If you are working in FlashIDE you have to put your preloader into the first frame. If you prefer to use another IDE you should use Frame metatag. Example:
Main.as
package com.sample.preloader
{
import flash.display.Sprite;
import flash.events.Event;
/**
* ...
* #author Author
*/
[Frame(factoryClass="com.sample.preloader.Preloader")]
public class Main extends Sprite
{
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);
// entry point
}
}
}
Preloader.as
package com.sample.preloader
{
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.utils.getDefinitionByName;
/**
* ...
* #author Author
*/
public class Preloader extends MovieClip
{
public function Preloader()
{
if (stage) {
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
}
addEventListener(Event.ENTER_FRAME, checkFrame);
loaderInfo.addEventListener(ProgressEvent.PROGRESS, progress);
loaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioError);
// TODO show loader
}
private function ioError(e:IOErrorEvent):void
{
trace(e.text);
}
private function progress(e:ProgressEvent):void
{
// TODO update loader
}
private function checkFrame(e:Event):void
{
if (currentFrame == totalFrames)
{
stop();
loadingFinished();
}
}
private function loadingFinished():void
{
removeEventListener(Event.ENTER_FRAME, checkFrame);
loaderInfo.removeEventListener(ProgressEvent.PROGRESS, progress);
loaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioError);
// TODO hide loader
startup();
}
private function startup():void
{
var mainClass:Class = getDefinitionByName("com.sample.preloader.Main") as Class;
addChild(new mainClass() as DisplayObject);
}
}
}