translating AS3 dispatchEvent into AS2 - actionscript-3

I have one as3 file which handles other files (small games). All files are AS3 except for one which is AS2 and it is too big for me to rewrite it into AS3.
In AS3 i use:
dispatchEvent(new Event("ending", true));
when game is finished.
I need to dispatch "ending" in AS2 file, so my AS3 main file can do it's magic.
Could someone translate this line from as3 to as2?

The event model is just a bunch of callbacks associated with event types (strings). The EventDispatcher maintains this association and iterates over the callbacks when a specific event is triggered by it.
This is pretty trivial to recreate yourself, and in you case you can simplify it greatly.
Here's an example of what could be a simple EventDispatcher in AS2:
function EventDispatcher():Object
{
var listeners:Object = { };
return {
addEventListener: function(type:String, callback:Function)
{
listeners[type] = callback;
},
dispatchEvent: function(type:String)
{
for(var i:String in listeners)
{
if(i === type) listeners[i]();
}
}
};
}
And its implementation:
// Create the event dispatcher.
var eventDispatcher:Object = EventDispatcher();
// Add an event listener as with AS3.
eventDispatcher.addEventListener("ending", endGame);
// Define the handler function.
function endGame():Void
{
trace("Game has ended.");
}
// Dispatch an event.
eventDispatcher.dispatchEvent("ending");
If you want to bring it closer to the AS3 Event model, you need to create an 'Event' object within the dispatchEvent loop and pass that to the handler, something like this:
dispatchEvent: function(type)
{
for(var i:String in listeners)
{
var event:Object = { type: i, target: this };
if(i === type) listeners[i](event);
}
}

Related

Convert AS2 Code to AS3 Format

please help me out converting the code below into as3. I have no ideea what is "SHEMA" , "BASE", "GLANCE" etc for AS3. THanks a lot.
This code is being written inside a movie clip.
function CopyFromShema(sframe)
{
SHEMA.gotoAndStop(sframe);
GLANCE.filters = SHEMA.GLANCE.filters;
BASE.filters = SHEMA.BASE.filters;
CAPTION.filters = SHEMA.CAPTION.filters;
}
SHEMA._visible = false;
SHEMA.gotoAndStop(1);
BASE.scale9Grid = new flash.geom.Rectangle(10, 10, 100, 5);
GLANCE.scale9Grid = new flash.geom.Rectangle(10, 6, 100, 2);
onRollOver = function ()
{
CopyFromShema(3);
}
;
onRollOut = function ()
{
CopyFromShema(2);
}
;
onPress = function ()
{
CopyFromShema(4);
}
;
onRelease = function ()
{
CopyFromShema(3);
}
;
onDragOver = function ()
{
onPress();
}
;
onDragOut = function ()
{
onRollOut();
}
;
as pointed in line "3" of provided code in question, SHEMA.gotoAndStop(sframe);
they are all MovieClips and not As2 Classes/Keywords.
everything is ok in AS3 just replace (do it for all event fucntions)
onRollOver = function ()
{
CopyFromShema(3);
};
with As3 Event handlers
stage.addEventListener(MouseEvent.ROLL_OVER, function(e:MouseEvent):void {
CopyFromShema(3);
});
about other MouseEvents :
onRollOut : MouseEvent.ROLL_OUT
onPress : MouseEvent.MOUSE_DOWN
onRelease : MouseEvent.MOUSE_UP
onDragOver : N/A (its MOUSE_OVER while MOUSE_DOWN)
onDragOut : N/A (its MOUSE_OUT while MOUSE_DOWN)
so what to do with non available events in as3? they are available but you have to handling them with bunch of available events, here is an example of it.
[update] why chaning AS2 to AS3?
most times, there is no real need for porting AS2 to AS3, but you can simply compile AS2 projects as swf, then embedding them in to the AS3 projects, and let them communicate with each other trough a LocalConnection as mentioned here

