-
TypeError: Error #1009: Cannot access a property or method of a null object reference
I am trying to do a drag and drop learning game, but the hittest is not working.
The graphics of the airplane (ap), the train (tn), and the covered wagon (cw) are supposed to be dragged to the timeline and then if the correct year is chosen, it should drop the graphic there. I keep getting the TypeError: Error #1009: Cannot access a property or method of a null object reference. I believe the checkTarget function is not working properly.
The timeline with the year is done with the line tool and the year is text. I then selected a portion of the timeline and converted it to a symbol with the instance name i.e. ttn_mc (target train movieclip). Is it possible the movieclip needs a larger "surface area" to click? or that the surface area needs to be the same or larger as the item that is be dropped?
The target movieclips themselves are not generated by an addChild, I just created them on the timeline with instance names. I have no linkage set up on each of the 3 targets and the instance names are not set up as variables in the .as files. I have 2 .as files: DragGame.as and DragDrop.as. The Document Class is DragGame.
The airplane, train, and covered wagon graphics are movieclips and added twice to the stage, once via manually dragged from library and once via the addChild method. None of them have instance names. The linkage is set up so that , for example, the train (TN) has a class of TN and the base class is DragDrop. Is it possible the target movieclips need to be added via addChild for them to be recognized in playback?
The target is being called by its instance name on the stage. But the program is not recognizing it. Could it be that I need i.e. "parent.ttn_mc" to go from one movie clip to another all on the same frame?
Also I do have an animation running for the first 600 frames. Then it stops to have this interaction with the user. So this code needs to work further down the timeline, not on frame 1...which is what I have seen other examples of drag/drop do.
The trace in the checkTarget function in DragGame.as does not show up in my output window.
Thanks in advance.
-
PHP Code:
package { import flash.display.MovieClip; import flash.events.MouseEvent; //import flash.display.DisplayObject; import DragDrop; import TN; import AP; import CW;
public class DragGame extends MovieClip { private var tn:TN; private var ap:AP; private var cw:CW;
trace("are you working?"); public function DragGame() { createPieces(); } trace("after createPieces"); private function createPieces():void { tn = new TN(); addChild(tn); tn.x = 169.9; tn.y = 90.8; tn.width = 370.9; tn.height = 68; tn.alpha = 0.3; tn._targetPiece = ttn_mc; tn.addEventListener(MouseEvent.MOUSE_UP, checkTarget); trace(ttn_mc); ap = new AP(); addChild(ap); ap.x = 496.6; ap.y = 169.9; ap.width = 162.8; ap.height = 110.2; ap.alpha = 0.3; ap._targetPiece = tap_mc.dropTarget ; ap.addEventListener(MouseEvent.MOUSE_UP, checkTarget); trace("after _targetPiece ap"); cw = new CW(); addChild(cw); cw.x = 44.8; cw.y = 193.1; cw.width = 197.0; cw.height = 94; cw.alpha = 0.3; cw._targetPiece = "TCW"; cw.addEventListener(MouseEvent.MOUSE_UP, checkTarget); trace("after _targetPiece cw"); } private function checkTarget(event:MouseEvent):void { if(event.currentTarget.hitTestObject(event.currentTarget._targetPiece)) { trace("whooooot!"); event.currentTarget.x = event.currentTarget._targetPiece.x; event.currentTarget.y = event.currentTarget._targetPiece.y; event.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, checkTarget); event.currentTarget.disable(); } else { event.currentTarget.x = event.currentTarget._origX; event.currentTarget.y = event.currentTarget._origY; } } } }
Last edited by 5TonsOfFlax; 11-04-2009 at 03:42 PM.
Reason: code formatting
-
DragDrop.as:
PHP Code:
package { import flash.display.MovieClip; import flash.events.MouseEvent; import flash.filters.DropShadowFilter; import flash.display.DisplayObject; public class DragDrop extends MovieClip { public var _targetPiece:*; public var _origX:Number; public var _origY:Number;
public function DragDrop() { _origX = this.x; _origY = this.y;
this.buttonMode = true; this.addEventListener(MouseEvent.MOUSE_DOWN,dragMovie); this.addEventListener(MouseEvent.MOUSE_UP, dropMovie); } private function dragMovie(event:MouseEvent):void { this.startDrag(); _origX = event.target.x; _origY = event.target.y; this.filters = [new DropShadowFilter()]; this.parent.addChild(this); } private function dropMovie(event:MouseEvent):void { this.stopDrag(); this.filters = []; event.target.stopDrag(); var myTargetName:String = "t" + event.target.name + "_mc"; var myTarget:DisplayObject = getChildByName(myTargetName); if (event.target.dropTarget != null && event.target.dropTarget.parent == myTarget){ event.target.removeEventListener(MouseEvent.MOUSE_DOWN, dragMovie); event.target.removeEventListener(MouseEvent.MOUSE_UP, dropMovie); event.target.buttonMode = false; event.target.x = myTarget.x; event.target.y = myTarget.y; } else { event.target.x = _origX; event.target.y = _origY; } } public function disable():void { this.buttonMode = false; this.removeEventListener(MouseEvent.MOUSE_DOWN,dragMovie); this.removeEventListener(MouseEvent.MOUSE_UP, dropMovie); } } }
Last edited by 5TonsOfFlax; 11-04-2009 at 03:42 PM.
Reason: code formatting
-
rorose, always format code with [code] or [php] tags. It makes it so much easier to read.
Also, can you point out the line which throws the error?
-
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display: isplayObject/_hitTest()
at flash.display: isplayObject/hitTestObject()
at DragGame/checkTarget()
You can see it does not give a line number.
How do I use the code tags on an .as file?
 Originally Posted by 5TonsOfFlax
