Why onPress function doesn't Work? - actionscript-3

Here is my code :
stop();
btn_start.onPress = function()
gotoAndStop("gameon")
I have An error and it sounds like: "
Access of possibly undefined property onPress through a Reference with static type
flash.display:SimpleButton.
I converted the text into a Button, I gave him an id, I don't know what to do, don't judge, I'm begginer.
Thanks!

You problem is that your are trying to use the ActionScript 2's onPress() function inside an ActionScript 3 code which didn't support that kind of functions.
In ActionScript 3 you should use event listeners to catch an event on an object.
In your case, you can use, for example, a MouseEvent.CLICK event listener like this :
btn_start.addEventListener(MouseEvent.CLICK, on_Press);
function on_Press(e:MouseEvent): void
{
gotoAndStop('gameon');
}
And for more about migration from ActionScript 2 to ActionScript 3, take a look here.
Hope that can help.

Related

Actionscript 3 - can't open multiple navigateToURL() instances at the same time

I am new to AS3, I want to open multiple browser tabs with flash.
I'm trying to simply start multiple instances of navigateToURL().
for each (var str:String in arrayofrequests)
{
[...]
try { navigateToURL(request, "_blank");}
[...]
}
but only the last instance of navigateToURL gets executed in the browser.
I searched online and someone pointed out callLater could solve this issue.
But every time I try to use callLater I get
Error: Call to a possibly undefined method callLater.
I analyzed adobe documentation here: http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7b06.html
All objects that inherit from the UIComponent class can open the callLater() method.
How I do this? I tried to change my code to something like this
public class Main extends UIComponent
but it isn't working.
To start, UIComponent class is the base class for all visual components used in Flex ( like Label, Progressbar, ...), but I think that your are using Flash, so it's not the good way.
Really I don't know why you want to open many urls in the browser in the same time ( and I think that your final user may be will not like that ), but you have to use some intervals between every navigateToURL() calls using a Timer object for example :
var urls:Array = [
'http://www.wikipedia.org',
'http://www.ubuntu.com',
'http://www.stackoverflow.com'
];
var timer:Timer = new Timer(300, urls.length);
timer.addEventListener(TimerEvent.TIMER, onTimer);
function onTimer(e:TimerEvent):void {
navigateToURL(new URLRequest(urls[timer.currentCount - 1]), '_blank');
}
timer.start();
Hope that can help.

AS3 conditional dispatchEvent?

Is it possible to target a mouseEvent via a dispatchEvent in AS3 whilst controlling the conditions withing the Method?
I'm able to work out how to target the Method but wondered if it's possible to simulate a click with showing==n being active at the same time.
With a standard dispatchEvent it doesn't register the conditions so I hoped there was a way to pre-assign it.
function clickthumb(e:MouseEvent):void{
//determine condition
var n:int=thumbs.indexOf(e.currentTarget);
if(showing==n){
trace("clicked Main target");
} else {
var diff:int=showing-n;
moveArray(-diff);
trace("clicked Side Target");
}
}
target_btn.dispatchEvent(new MouseEvent(MouseEvent.CLICK, clickthumb, false, 0, true));
Any help will be greatly appreciated, thanks for your time.
dispatchEvent is not used that way, you need to use addEventListener for custom functions, otherwise you could use target_btn.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
I think you are looking for:
target_btn.addEventListener(MouseEvent.CLICK, clickThumb);

Why does this not work? Flash As3, if added child is at frame something?

This is my code help me please its really frustrating!
I have a movieclip in my library and added it with AS3 to the stage.
That part was easy. But now i want to control that movieclip.
If introScene "introClass" Reaches frame 120 then i want to remove that movieclip
and replace it with another one. The problem is the if statement doesn't work.
I also tried getChildByName but that didn't work either.
var introClass = new introScene;
addChild(introClass);
introClass.x = 640;
introClass.y = 387;
/*******INTRO-SCENE*******/
introClass.addEventListener(Event, introLoaded);
function introLoaded(event):void{
if(introClass == 120 ){
trace("Frame Reached")
}
}
i tried this and this also doesn't work :(
introClass.addEventListener(Event, introLoaded);
function introLoaded (e:Event):void{
if(MovieClip(introClass).currentFrame == 120){
trace("120 complete")
}
}
This is wrong statement:
introClass.addEventListener(Event, introLoaded);
You need to pass a string to addEventListener. Event type name is converted to a string at runtime which adds a event listener to "flash.events.Event" or something. And your object obviously doesn't have this event. You need to use Event.ENTER_FRAME for example.

How to keep AS3 code simple