AS2 to AS3 conversions, loading multiple external swf's with same preloader

I'm new as a member here, but have found some very helpfull information here in the past, and cannot find a fix for my current issue. I've been trying to rewrite my flash AS2 website to AS3, and am getting roadblocked by all the major differences between these to actionscripts. I have a majority of it rewritten (successfully I think), but cannot seem to find the correct way to rewrite this AS2 code:
//AS2 ATTACH PRELOADER
function onLoadStart(target){
attachMovie("preloader anim", "preloader_mc", 500, {_x:447, _y:290});
}
function onLoadProgress(target, bytes_loaded, bytes_total){
target.stop();
target._visible = false;
preloader_mc.value = bytes_loaded/bytes_total;
}
function onLoadComplete(target){
trace("complete")
target.play();
target._visible = true;
preloader_mc.removeMovieClip();
}
function onLoadError(target, error_code){
preloader_mc.removeMovieClip();
trace(error_code);
}
//AS2 LOAD SWFS WITH ABOVE PRELOADER
var loader_mcl = new MovieClipLoader();
loader_mcl.addListener(this);
skullo_b.onRelease = function(){
startPreload("load/skullo.swf")
}
fruit_b.onRelease = function(){
startPreload("load/fruitbat.swf")
}
//...many more swfs left out to save space
function startPreload(url){
loader_mcl.loadClip(url, container_mc);
}
I know attachmovie is no longer for AS3, so from my research I've rewritten it as follows, but keep getting other errors that I'm having a loss on fixing. Basically, I have 30+ buttons, that when I click on each, it will load an external swf at the same location on the stage (container mc) and hide the previously loaded swf, and each swf will utilize the same preloader (preloader_anim). I've included the current errors I'm getting after finally clearing some others. If anyone can help me out, or point me to an online example of this I haven't been able to locate I would be very grateful. I've found some examples of loading external swfs with as3, but not multiples with the same preloader. I am also very new to as3, and haven't messed with classes yet, so all my code is on the timeline if that makes any difference.
//AS3 ATTACH PRELOADER
//ERROR 1046: Type was not found or was not a compile-time constant: preloader_mc.
//ERROR 1180: Call to a possibly undefined method preloader_mc.
var preloader_anim:preloader_mc = new preloader_mc();
preloader_anim.x = 458;
preloader_anim.y = 290;
addChild(preloader_anim);
function onLoadProgress(target, bytes_loaded, bytes_total){
target.stop();
target._visible = false;
var preloader_mc = bytes_loaded/bytes_total;
}
function onLoadComplete(target){
trace("complete")
target.play();
target._visible = true;
preloader_mc.removeMovieClip();
}
function onLoadError(target, error_code){
preloader_mc.removeMovieClip();
trace(error_code);
}
//AS3 LOAD SWFS WITH ABOVE PRELOADER
var imgLoader:Loader = new Loader();
//ERROR 1061: Call to a possibly undefined method addListener through a reference with static type flash.display:Loader.
imgLoader.addListener(this);
skullo_b.addEventListener(MouseEvent.CLICK, skullo_bClick);
angel_b.addEventListener(MouseEvent.CLICK, angel_bClick);
function skullo_bClick(e:MouseEvent):void {
startPreload("load/skullo.swf")
}
function metal_bClick(e:MouseEvent):void {
startPreload("load/metal.swf");
}
function startPreload(url){
//ERROR 1061: Call to a possibly undefined method loadClip through a reference with static type flash.display:Loader.
imgLoader.loadClip(url, container_mc);
}
Let's go through this in order of your errors.
ERROR 1046: Type was not found or was not a compile-time constant: preloader_mc
&
ERROR 1180: Call to a possibly undefined method preloader_mc.
These errors are because the compiler can't find any class called preloader_mc
If you have an asset in your library called preloader_mc, that is not enough, you need to go it's properties and choose export for actionscript, then give it a class name (the class name can be the same as the library asset name, so: preloader_mc).
Just make sure though, that you don;t have any variable or function names that clash with your class names (this is currently your case with preloader_mc). Common practice, is to make all class names start with an Uppercase letter, and all function and vars start with a lowercase letter.
2.
ERROR 1061: Call to a possibly undefined method addListener through a reference with static type flash.display:Loader.
In AS3, what you want is addEventListener. With the Loader class you need to listen for each event, instead of giving it a context that has pre-set methods. It takes a string event name, and a callback function. So you probably want this:
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaderComplete);
imgLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
function progressHandler(e:ProgressEvent):void {
//this function will run whenever progress in the load is made
trace("progressHandler: bytesLoaded=" + e.bytesLoaded + " bytesTotal=" + e.bytesTotal);
}
function imgLoaderComplete(e:Event):void {
//this function will be called after the loader finishes loading
}
It's also a good idea to listen for IO_ERROR & SECURITY_ERROR events on the loader as well:
imgLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
imgLoader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
ERROR 1061: Call to a possibly undefined method loadClip through a reference with static type flash.display:Loader.
There is not method called loadClip on the Loader class. What you want is the following (to start loading)
imgLoader.load(new URLRequest("yoururlhere"));
For more details on how to properly use the Loader class, read the documentation.
So, in the end, it should look more like this:
//take your preloader movie clip, and export it for actionscript with the class name "Preloader_MC"
//create vars for the pre loader and loader (don't create the objects yet though)
var preLoader:Preloader_MC;
var imgLoader:Loader;
skullo_b.addEventListener(MouseEvent.CLICK, skullo_bClick);
angel_b.addEventListener(MouseEvent.CLICK, angel_bClick);
function skullo_bClick(e:MouseEvent):void {
startPreload("load/skullo.swf")
}
function metal_bClick(e:MouseEvent):void {
startPreload("load/metal.swf");
}
function startPreload(url) {
//if the loader is currently populated, destroy it's content
if (imgLoader) {
imgLoader.unloadAndStop();
removeChild(imgLoader);
}else {
//it doesn't exist yet, so create it and add the listeners
imgLoader = new Loader();contentLoaderInfo
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaderComplete);
imgLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
imgLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
imgLoader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
}
if (!preLoader) {
preLoader = new PreloaderMC();
addChild(preLoader);
}
imgLoader.load(new URLRequest(url));
addChild(imgLoader);
}
function removePreLoader():void {
removeChild(preLoader);
preLoader = null;
}
function progressHandler(e:ProgressEvent):void {
var percentLoaded:Number = e.bytesLoaded / e.bytesTotal; //number between 0 - 1
preLoader.value = percentLoaded;
}
function imgLoaderComplete(e:Event):void {
removePreLoader();
}
function ioErrorHander(e:IOErrorEvent):void {
//file not found, do something
removePreLoader();
}
function securityErrorHandler(e:SecurityErrorEvent):void {
//do something, file wasn't allowed to be loaded
removePreLoader();
}

