Copy link to clipboard
Copied
Hi,
Hoping someone can help as have got 90% of the way through a project and hit a wall at the final (end-of-level-baddie) problem.
I'm currently embedding old AS2 activities (build by a second party - now not operating/contactable) into a new AS3 menu system.
Most of them I've managed to port across and embed without issue. Unfortunately embedding the drag and drop activity is proving to be, for want of a better phrase, a complete drag.
I've managed to decompile the code, so have put a few trace statements in to find out what might be going wrong. Looking in the collision detection part of the code, the problem appears to be that when the activity is embedded, although the index of the drag clip is returned fine with its corresponding index number, the index of the drop clip is returned as 'undefined'.
The activity works fine in a standalone flash player, with both indexes returning their respective numbers. However not so when it's embedded.
I'm guessing that this is a levels issue, but is there any easy way that I can force the AS2 drag and drop game to act as self-contained and ignore its parent holding clip?
Thanks in advance
reference to _level0 is the problem.
on the first frame of the as2 movie, use:
var tl:MovieClip=this;
then replace all _level0 references with tl.
you may also be able to use:
this._lockroot=true in that first frame and then replace all _level0 references with _root.
p.s. you may have other problems if something like eval(somedroptarget) is used.
Copy link to clipboard
Copied
what code in the as2 files is failing when loaded into an as3 parent?
Copy link to clipboard
Copied
Hi kglad,
Thanks for replying (you've helped me out before 🙂 )
A search of the classes reveals only one mention of getDepth() on a text field, which is irrelevant at the mo (as the engine's just creating image drag and drops)
The main activity stage is created by an EngineClass (which drives all the activities I've been adapting, but wasn't a problem with less layer critical ones).
There are three lines I can see where the activity stage is created using 'getNextHighestDepth()'
this.mWhere.createEmptyMovieClip("activity_mc", this.mWhere.getNextHighestDepth());
this.mWhere.createEmptyMovieClip("activityMask_mc", this.mWhere.getNextHighestDepth());
this.mWhere.createEmptyMovieClip("toolbars_mc", this.mWhere.getNextHighestDepth());
All the drags and drops are then created within this activity_mc. When I run the activity as standalone (where it works), and drag an item onto a drop zone, the traces I set up on the Drag and Drop items report back the following:
DragObject: _level0.activity_mc.container_mc.dropItem2.dropSkin.greyBorder.whiteBG
DropArea: _level0.activity_mc.container_mc.dropItem2.dropSkin.greyBorder
When I run it embedded in the AS2 wrapper it then fires back the following after an attempted drop:
DragObject: undefined
DropArea: undefined
...and the item refuses to drop on the dropzone, returning to where it came from.
The tiny amount of knowledge I have makes me (probably mistakenly) assume that if I could place the activity_mc layer on root, then everything would be contained within the embedded clip and the layering wouldn't go so wonky. But in reality I've got no idea! To make matters worse, the original drag and drop activity is itself inside another as2 wrapper which contains some navigation buttons...
Copy link to clipboard
Copied
reference to _level0 is the problem.
on the first frame of the as2 movie, use:
var tl:MovieClip=this;
then replace all _level0 references with tl.
you may also be able to use:
this._lockroot=true in that first frame and then replace all _level0 references with _root.
p.s. you may have other problems if something like eval(somedroptarget) is used.
Copy link to clipboard
Copied
That sounds promising, however I looked for _level0 references in both the drag and drop classes/file and its AS2 wrapper and the only reference I could find is within a print function (so I guess this is irrelevant).
function tbPrint()
{
var __reg2 = new Object();
__reg2.page = _level0;
__reg2.pageWidth = 796;
__reg2.pageHeight = 536;
__reg2.boundary = {xMin: 0, xMax: 796, yMin: 0, yMax: 536};
__reg2.options = {printAsBitmap: true};
__reg2.frame = 1;
var __reg3 = new Array(__reg2);
this.mWrapper.printPages(__reg3);
}
I've tried this._lockroot=true in my AS2 wrapper, but then couldn't find any _level0 references in the rest of the code.
Copy link to clipboard
Copied
Haha. I'm collecting the full set of problems.
I'd put a trace in the checkDropArea function earlier next to an eval...
function checkDropArea()
{
clearInterval(this.mDragInterval);
var bHit = false;
var dropObject = eval(this._droptarget)
trace("DragObject: "+eval(this._droptarget))
var dropClip = dropObject._parent
trace("CheckDropArea: "+dropClip)
etc...
Copy link to clipboard
Copied
you listed it here
DragObject: _level0.activity_mc.container_mc.dropItem2.dropSkin.greyBorder.whiteBG
DropArea: _level0.activity_mc.container_mc.dropItem2.dropSkin.greyBorder
and like i mentioned, there are other ways to have _level0 references in the as2 swf without explicitly using it.
Copy link to clipboard
Copied
Thanks for all your help.
I could see the trace reporting _level0 but wasn't sure where this was being explicitly specified in the code.
I've locked both the original activity wrapper.swf to root, and the draganddrop.swf to root.
When I run the activity embedded within the AS3 menu system, it's now showing everything as being run from _root (which is good), which now leads me to believe that it's the line:
var dropObject = eval(this._droptarget)
...that's causing the issues, as you mentioned.
Copy link to clipboard
Copied
that's a problem.
you may be able to use the flash string/array methods to work-around it but it would require case-by-case handling.
Copy link to clipboard
Copied
I don't mind case-by-case handling as there only appears to be a single appearance of it being used to create a MovieClip.
I've done a Google search for flash string/array workarounds for eval(this._droptarget) but am drawing blanks. What is the approved method, if any, please?
BTW, Thanks for your help so far on this, kglad. You're a lifesaver!
Copy link to clipboard
Copied
i don't know that there's a good/bad way to do this, but if there's only one place (and the drop targets all have the same parent), replace
var dropObject = eval(this._droptarget)
what you should replace it with depends on the path to the drop targets. use trace(dropObject) to see that path.
Copy link to clipboard
Copied
I hope I was heading that way. This is where I am at the moment.
When I run it as standalone, drag an item onto a dropzone and trace dropObject, or eval(this._droptarget), I get a result in the following format
_level0.activity_mc.container_mc.dropItem3.dropSkin.greyBorder.whiteBG
(The _level0 only appears in standalone - when it's embedded, all the references are to root, however the eval(this._droptarget) bit returns 'undefined')
When you trace simply 'this._droptarget', without the eval bit, it returns in the form of
/activity_mc/container_mc/dropItem3/dropSkin/greyBorder/whiteBG
This led me to think that if I used something along the lines of:
var dropObjectS:String = this._droptarget
var dropObject:MovieClip = this[((str_replace(dropObjectS,"/",".")).substr(1))]
Where the bottom line takes all except the first slash of the string and replaces the slashes with dots, then I might be approaching the syntax churned out by eval(this_droptarget). The square brackets were hopefully meant to render the string back into an object.
Nothing as yet, unsurprisingly...
Copy link to clipboard
Copied
use:
var tl:MovieClip=this
on frame 1 of your as2 swf's main timeline.
then use:
var dropObjectS:String = this._droptarget
var dropObject:MovieClip = tl[dropObjectS.split("/").join(".")];
// p.s. split/join is faster than replace
// p.p.s. you will need to use a path to tl (ie, use trace(this) on the main timeline and the timeline where dropObjectS is defined to see the path that needs to be used.)
// p.p.p.s. please mark helpful/correct responses.
Copy link to clipboard
Copied
That's still not quite getting it. I've put the code on the first frame, and changed the dropObject code, but it's still returning 'undefined' when I trace dropObject.
Thanks for all your help and patience so far.
Copy link to clipboard
Copied
what do those two trace(this) statements show and what path are you using to tl?
Copy link to clipboard
Copied
Ah - ok.
In standalone mode, the main swf trace this returns:
_level0
...and the example in the game engine.as file returns:
_level0.activity_mc.container_mc.dragItem3
When it's embedded (which is the case I'm most concerned about getting working) they return:
_root.activityMask
...and the example in the game engine.as file returns:
_root.activityMask.activity_mc.container_mc.dragItem3
Copy link to clipboard
Copied
so the reference to tl is
this._parent._parent._parent.tl
from engine.as
ie, use:
var dropObjectS:String = this._droptarget
var dropObject:MovieClip = this._parent._parent._parent.tl[dropObjectS.split("/").join(".")];
Copy link to clipboard
Copied
Still giving me undefined when I trace dropObject.
If I trace out the string that's being generated between the square brackets, I get:
.activityLayer.instance79.instance80.activityMask.activity_mc.container_mc.dropItem3.dropSkin.greyBorder.whiteBG
Is that right that it starts with a leading '.'? Or should I trim that off?
Just a thought.
Copy link to clipboard
Copied
trim it,
var dropObject:MovieClip = this._parent._parent._parent.tl[dropObjectS.split("/").join(".").substr(1)];
Copy link to clipboard
Copied
Was hoping that was going to nail it, but it's still returning 'undefined' when I trace dropObject.
I was so hoping to avoid the AS3 rebuild... 😞
Copy link to clipboard
Copied
use
this._lockroot=true on frame 1 of the main timeline and try:
var dropObject:MovieClip =_root[dropObjectS.split("/").join(".").substr(1)];
Copy link to clipboard
Copied
OK. Thanks for that.
Not working, but when I trace _root on the timeline and within the engine.as I get the same result now:
_root.activityMask
activityMask is the MovieClip that the whole thing is loaded into in my AS2Bridge swf. This then contains the draganddrop.swf and its wrapper.swf.
tracing 'this._droptarget' from within engine.as gives me
/activityLayer/instance79/instance80/activityMask/activity_mc/container_mc/dropItem3/dropSkin/greyBorder/whiteBG
Which is the whole path from my AS3.swf...
/activityLayer/instance79/instance80/
through the AS2Bridge...
/activityMask
Into the wrapper and draganddrop.swf...
/activity_mc/container_mc/dropItem3/dropSkin/greyBorder/whiteBG
Going to sleep on this now, but thanks again for all your help in pointing me in (hopefully) the right direction. Cheers again.
Copy link to clipboard
Copied
Good old sleep.
Cracked it this 6.30am GMT thanks to all your advice on _root and strings.
In the end the thing that wasn't working was trying to reference the nested string in between the square brackets. I believe it would have required separating out each nested MovieClip element into their own square brackets for it to work, e.g. [movie1][movie2][movie3]... which I couldn't easily think of a way to do, especially if the number of nested clips varied dependent on whether it was embedded/standalone/of if I changed the layer order/nesting in the main navigation.
So, instead, I used the traces I'd set up to work out a rule to pull out the info needed:
_root = _root.activityMask
this: _root.activityMask.activity_mc.container_mc.dragItem0
this._droptarget (dropObjectS) = /activityLayer/instance79/instance80/activityMask/activity_mc/container_mc/dropItem1/dropSkin/greyBorder/whiteBG
Basically the crucial (changing) part of the this._droptarget is the 'dropItem1' bit. The rest of the path varies dependent on whether it's being run standalone or embedded. Knowing that this drag and drop activity never uses more than 10 dropzones (and the numbering starts from '0') I realised that you could pull this info out with the following:
dropObjectS.substr(dropObjectS.lastIndexOf("dropItem"),9)
Which I then put into this:
var dropObject:MovieClip =_root.activity_mc.container_mc[dropObjectS.substr(dropObjectS.lastIndexOf("dropItem"),9)];
And suddenly the beast lives again and I avoid having to recreate it in AS3(!)
Once again, thanks so much for all your help on this, kglad. You've been invaluable.
Copy link to clipboard
Copied
i'm embarrassed to say i know/knew that about referencing that object:
var dropObjectA:Array=dropObjectS.split("/");
bar dropObject:Movieclip;
switch(dropObjectA.length){
case 2:
dropObject=_root[dropObjectA[1]];
break;
}
case 3:
dropObject=_root[dropObjectA[1][dropObjectA[2]]];
break;
}
case 4:
dropObject=_root[dropObjectA[1][dropObjectA[2][dropObjectA[3]]]];
break;
}
case 5:
dropObject=_root[dropObjectA[1][dropObjectA[2][dropObjectA[3][dropObjectA[4]]]]];
break;
}
case 6:
dropObject=_root[dropObjectA[1][dropObjectA[2][dropObjectA[3][dropObjectA[4][dropObjectA[5]]]]]];
break;
}
etc
Find more inspiration, events, and resources on the new Adobe Community
Explore Now