View Full Version : event.target issues
Zippo
02-04-2009, 05:04 AM
so i am trying to define a new MovieClip variable and assign it the value of event.target in the function. I keep getting this error "1118: Implicit coercion of a value with static type Object to a possibly unrelated type flash.display:MovieClip."
i know that this works, i have defined variables like this before, i just can't figure out why it isn't working now. maybe i just need a second pair of eyes to look at it, who knows. :confused:
import fl.transitions.Tween;
import fl.transitions.easing.*;
var p:Number = 0;
var scale_factor:Number = 0.4;
var tween_duration:Number = 0.6;
var photo_folder:String = "thumbnails/";
var file_extension:String = ".jpg";
var photo_array:Array = new Array("400x300_01",
"400x300_02",
"400x300_03",
"400x300_04",
"400x300_05",
"400x300_06");
var total_photo:Number = photo_array.length;
var photo_group:MovieClip = new MovieClip();
stage.addChild(photo_group);
for( p = 0; p < total_photo; p++ )
{
var pic_request:URLRequest = new URLRequest( photo_folder + photo_array[p] + file_extension );
var pic_loader:Loader = new Loader();
pic_loader.load(pic_request);
pic_loader.contentLoaderInfo.addEventListener(Even t.COMPLETE, on_loaded);
}
function on_loaded(event:Event):void
{
var image_bm:Bitmap = new Bitmap();
var image_mc:MovieClip = new MovieClip();
image_bm = Bitmap(event.target.content);
image_bm.x = - image_bm.width * 0.5;
image_bm.y = - image_bm.height * 0.5;
image_bm.smoothing = true;
var bg_width = image_bm.width + 16;
var bg_height = image_bm.height + 16;
image_mc.addChild(image_bm);
image_mc.scaleX = image_mc.scaleY = scale_factor;
image_mc.graphics.beginFill(0x000000);
image_mc.graphics.drawRect( - bg_width * 0.494, - bg_height * 0.494, bg_width, bg_height );
image_mc.graphics.beginFill(0xFFFFFF);
image_mc.graphics.drawRect( - bg_width * 0.5, - bg_height * 0.5, bg_width, bg_height );
image_mc.graphics.endFill();
image_mc.buttonMode = true;
image_mc.addEventListener( MouseEvent.MOUSE_OVER, bring_it );
image_mc.addEventListener( MouseEvent.MOUSE_DOWN, drag_it );
image_mc.addEventListener( MouseEvent.CLICK, drop_it );
photo_group.addChild(image_mc);
var positionX:Number = 100 + Math.random() * 250;
var positionY:Number = 600 + Math.random() * 60;
var rotate:Number = Math.random() * 120 - 60;
new Tween(image_mc, "x", Strong.easeOut, 100, positionX, 2, true);
new Tween(image_mc, "y", Strong.easeOut, 800, positionY, 2, true);
new Tween(image_mc, "rotation", Strong.easeOut, 0, rotate, 2, true);
}
function bring_it(event:MouseEvent):void
{
var mc:MovieClip = event.target;
photo_group.addChild(mc);
}
function drag_it(event:MouseEvent):void
{
var mc:MovieClip = event.target;
mc.addEventListener( Event.ENTER_FRAME, moving );
new Tween(mc, "rotation", Strong.easeOut, mc.rotation, 0, tween_duration, true);
new Tween(mc, "scaleX", Strong.easeOut, mc.scaleX, 1, tween_duration, true);
new Tween(mc, "scaleY", Strong.easeOut, mc.scaleY, 1, tween_duration, true);
}
function drop_it(event:MouseEvent):void
{
var rotate:Number = Math.random() * 120 - 60;
var mc:MovieClip = event.target;
mc.removeEventListener( Event.ENTER_FRAME, moving );
new Tween(mc, "rotation", Strong.easeOut, mc.rotation, rotate, tween_duration, true);
new Tween(mc, "scaleX", Strong.easeOut, mc.scaleX, scale_factor, tween_duration, true);
new Tween(mc, "scaleY", Strong.easeOut, mc.scaleY, scale_factor, tween_duration, true);
}
function moving(event:Event):void
{
var mc:MovieClip = event.target;
mc.x = mouseX;
mc.y = mouseY;
}
thank you in advance for the help :)
Mazoonist
02-04-2009, 05:11 AM
Inside your handler functions, you have to "cast" your event.target to MovieClip type:
var mc:MovieClip = MovieClip(event.target);
lordofduct
02-04-2009, 05:11 AM
there is no way the compiler knows if the object being returned by target (which is typed Object) is actually a MovieClip...
so say:
var mc:MovieClip = event.target as MovieClip;
the thing is IF target doesn't extend MovieClip, then mc will be null. Which means the next two lines will fail... so you might want to say:
function moving(event:Event):void
{
if (event.target is MovieClip)
{
var mc:MovieClip = event.target as MovieClip;
mc.x = mouseX;
mc.y = mouseY;
}
}
...
edit (mazoonist and I posted at the same time)
of course the syntax that I show does the same thing mazoonist does. That's all just personal preference, both work the same way. I just prefer the as/is method because my eyes are accustomed to reading
SomeClass( ... )
as a construction of a new object with some params.
x33905
02-04-2009, 05:11 AM
Try coercing it to the MovieClip class. Not sure if it will work, but it's the first thing that came to mind.
example:
var mc:MovieClip = MovieClip(event.target);
x33905
02-04-2009, 05:15 AM
Good call Mazoonist, I suppose coercion wasn't the right term for this situation since it actually is of the movieclip class :D
lordofduct
02-04-2009, 05:18 AM
Good call Mazoonist, I suppose coercion wasn't the right term for this situation since it actually is of the movieclip class :D
It is called coercion actually, you were right... because you don't know what target is (maybe you do as the programmer, but the program doesn't as it isn't sure who called the function)... so you coerce it to be MovieClip, and if it fails then it returns null.
x33905
02-04-2009, 05:22 AM
Ah. Good ol' terminology always messin' me up.
Mazoonist
02-04-2009, 05:49 AM
The bottom line is that in the original code:
var mc:MovieClip = event.target;
mc is definitely a MovieClip variable because you've strictly typed it as one. But the event.target might not be, because there are other types of InteractiveObjects capable of dispatching mouse events, and this listener might be assigned to any number of different objects. You know that each of these listeners is being attached to MovieClips only. But the compiler has no way of knowing that. By casting, you are telling it that you know these objects are MovieClips.
The way I understand it, unless you're doing something inside the handler that's specific to MovieClips, like "gotoAndPlay" or anything to do with frames, you could just as easily cast to something more generic, like InteractiveObject.
Maybe how you cast is a matter of personal preference, like lordofduct says, whatever looks best to your eyes. To me,
MovieClip(event.target)
looks like something that says "force event.target into a MovieClip mold." But I have no problem with the as operator, either. And as you find out on page 149 of Essential Actionscript 3.0, there are two cases where the former way won't work: the Date class and the Array class (for legacy reasons, as Colin Moock points out). To cast these, you must use the as operator. So if you use the as operator you are covered in all cases. On the other hand, how often are you going to cast something as a Date or an Array? Not that you would never run into this, I'm not saying that. But you are certainly going to be casting to display object types a lot, and either way works just fine.
senocular
02-04-2009, 12:19 PM
edit (mazoonist and I posted at the same time)
of course the syntax that I show does the same thing mazoonist does. That's all just personal preference, both work the same way. I just prefer the as/is method because my eyes are accustomed to reading
SomeClass( ... )
as a construction of a new object with some params.
That's not necessarily true. There are some important differences between those two types of casts.
var newValue:ClassType = ClassType(oldValue);
^ Uses a conversion function. Depending on the class, this could change the value or just recast the value passed into the new type. As a developer you have no control over this function, though some internal classes such as XML, Number, Array, etc. do additional work to convert semi-unrelated values (such as strings) rather than just recasting it.
If the cast fails, an error is thrown.
var newValue:ClassType = oldValue as ClassType;
^ Uses the as operator. The as operator is a kind of combination of the is operator and a cast. The as operator evaluates a value to determine if it is of the type compared against. If it is, the cast is made and the original value is returned. Compared to conversion functions, as is faster.
Values are never converted from one type to another.
If the cast fails, null is returned, there is no error.
With as, you will need to make sure the resulting value is not null before you try to use it, otherwise your code will fail throwing null reference errors. For casting, you may need to encase the call in a try..catch block.
Additionally understand that no change in value will be made. For example:
var num = 3.75;
var inter:int = num as int;
trace(inter); // 0
// ^ not null since int can't be null, instead null
// is returned and the int type converts it to 0
inter = int(num);
trace(inter); // 3
Now, it should be noted that there are some side affects to the conversion functions. For example, Array() will create a new array using the value passed as its one and only element since it favors conversion over casting. So, if you have an array that you simply want to cast as Array, you should use as. Otherwise you'll have a new array with your original array in it.
var arr = [1,2,3];
trace(Array(arr).length); // 1
trace((arr as Array).length); // 3
Zippo
02-04-2009, 04:36 PM
You all have been very helpful. it is much appreciated.
var mc:MovieClip as event.target;
has worked properly and has not given me any errors.
now the only other thing i wish i had done from the start is brought the pictures in thru XML, because now i want to add a text box with descriptions. why is it as a designer i never think of these things when i'm creating them lol:p
x33905
02-04-2009, 07:11 PM
Good info Senocular, thanks for the explanation.
lordofduct
02-04-2009, 09:28 PM
OH, I thought the conversion function was slower. Heh.
I still prefer the as way of doing it. Just for readability and consistancy in my mannerism. I also don't like the error thrown by the conversion function, I can just check null with as.
Good to know which is faster though.
senocular
02-04-2009, 09:44 PM
OH, I thought the conversion function was slower. Heh.
To be honest, I haven't done tests myself; I heard of others that have and that's what the outcome was. If you heard otherwise its quite possible as may be faster or it can be circumstantial. : )
lordofduct
02-04-2009, 09:51 PM
I just tried:
package {
import flash.display.Sprite;
import flash.utils.getTimer;
[SWF(height="800", width="600")]
public class test extends Sprite
{
protected var mc:Sprite;
public function test( )
{
var obj:Object = new Sprite();
var t:Number = getTimer();
var i:int = 10000000;
while( i-- )
{
var test:Sprite = obj as Sprite;
}
t = getTimer() - t;
var q:Number = getTimer();
i = 10000000;
while( i-- )
{
var test:Sprite = Sprite( obj );
}
q = getTimer() - q;
trace ( t, q, t - q );
}
}
}
as worked faster:
1324 1889 -565
half a second faster for 10000000 iterations
senocular
02-04-2009, 10:00 PM
Good to know! I'll update my comments
Zippo
02-05-2009, 04:12 AM
so i have failed miserably trying to import the image data using xml.
this is the code that works
var p:Number = 0;
var scale_factor:Number = 0.4;
var tween_duration:Number = 0.6;
var photo_folder:String = "thumbnails/";
var file_extension:String = ".jpg";
var photo_array:Array = new Array("400x300_01",
"400x300_02",
"400x300_03",
"400x300_04",
"400x300_05",
"400x300_06");
var total_photo:Number = photo_array.length;
var photo_group:MovieClip = new MovieClip();
stage.addChild(photo_group);
for( p = 0; p < total_photo; p++ )
{
var pic_request:URLRequest = new URLRequest( photo_folder + photo_array[p] + file_extension );
var pic_loader:Loader = new Loader();
pic_loader.load(pic_request);
pic_loader.contentLoaderInfo.addEventListener(Even t.COMPLETE, on_loaded);
}
what i tried to do was this
var p:Number = 0;
var scale_factor:Number = 0.4;
var tween_duration:Number = 0.6;
/*var photo_folder:String = "thumbnails/";
var file_extension:String = ".jpg";
var photo_array:Array = new Array("400x300_01",
"400x300_02",
"400x300_03",
"400x300_04",
"400x300_05",
"400x300_06");*/
var xml:XML;
var picList:XMLList;
var total_photo:Number = picList.length;
var photo_group:MovieClip = new MovieClip();
stage.addChild(photo_group);
for( p = 0; p < total_photo; p++ )
{
//var pic_request:URLRequest = new URLRequest( photo_folder + photo_array[p] + file_extension );
var pic_request:URLRequest = new URLRequest();
var pic_loader:Loader = new Loader();
pic_loader.load(pic_request);
pic_loader.contentLoaderInfo.addEventListener(Even t.COMPLETE, on_loaded);
and i get another "null object reference" in my output box.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at erik_baldwin_dot_com_fla::MainTimeline/erik_baldwin_dot_com_fla::frame2()
why is it referencing frame 2???:confused:
::EDIT::
i forgot to add my on_loaded function
function on_loaded(event:Event):void
{
xml = XML(event.target.data);
picList = xml.children();
var image_bm:Bitmap = new Bitmap();
var image_mc:MovieClip = new MovieClip();
image_bm = Bitmap(event.target.content);
image_bm.x = - image_bm.width * 0.5;
image_bm.y = - image_bm.height * 0.5;
image_bm.smoothing = true;
var bg_width = image_bm.width + 16;
var bg_height = image_bm.height + 16;
image_mc.addChild(image_bm);
image_mc.scaleX = image_mc.scaleY = scale_factor;
image_mc.graphics.beginFill(0x000000);
image_mc.graphics.drawRect( - bg_width * 0.494, - bg_height * 0.494, bg_width, bg_height );
image_mc.graphics.beginFill(0xFFFFFF);
image_mc.graphics.drawRect( - bg_width * 0.5, - bg_height * 0.5, bg_width, bg_height );
image_mc.graphics.endFill();
image_mc.buttonMode = true;
image_mc.addEventListener( MouseEvent.MOUSE_OVER, bring_it );
image_mc.addEventListener( MouseEvent.MOUSE_DOWN, drag_it );
image_mc.addEventListener( MouseEvent.CLICK, drop_it );
photo_group.addChild(image_mc);
var positionX:Number = 100 + Math.random() * 250;
var positionY:Number = 600 + Math.random() * 60;
var rotate:Number = Math.random() * 120 - 60;
new Tween(image_mc, "x", Strong.easeOut, 100, positionX, 2, true);
new Tween(image_mc, "y", Strong.easeOut, 800, positionY, 2, true);
new Tween(image_mc, "rotation", Strong.easeOut, 0, rotate, 2, true);
}
|
vBulletin® v3.8.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.