Dragging movie clips in Action Script 3

Hi so recently I have been attempting to Drag a movie clip in AS3 but I'm having some trouble picking up with the hit tests anyone got any ideas? Just to clarify, the issue is that when the movieclips hit the drag test object, they're not executing the gotoframe() function.
initDrag() adds action listeners:
MOUSE_DOWN on the object
MOUSE_UP on the stage so it doesn’t matter if you are off the object
endDrag() removes the action listeners; call this (for each object) before you go to another frame
startADrag()create a rectangle within which the object can be dragged (in this case the stage)
call startDrag() on the object
stopADrag() call stopDrag() on the object from currentObject (but only if currentObject is not null).
var currentObject:MovieClip = null;
initDrag(block1);
initDrag(block2);
initDrag(block3);
initDrag(block4);
function initDrag(obj:MovieClip )
{
obj.addEventListener(MouseEvent.MOUSE_DOWN,startADrag);
stage.addEventListener(MouseEvent.MOUSE_UP,stopADrag);
}
function endDrag(obj:MovieClip )
{
obj.removeEventListener(MouseEvent.MOUSE_DOWN,startADrag);
stage.removeEventListener(MouseEvent.MOUSE_UP,stopADrag);
}
function startADrag(e:MouseEvent):void
{
currentObject = (MovieClip)(e.target);
var rect:Rectangle = new Rectangle(0,0,stage.stageWidth - currentObject.width,stage.stageHeight - currentObject.height + 100);
currentObject.startDrag(false,rect);
}
function stopADrag(e:MouseEvent):void
{
if (currentObject != null)
{
currentObject.stopDrag();
}
}
if(block1.hitTestObject(dragtest)){
gotoAndStop("lose");
}
if(block2.hitTestObject(dragtest)){
gotoAndStop(27);
}
if(block3.hitTestObject( dragtest)){
gotoAndStop("lose");
}
if(block4.hitTestObject( dragtest)){
gotoAndStop("lose");
}
thanks for any advice or answers.
The following code should work as expected. The problem is, as i already stated in my comment, that your calls to hitTestObject(obj) only get executed once, at the very beginning of your application. What you need to do though is to check it constantly.
Think about it, if your calls to hitTestObject-calls only get executed once at the beginning, when you didn't even have a chance to drag one of your objects, it will always return false, right? Because your objects are still in their initial position (outside of the dragtest objecti must assume).
With an event listener for Event.ENTER_FRAME you check it once per frame instead. So even if all the results for hitTestObject are false, it will check them all again on the next frame (if you are currently dragging, controlled through a simple boolean called dragging).
var currentObject:MovieClip = null;
var dragging:Boolean = false;
initDrag(block1);
initDrag(block2);
initDrag(block3);
initDrag(block4);
addEventListener(Event.ENTER_FRAME, checkForHit);
function checkForHit(e:Event):void{
if(dragging){
if(block1.hitTestObject(dragtest)){
gotoAndStop("lose");
}
if(block2.hitTestObject(dragtest)){
gotoAndStop(27);
}
if(block3.hitTestObject( dragtest)){
gotoAndStop("lose");
}
if(block4.hitTestObject( dragtest)){
gotoAndStop("lose");
}
}
}
function initDrag(obj:MovieClip )
{
obj.addEventListener(MouseEvent.MOUSE_DOWN,startADrag);
stage.addEventListener(MouseEvent.MOUSE_UP,stopADrag);
}
function endDrag(obj:MovieClip )
{
obj.removeEventListener(MouseEvent.MOUSE_DOWN,startADrag);
stage.removeEventListener(MouseEvent.MOUSE_UP,stopADrag);
}
function startADrag(e:MouseEvent):void
{
currentObject = (MovieClip)(e.target);
var rect:Rectangle = new Rectangle(0,0,stage.stageWidth - currentObject.width,stage.stageHeight - currentObject.height + 100);
currentObject.startDrag(false,rect);
dragging = true;
}
function stopADrag(e:MouseEvent):void
{
if (currentObject != null)
{
currentObject.stopDrag();
dragging = false;
}
}