rorose, always format code with [code] or [php] tags. It makes it so much easier to read.
Also, can you point out the line which throws the error?
-
Are you publishing for debug? It should give a line number, but someone more familiar with the IDE might be able to tell you what you need to do to configure it.
The stack trace tells us a bit more, specifically that it's not a 1009 error, but caused by sending a null object to hitTestObject in the checkTarget function.
currentTarget in checkTarget will be the item to which the event listener was added. So, it must have a _targetPiece property which is appropriately defined. It'd be great if you knew which one was causing the error, but let's go through all of them.
tn has _targetPiece set to ttn_mc. This could be null, but if it is, you should see a 'null' trace since you trace ttn_mc right after adding the event listener. Do you see "[object MovieClip]" or "null"?
ap has _targetPiece set to tap_mc.dropTarget. If that is null at the time it is assigned, then it would cause the error. Is it? Put in a trace to find out.
cw has _targetPiece set to the string "TCW", which is nonsense. It needs to be set to a DisplayObject, not the name of a DisplayObject. This one will cause an error, and needs to be fixed, but it would cause a different error than the one you're getting so it must be one of the other two.
You should also save event.currentTarget into a new variable within checkTarget which is typed appropriately. It'll catch some type errors and avoid a bunch of unnecessary lookups and typing.
PHP Code:
private function checkTarget(event:MouseEvent):void
{
var ec:MovieClip = MovieClip(event.currentTarget);
var target:DisplayObject = DisplayObject(ec._targetPiece);
if(ec.hitTestObject(target))
{
trace("whooooot!");
ec.x = target.x;
ec.y = target.y;
ec.removeEventListener(MouseEvent.MOUSE_UP, checkTarget);
ec.disable();
}
else
{
ec.x = ec._origX;
ec.y = ec._origY;
}
}
}
code tags are for this forum, not for your .as files. I just mean surround the code you post with [php] and [/php].
-
all are null
I did a trace on all 3 and got:
null
null
null
TypeError: Error #2007: Parameter hitTestObject must be non-null.
at flash.display: isplayObject/_hitTest()
at flash.display: isplayObject/hitTestObject()
at DragGame/checkTarget()
Here is my revised code, adding your snippet, and commenting out mine for the checkTarget function:
PHP Code:
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.display.DisplayObject;
import DragDrop;
import TN;
import AP;
import CW;
public class DragGame extends MovieClip
{
private var tn:TN;
private var ap:AP;
private var cw:CW;
public function DragGame()
{
createPieces();
}
private function createPieces():void
{
tn = new TN();
addChild(tn);
tn.x = 169.9;
tn.y = 90.8;
tn.width = 370.9;
tn.height = 68;
tn.alpha = 0.3;
tn._targetPiece = ttn_mc;
tn.addEventListener(MouseEvent.MOUSE_UP, checkTarget);
trace(ttn_mc);
ap = new AP();
addChild(ap);
ap.x = 496.6;
ap.y = 169.9;
ap.width = 162.8;
ap.height = 110.2;
ap.alpha = 0.3;
ap._targetPiece = tap_mc;
ap.addEventListener(MouseEvent.MOUSE_UP, checkTarget);
trace(tap_mc);
cw = new CW();
addChild(cw);
cw.x = 44.8;
cw.y = 193.1;
cw.width = 197.0;
cw.height = 94;
cw.alpha = 0.3;
cw._targetPiece = tcw_mc;
cw.addEventListener(MouseEvent.MOUSE_UP, checkTarget);
trace(tcw_mc);
}
/* private function checkTarget(event:MouseEvent):void
{
if(event.currentTarget.hitTestObject(event.currentTarget._targetPiece))
{
trace("whooooot!");
event.currentTarget.x = event.currentTarget._targetPiece.x;
event.currentTarget.y = event.currentTarget._targetPiece.y;
event.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, checkTarget);
event.currentTarget.disable();
}
else
{
event.currentTarget.x = event.currentTarget._origX;
event.currentTarget.y = event.currentTarget._origY;
}
}*/
private function checkTarget(event:MouseEvent):void
{
var ec:MovieClip = MovieClip(event.currentTarget);
var target:DisplayObject = DisplayObject(ec._targetPiece);
if(ec.hitTestObject(target))
{
trace("whooooot!");
ec.x = target.x;
ec.y = target.y;
ec.removeEventListener(MouseEvent.MOUSE_UP, checkTarget);
ec.disable();
}
else
{
ec.x = ec._origX;
ec.y = ec._origY;
}
}
}
}
-
Well, that's your problem. You are setting the _targetPiece properties to things that don't exist (yet?). If those target clips are added later, you will have to set the _targetPiece properties after they are around to reference. That means you'd have to keep references to tn, ap, and cw in a bigger scope so that you can refer to them at a later time too.
-
Link to my movie online
Hi again,
Here is the link to my movie:
http://www.designsbydegrees.com/ca/
The modes of transportation are supposed to be dragged down to the timeline. But, that doesn't happen till around frame 615 or so.
And there is a mask that allows the timeline to reveal from left to right.
Any other ideas how to implement what you are saying? Should I get you the fla?
-
My fla is too large to upload here.
-
Can I email it to you? It is 4.3 MB
-
oh, and I don't have any actions on my main timeline, except for a stop(); on the last frame.
-
bigger scope? how?
How would I do what you are suggesting below? Add actionscript to a frame in my timeline so that it is referenced later in time? How do I create a bigger scope?
 Originally Posted by 5TonsOfFlax