This is my original pseudo code:
function1();
function1():void{
//do something
after mouseclick do function2
}
function2():void{
//do something
after animationfinish do function3
}
etc..
Can I get it into something like this?:
function1();
after mouseclick do function2()
after animationfinish do function3()
What is an easy way to get listeners on the top level?
If I understand your question correctly, when function1 is called you want to addEventListener(MouseEvent.CLICK, function2);
Are you using Actiosncript to animate or Keyframes?
I know with TweenMax you can add a function to call at the end of the tween. If using fl.Transtions.Tween you can listen for TweenEvent.MOTION_FINISH and then call function3. I don't mess much with the timeline in Flash, since I feel more in control with coding it, but I know you can add code at the last frame of an animation to call function3.
If I am completely missing you question feel free to clarify what exactly you are seeking.
If i good understand - You like to create functions chain .
I depends what You like to do , problem is in many possibilities.
For call few functions i use this class :
https://github.com/turbosqel/as3SupportLib/blob/master/as3SupportLib/src/turbosqel/utils/CountCall.as
You can also use deeper and more elastic way and add next callbacks to function :
var func:Function = function():void { // declare new function
... function body // your class actions
for each(var call:Function in arguments.callee){ // get functions
call(); // call function
}
}
func["someFunction"] = someFunction; // add function as dynamic value
func["otherFunction"] = anotherFunctionToCall; // add another function
func(); // call function

Clearing eventListeners on a FileReference object

I have a strange issue! I am trying to remove an event listener on a FileReference object by calling a function, but it seems not to be removed, and I do not understand why.
Here is the code:
private function clearFileUploadListeners(file:FileReference, index:String):void {
var dispatchEvent:Function = function(event:Event):void {
dispatch(event.type, event, index);
};
file.removeEventListener(Event.COMPLETE, dispatchEvent);
var bool:Boolean = file.hasEventListener(Event.COMPLETE);
if (bool)
trace("ERROR");
}
When I run this code, the trace actually happens. I don't understand why this boolean returns true, when I just tried to remove the eventListener just above! I guess I am probably doing something really stupid because it seems like a strange error.
I hope someone can please help me on this issue.
EDIT:
I believe it has to do with the fact that the dispatchEvent function is defined inside another function when I add the listener:
private function upload(file:FileReference, index:String):void {
var dispatchEvent:Function = function(event:Event):void {
dispatch(event.type, event, index);
};
file.addEventListener(Event.COMPLETE, dispatchEvent);
}
The problem is that I need to access this "index" variable from the listener, and I can't set it as a global variable as each file has it's own index and it's a burden if I have to extend each event class to keep track of the index (Event, ProgressEvent, ..). I hope someone can please help me on this.
EDIT2:
I actually found a temporary solution, I am not sure if it is the best! I put my removeListener method actually inside the upload method, but made it a variable. As AS3 allows dynamic object, I attached this method to one of my object, and so I just call the reference to the method when necessary. The event is actually removed. Is this a good solution please?
Thank you very much,
Rudy
You're right, it has to do with the fact that you're defining a function inside another function, then using it to handle events.
Each time the function upload is called, it creates a new closure, and assigns a reference to it to the dispatchEvent variable, which is then passed to the addEventListener class. So each time upload is called, it is using a new, different closure in the call to addEventListener. Similarly, in the clearFileUploadListeners function, a new closure is being created on each call (which happens to have the same code each time, but isn't the same function object). The call to removeEventListener does nothing if the given callback has not been added as an event listener for the given event, which is the case here.
To solve your problem, you need to store a reference to the closure that you pass to the addEventListener function. This way, you can get a reference to the same closure that was added when you need to remove it later in clearFileUploadListeners.
You can try something along the lines of the following code (untested):
import flash.utils.Dictionary;
var callbackRegistry:* = new Dictionary();
private function upload(file:FileReference, index:String):void {
var dispatchEvent:Function = generateFileUploadCompleteCallback();
callbackRegistry[file] = dispatchEvent;
file.addEventListener(Event.COMPLETE, dispatchEvent);
}
private function clearFileUploadListeners(file:FileReference, index:String):void {
var dispatchEvent:Function = callbackRegistry[file];
callbackRegistry[file] = null;
file.removeEventListener(Event.COMPLETE, dispatchEvent);
var bool:Boolean = file.hasEventListener(Event.COMPLETE);
if (bool)
trace("ERROR");
else
trace("YAY, ALL OK!");
}
private function generateFileUploadCompleteCallback(index:String):Function {
return function(event:Event):void {
dispatch(event.type, event, index);
};
}
Two other things to note on this subject.
If you must utilize a native Event directly then you should pretty much always make sure and use these last three optional params :
myObject.addEventListener( Event.COMPLETE, myFunction, false, 0, true );
Check Grant Skinner's post on the subject here :
http://gskinner.com/blog/archives/2006/07/as3_weakly_refe.html
And the very best practice of all is to ALWAYS (seriously always) use Robert Penner's Signals (instead of custom events) and his NativeSignals (to wrap needed native Flash events).
Five times faster than Flash's native events.
Always safe with weak references.
Any number of typed payload(s) in each Signal.
Get the SWC here :
https://github.com/robertpenner/as3-signals
Signals were designed to solve the very problem you are having.
Imagine instead of creating an array and managing that to remove all listeners if you could just call :
signalBtnClicked.removeAll();
or
signalBtnClicked.addOnce( function( e : MouseEvent ) : void { /* do stuff */ } );
Knowing that the closure you just created will immediately be dereferenced once it is called and happily go night night when the GC makes its rounds.