want to change the code actionscript2 to actionscript3?

i am newbie to flash.i need to change the below actionscript code to actionscript 3.0 code.
i am currently working on drag and drop. so i want to duplicate the movieclip while dragging i found the code on internet but it is actionscript 2.0 so please convert it to as3. the box is a instance name of a movieclip.
the code blocks are:
var num:Number = 0
box.onPress = function(){
num++
duplicateMovieClip(box ,"box"+num, _root.getNextHighestDepth())
_root["box"+num].startDrag();
}
box.onReleaseOutside = function(){
trace(_root["box"+num])
stopDrag();
}
If you dont want to use seperate .as file, follow this steps:
1- assign AS linkage to box movieClip (in library panel):
2- Select frame 1 on the timeline, and paste this code in the Actions panel:
var boxes:Array=[];
//var box:Box=new Box();
//addChild(box);
box.addEventListener(MouseEvent.MOUSE_DOWN,generateBox);
function generateBox(e:MouseEvent):void{
var newBox:Box=new Box();
newBox.x = e.target.x;
newBox.y = e.target.y;
newBox.startDrag();
newBox.addEventListener(MouseEvent.MOUSE_UP,stopD);
newBox.addEventListener(MouseEvent.MOUSE_DOWN,startD);
boxes.push(newBox);
addChild(newBox);
}
function startD(e:MouseEvent):void{
e.target.startDrag();
}
function stopD(e:MouseEvent):void{
e.target.stopDrag();
}
Unfortunately, there's no duplicateMovieClip analog in AS3, so you'll have to create a Class for your box movieClip template. Let's say it will be called BoxTemplate. (You can google how to create Classes for your library object). Add a Class with this name and add this code (event subscription in the constructor and a private event listener). You'll get something like this:
package
{
public class BoxTemplate
{
public function BoxTemplate()
{
addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
}
private function onMouseUp(e:MouseEvent):void
{
stopDrag();
}
}
Leave your present instance of this symbol on the stage. This is your code in the frame:
import flash.event.MouseEvent
box.addEventListener(MouseEvent.CLICK, onClick);
function onClick(e:MouseEvent):void
{
var newBox:BoxTemplate = new BoxTemplate();
newBox.x = e.target.x;
newBox.y = e.target.y;
addChild(newBox);
newBox.startDrag();
}
It will allow you to infinitely clone your boxes. Of course, you can add all of them in the array to keep the references.

AS3 Event Race Condition

I'm having some trouble solving a race condition that exists when I instantiate new MovieClip classes with some custom events that fire back before I can store the instances in an associative object.
Main Class
var pages:Object = {
"page1":"page1",
"page2":"page2"
};
for(var pageName:String in pages)
{
pages[pageName] = buildPage(pageName, onReady);
}
function buildPage(pageName:String, onReady:Function)
{
var newPage:MovieClip = new (getDefinitionByName(pageClass) as Class)();
newPage.addEventListener("PAGE_READY", onReady);
newPage.dispatchEvent(new Event("PAGE_CREATE"));
return newPage;
}
function onReady(e:Event)
{
for(var pageName:String in pages)
{
trace(typeof pages[pageName]);
}
}
Page 1 & 2 Classes extends MovieClip
function pageX()
{
this.addEventListener("PAGE_CREATE",this.onCreate);
}
function onCreate(e:Event)
{
this.graphics.beginFill(0xFF0000);
this.graphics.drawRect(0,0,200x200);
this.graphics.endFill();
this.dispatchEvent(new Event("PAGE_READY"));
}
Unfortunatley when this all fires off I get:
string
string
object
string
The original string object still exists before I can store the MovieClip instance for later reference. Any suggestions on how to beat this?
The code you posted does not depict a standard class.
Is this code on the movieclip frames or in separate files?
But as far as posted code I can see your issue is with the PAGE_CREATE event firing before the object has been added to the array.
your are doing
newPage.dispatchEvent(new Event("PAGE_CREATE"));
before you return the object.
You did not post the full classes so I really can't help you rewrite your code but, from what you posted I would remove the buildPage method completely and put the code in loop then dispatch the event after the object has been added to the array.
Also, another reason, best practice would be not to call a function from a loopif that function does not have a lot of code in it.
for(var pageName:String in pages)
{
var newPage:MovieClip = new (getDefinitionByName(pageClass) as Class)();
newPage.addEventListener("PAGE_READY", onReady);
pages[pageName] = newPage;
newPage.dispatchEvent(new Event("PAGE_CREATE"));
}