Well, that's your problem. You are setting the _targetPiece properties to things that don't exist (yet?). If those target clips are added later, you will have to set the _targetPiece properties after they are around to reference. That means you'd have to keep references to tn, ap, and cw in a bigger scope so that you can refer to them at a later time too.
-
You could, but I can't open it here. If it's CS4, I can't open it at all.
I'd suggest keeping references to tn, ap, and cw at the class level, and making a function to set up the targets and mouse-up listeners. Call that function from the frame where the targets actually exist.
PHP Code:
package { import flash.display.MovieClip; import flash.events.MouseEvent; import flash.display.DisplayObject; import DragDrop; import TN; import AP; import CW;
public class DragGame extends MovieClip { private var tn:TN; private var ap:AP; private var cw:CW;
public function DragGame() { createPieces(); } private function createPieces():void { tn = new TN(); addChild(tn); tn.x = 169.9; tn.y = 90.8; tn.width = 370.9; tn.height = 68; tn.alpha = 0.3; ap = new AP(); addChild(ap); ap.x = 496.6; ap.y = 169.9; ap.width = 162.8; ap.height = 110.2; ap.alpha = 0.3; cw = new CW(); addChild(cw); cw.x = 44.8; cw.y = 193.1; cw.width = 197.0; cw.height = 94; cw.alpha = 0.3; } public function setUpTargets():void{ tn._targetPiece = ttn_mc; tn.addEventListener(MouseEvent.MOUSE_UP, checkTarget); trace(ttn_mc);
ap._targetPiece = tap_mc; ap.addEventListener(MouseEvent.MOUSE_UP, checkTarget); trace(tap_mc);
cw._targetPiece = tcw_mc; cw.addEventListener(MouseEvent.MOUSE_UP, checkTarget); trace(tcw_mc); }
private function checkTarget(event:MouseEvent):void { var ec:MovieClip = MovieClip(event.currentTarget); var target:DisplayObject = DisplayObject(ec._targetPiece); if(ec.hitTestObject(target)) { trace("whooooot!"); ec.x = target.x; ec.y = target.y; ec.removeEventListener(MouseEvent.MOUSE_UP, checkTarget); ec.disable(); } else { ec.x = ec._origX; ec.y = ec._origY; } } } }
call setUpTargets from the frame where the targets exist.
-
not null anymore, but still snapping back
Thank you! So I got the values to return with real values and not null, as you can see below. The problem is still that the modes of transportation keep snaping back and recognizing the hit target area. Below is the code of the DragDrop.as that is being imported into the DragGame.as file we were just working on.
[object TTN]
[object TAP]
[object TCW]
PHP Code:
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.filters.DropShadowFilter;
import flash.display.DisplayObject;
public class DragDrop extends MovieClip
{
public var _targetPiece:*;
public var _origX:Number;
public var _origY:Number;
public function DragDrop()
{
_origX = this.x;
_origY = this.y;
this.buttonMode = true;
this.addEventListener(MouseEvent.MOUSE_DOWN,dragMovie);
this.addEventListener(MouseEvent.MOUSE_UP, dropMovie);
}
private function dragMovie(event:MouseEvent):void
{
this.startDrag();
_origX = event.target.x;
_origY = event.target.y;
this.filters = [new DropShadowFilter()];
this.parent.addChild(this);
}
private function dropMovie(event:MouseEvent):void
{
this.stopDrag();
this.filters = [];
event.target.stopDrag();
var myTargetName:String = "t" + event.target.name + "_mc";
var myTarget:DisplayObject = getChildByName(myTargetName);
if (event.target.dropTarget != null && event.target.dropTarget.parent == myTarget){
event.target.removeEventListener(MouseEvent.MOUSE_DOWN, dragMovie);
event.target.removeEventListener(MouseEvent.MOUSE_UP, dropMovie);
event.target.buttonMode = false;
event.target.x = myTarget.x;
event.target.y = myTarget.y;
} else {
event.target.x = _origX;
event.target.y = _origY;
}
}
public function disable():void
{
this.buttonMode = false;
this.removeEventListener(MouseEvent.MOUSE_DOWN,dragMovie);
this.removeEventListener(MouseEvent.MOUSE_UP, dropMovie);
}
}
}
-
not dropping on target
It is still not dropping on the target. Even though no other error is coming up.
-
I'm still not getting my: trace("whooooot!");
-
Your target determination code is really weird. Since these DragDrops have a _targetPiece property already set, you should use that rather than composing a name and then getting a child by name. Since the targets are not children of the DragDrops, the getChildByName will return null, and it'll never match.
PHP Code:
private function dropMovie(event:MouseEvent):void{ this.stopDrag(); this.filters = []; stopDrag(); if (dropTarget != null && _targetPiece.contains(dropTarget)){ removeEventListener(MouseEvent.MOUSE_DOWN, dragMovie); removeEventListener(MouseEvent.MOUSE_UP, dropMovie); buttonMode = false; x = _targetPiece.x; y = _targetPiece.y; } else { x = _origX; y = _origY; } }
Also, you should change the type of _targetPiece from * to DisplayObject.
-
Since the dropMovie code would move the instance off the target, the hittest would never return true. I think the above code should fix it.
-
TypeError: Error #1010: A term is undefined and has no properties.
at DragDrop/dropMovie()
PHP Code:
package { import flash.display.MovieClip; import flash.events.MouseEvent; import flash.filters.DropShadowFilter; import flash.display.DisplayObject; public class DragDrop extends MovieClip { public var _targetPiece:*; public var _origX:Number; public var _origY:Number;
public function DragDrop() { _origX = this.x; _origY = this.y;
this.buttonMode = true; this.addEventListener(MouseEvent.MOUSE_DOWN,dragMovie); this.addEventListener(MouseEvent.MOUSE_UP, dropMovie); } private function dragMovie(event:MouseEvent):void { this.startDrag(); _origX = event.target.x; _origY = event.target.y; this.filters = [new DropShadowFilter()]; this.parent.addChild(this); } private function dropMovie(event:MouseEvent):void { this.stopDrag(); this.filters = []; stopDrag(); if (dropTarget != null && _targetPiece.contains(dropTarget)){ removeEventListener(MouseEvent.MOUSE_DOWN, dragMovie); removeEventListener(MouseEvent.MOUSE_UP, dropMovie); buttonMode = false; x = _targetPiece.x; y = _targetPiece.y; } else { x = _origX; y = _origY; } } public function disable():void { this.buttonMode = false; this.removeEventListener(MouseEvent.MOUSE_DOWN,dragMovie); this.removeEventListener(MouseEvent.MOUSE_UP, dropMovie); } } }
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|