ActionScript 3: how do you compare if the object where you clicked on is that type of object - actionscript-3

I have a red box called mc1_mc and every time when you drag on it you get a new little blue box added to the stage. Yhe idea is that you can drag those blue boxes too. however I dont know how to detect them.
this is the code:
var newBlok:Boolean;
var blokIndex:int = 0;
var blokje:blok;
var huidigBlok:DisplayObject;
var prullenBak:DisplayObject = getChildByName("groen_mc");
stage.addEventListener(MouseEvent.MOUSE_DOWN,pickUp);
stage.addEventListener(MouseEvent.MOUSE_UP,dropIt);
function pickUp(event:MouseEvent):void
{
trace(event.currentTarget);
trace(event.target);
trace(event.target.name);
if (event.target.name == "mc1_mc")
{
trace("hoi");
blokje = new blok;
blokje.name = "blokje" + blokIndex;
blokIndex++;
addChild(blokje);
blokje.startDrag(true);
}
if (event.target.type == blok)
{
trace("blok");
}
//blokjeVast = blokje;
}
function dropIt(event:MouseEvent):void
{
event.target.stopDrag();
}
he wont ever come to the line: trace("blok");
even when the object i clicked on gives:
[object Stage]
[object blok]
blokje0
for the lines.
trace(event.currentTarget);
trace(event.target);
trace(event.target.name);
does anyone know how to do check if its a object of type "blok"?

To check whether an object is of a certain type, you can use the is operator.
So, you should change this:
if (event.target.type == blok)
{
trace("blok");
}
To this:
if(event.target is blok)
{
trace("blok");
}
And if the target is of type blok, you should see the trace.
There's one caveat here. ìs tells you if an object is of a certain type. Since a class can extend other classes and implement interfaces, you should check for the most derived or specific one first (if you want to distinguish between, say, Sprite and MovieClip).
var mc:MovieClip = new MovieClip();
if(mc is MovieClip) {
trace("is MovieClip");
} else if(mc is Sprite) {
trace("is Sprite");
}
// even if mc is a MovieClip, your code will never get in the else block
if(mc is Sprite) {
trace("is Sprite");
} else if(mc is MovieClip) {
trace("is MovieClip");
}

Related

how to hittestObject multiple movie clips at the same time

I have a simple drag and drop to the target system it works fine except I don't someone to be able to drop where there is a movie clip already. decided to hittestObject on the target to check if there is a movie clip there. in if there is it just sends the object back to its original position. however, when I try to code the same thing for more than one object it only works on one of the objects.
I've tried putting my objects in an array and putting them in a variable however I can only hittestobject one object in the array or variable at a time when I need to hitestobject multiple objects at the same time. Please help
if (char2.hitTestObject(target0))
{
slot0=true;
}
if (!char2.hitTestObject(target0))
{
slot0=false;
}
if (char2.hitTestObject(target1))
{
slot1=true;
}
if (!char2.hitTestObject(target1))
{
slot1=false;
}
if (char2.hitTestObject(target2))
{
slot2=true;
}
if (!char2.hitTestObject(target2))
{
slot2=false;
}
I need to also hittestobject on char1 and char0. this code works however if I try to simply duplicate the code and replace char2 with char1 only one other code blocks with work please help. Also an alternative like
if (char2 || char1.hitTestObject(target0))
{
slot0=true;
}
would work that would be helpful. please help show me how to do it or let me know if it's even possible. thank you!!
Full Code:
var slot0:Boolean;
var slot1:Boolean;
var slot2:Boolean;
addEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler);
function fl_EnterFrameHandler(et:Event):void
{
trace(slot0);
}
// Unlike the Object class, that allows String keys only
// the Dictionary class allows you to store and
// access data by the object instance.
var theValids:Dictionary = new Dictionary;
var theCharacters:Dictionary = new Dictionary;
// We'll store the original (x,y) coordinates here.
var theOrigin:Point = new Point;
// The Sprite class is the superclass of MovieClip, furthermore,
// the startDrag method defined for Sprite class, so unless you
// create your own dragging code, you are bound to use Sprites,
// while you cannot drag SimpleButtons and TextFields this way.
// We'll store the current dragged object here.
var theObject:Sprite;
var theChar:Sprite;
// This first argument is the object you want to be draggable.
// The "...targets:Array" means you can call this method with
// any number of arguments, the first one is mandatory, the
// rest will be passed in a form of Array (empty Array if you
// call this method with a single argument).
function setupDraggable(source:Sprite, ...targets:Array):void
{
// Make the object draggable.
source.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
source.mouseChildren = false;
source.mouseEnabled = true;
source.buttonMode = true;
// Keep the list of the object's targets so it can be
// retrieved later by the key of the object itself.
theValids[source] = targets;
}
// Ok, let's setup the objects and link them to their designated
// targets. The whole point of the rest of the code is to make
// this one part as simple as it possible: you just edit
// these lines to tell which one objects go where.
// This object can be dropped to a single target.
// setupDraggable(obj_1 , target1);
// These objects can go to two targets each.
// setupDraggable(obj_10, target1, target10);
// setupDraggable(obj_2 , target2, target20);
stage.addEventListener(MouseEvent.MOUSE_DOWN, setslot1);
function setslot1(e:MouseEvent):void{
if (character1.hitTestObject(target0))
{
slot0=true;
}
if (!character1.hitTestObject(target0))
{
slot0=false;
}
if (character1.hitTestObject(target1))
{
slot1=true;
}
if (!character1.hitTestObject(target1))
{
slot1=false;
}
if (character1.hitTestObject(target2))
{
slot2=true;
}
if (!character1.hitTestObject(target2))
{
slot2=false;
}
}
stage.addEventListener(MouseEvent.MOUSE_DOWN, setslot2);
function setslot2(e:MouseEvent):void{
if (character0.hitTestObject(target0))
{
slot0=true;
}
if (!character0.hitTestObject(target0))
{
slot0=false;
}
if (character0.hitTestObject(target1))
{
slot1=true;
}
if (!character0.hitTestObject(target1))
{
slot1=false;
}
if (character0.hitTestObject(target2))
{
slot2=true;
}
if (!character0.hitTestObject(target2))
{
slot2=false;
}
}
stage.addEventListener(MouseEvent.MOUSE_DOWN, setslot3);
function setslot3(e:MouseEvent):void{
if (char2.hitTestObject(target0))
{
slot0=true;
}
if (!char2.hitTestObject(target0))
{
slot0=false;
}
if (char2.hitTestObject(target1))
{
slot1=true;
}
if (!char2.hitTestObject(target1))
{
slot1=false;
}
if (char2.hitTestObject(target2))
{
slot2=true;
}
if (!char2.hitTestObject(target2))
{
slot2=false;
}
}
// This one object can be dropped to any of targets.
setupDraggable(character0, target0, target1, target2, redslot);
setupDraggable(character1, target0, target1, target2, greenslot);
setupDraggable(char2, target0, target1, target2, blueslot);
// The MOUSE_DOWN event handler.
function onDown(e:MouseEvent):void
{
if (char2.hitTestObject(target0))
{
slot0=true;
}
if (!char2.hitTestObject(target0))
{
slot0=false;
}
if (char2.hitTestObject(target1))
{
slot1=true;
}
if (!char2.hitTestObject(target1))
{
slot1=false;
}
if (char2.hitTestObject(target2))
{
slot2=true;
}
if (!char2.hitTestObject(target2))
{
slot2=false;
}
// Clean-up. Remove the reference, the object is no longer
// being dragged, so you won't need to keep it.
//theObject = null;
// Get the reference to the object under the mouse.
theObject = e.currentTarget as Sprite;
// Keep the object's initial position.
theOrigin.x = theObject.x;
theOrigin.y = theObject.y;
// Put the dragged object on top of anything else.
// We are operating in the parent context of all these
// objects here so there's no need to address anObj.parent.
setChildIndex(theObject, numChildren - 1);
// Start dragging.
theObject.startDrag(true);
// Listen to the MOUSE_UP event, which could happen offstage
// and out of the dragged object, so the only reliable
// way is to listen it from the Stage. That's why we
// are keeping theObject reference as an additional
// variable, without relying on event's data.
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
}
// The MOUSE_UP event handler.
function onUp(e:MouseEvent):void
{
// Unsubscribe the MOUSE_UP event handler.
//stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
// Stop the dragging process.
theObject.stopDrag();
// Let's assume there could be more than a single collision.
// We need to figure the one target that is closest.
var theTarget:DisplayObject;
var theDistance:int = 100000;
// Store the dragged object position so we can
// measure distances to the valid collisions, if any.
var thePlace:Point = theObject.localToGlobal(new Point);
// Now, the magic. Lets browse through the
// valid targets and see if there's a collision.
for each (var aTarget:DisplayObject in theValids[theObject])
{
if (theObject.hitTestObject(aTarget))
{
// Let's see if the current collision is closer
// to the dragged object, than the previous one
// (if any, that's what initial 100000 for).
var aPlace:Point = aTarget.localToGlobal(new Point);
var aDistance:int = Point.distance(aPlace, thePlace);
if (aDistance < theDistance)
{
theTarget = aTarget;
theDistance = aDistance;
}
}
}
// If there's at least one collision,
// this variable will not be empty.
if (theTarget)
{
// Make the object non-interactive.
// theObject.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
// theObject.mouseEnabled = false;
// theObject.buttonMode = false;
// Glue the dragged object to the center of the target.
theObject.x = theTarget.x;
theObject.y = theTarget.y;
}
else
{
// If we're here, that means there was no valid collisions,
// lets return the object to its designated place.
theObject.x = theOrigin.x;
theObject.y = theOrigin.y;
}
if(slot0==true){
if (theObject.hitTestObject(target0))
{
theObject.x = theOrigin.x;
theObject.y = theOrigin.y;
}
}
if(slot1==true){
if (theObject.hitTestObject(target1))
{
theObject.x = theOrigin.x;
theObject.y = theOrigin.y;
}
}
if(slot2==true){
if (theObject.hitTestObject(target2))
{
theObject.x = theOrigin.x;
theObject.y = theOrigin.y;
}
}
// Clean-up. Remove the reference, the object is no longer
// being dragged, so you won't need to keep it.
//theObject = null;
}
Only setslot3 works setslot 1&2 dont work and this happens anytime i put more than one of this specific code.

AS3 - How do you call previous currentTarget from within a different event?

I have a dropdown menu that lets you select an item to be placed on the stage. The item is drag and droppable so I use event.currentTarget.startDrag(); to start the drag. Ok, everything works fine so far.
However, I also need to be able to rotate the item while it is being dragged (using the spacebar).
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);
function myKeyDown(e:KeyboardEvent):void{
if (e.keyCode == Keyboard.SPACE){
rotate++;
if (rotate == 5){
rotate = 1;
}
WHATGOESHERE?.gotoAndStop(rotate);
}
If I hardcode in an instance name of an object everything works fine - so the rotate function is working properly. The problem is, how can I reference event.currentTarget from the startDrag function while inside of the keyDown event?
My first thought was to set event.currentTarget to a variable and then calling the variable from within the keyDown event. However, targetHold = event.currentTarget; does not seem to record the instance name of the object being clicked...
public var targetHold:Object = new Object;
function ClickToDrag(event:MouseEvent):void {
event.currentTarget.startDrag();
targetHold = event.currentTarget;
trace ("targetHold " + targetHold);
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);
function myKeyDown(e:KeyboardEvent):void{
if (e.keyCode == Keyboard.SPACE){
rotate++;
if (rotate == 5){
rotate = 1;
}
targetHold.gotoAndStop(rotate); //does not work
}
}
function ReleaseToDrop(event:MouseEvent):void {
event.currentTarget.stopDrag();
}
As you click the object, it should have focus. If you register the listener for the KeyboardEvent on the object and not on the stage, it will be .currentTarget.
Here's an example of what I have in mind. Right after starting the drag, add the listener to the same object instead of the stage.
event.currentTarget.startDrag();
event.currentTarget.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);
The proper way of doing this would be to define all the functionality in a class. Within a self contained class, you would not need any .currentTarget.
Here is how I would do this: (well, actually I'd follow #null's advice and encapsulate it in a sub class that all your dragable objects would extend, but that is a little broad so this will do)
public var targetHold:MovieClip; //don't make a new object, just create the empty var
public function YourConstructor(){
//your other constructor code
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown); //don't add the listener in the click function
}
private function clickToDrag(event:MouseEvent):void {
if(targetHold) ReleaseToDrop(null); //safeguard in case flash lost the focus during the mouse up
targetHold = event.currentTarget as MovieClip; //assign the current target. Might as well cast it as MovieClip and get code completion benefits
targetHold.startDrag();
trace ("targetHold " + targetHold);
}
private function myKeyDown(e:KeyboardEvent):void{
//check if target hold exists
if (targetHold != null && e.keyCode == Keyboard.SPACE){
rotate++;
if (rotate == 5){
rotate = 1;
}
targetHold.gotoAndStop(rotate);
}
}
private function ReleaseToDrop(event:MouseEvent):void {
if(targetHold) targetHold.stopDrag();
targetHold = null;
}

Need an object to become 'unclickable' behind certain objects. As3 Flash Cs4

How can I make a clickable movieclip 'hide' behind another object. Eg.. I have a rabbit movieclip - he is clickable - as he walks behind a tree(MC) he needs to hide behind that tree.
At the moment, if I click on the tree - the mouse click seems to ignore the tree completely and I can still click the unseen rabbit.
var HitCount:Number = 10;
var RabbitG1X:Number = 0;
var RabbitG1Y:Number = 0;
var RabbitG2X:Number = 0;
var RabbitG2Y:Number = 0;
Mouse.hide();
stage.addEventListener(MouseEvent.MOUSE_MOVE, follow);
function follow(evt:MouseEvent)
{
Cursor_mc.x =mouseX;
Cursor_mc.y=mouseY;
}
stage.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(event:MouseEvent):void
{
if (Cursor_mc.hitTestObject(RabbitG1_mc))
{
trace ("you fed rabbit1 ");
RabbitG1_mc.x = RabbitG1X + 5000;
RabbitG1H_mc.x = RabbitG1X + 1271.85;
RabbitG1H_mc.y = RabbitG1Y + 184.05;
HitCount = HitCount -1;
Dec_txt.text = "" + HitCount + "";
}
if (Cursor_mc.hitTestObject(RabbitG2_mc))
{
trace ("you fed rabbit2 ");
RabbitG2_mc.x = RabbitG2X + 5000;
RabbitG2H_mc.x = RabbitG2X + 1271.85;
RabbitG2H_mc.y = RabbitG2Y + 184.05;
HitCount = HitCount -1;
Dec_txt.text = "" + HitCount + "";
}
if (HitCount ==0)
{
trace("You fed all the rabbits");
}
}
I tried adding this to the tree mc to see if I could kill the mouse when it moved over tree.
Tree2MC.addEventListener(MouseEvent.CLICK, solid);
function solid(e:MouseEvent):void{
Tree2MC.mouseEnabled = false;
}
However, it isn't ideal. I really need a clickable object to hide if it goes behind another object on the stage. So if he is half hidden and I click on the part of the MC still revealed, it will click.. And it didn't work.
First, there is no need to use the hitTest code to figure out what was clicked. You can use the mouse event's .target property to figure that out - that will also solve your issue of knowing if the tree was clicked or the rabbit.
For example:
function clickHandler(event:MouseEvent):void {
if (event.target == RabbitG1_mc){
//.....do you stuff
if (event.target == RabbitG2_mc){
Now, one thing to point out, is the .target of an event could also be a child object of a rabbit (if your rabbit MC had other objects inside it). So to make sure it's consistent, you can do something like this when you initialize your rabbits:
RabbitG1_mc.mouseChildren = false;
RabbitG2_mc.mouseChildren = false;
Alternatively, you could just add mouse event listeners to the rabbits directly instead of one listener on the stage that will catch everything. This way, if an object (tree) is in front of them (and is mouse enabled), the click event will dispatch on the tree instead of the rabbit and the clickHandler won't run.
RabbitG1_mc.addEventListener(MouseEvent.CLICK, clickHandler);
RabbitG2_mc.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler(event:MouseEvent):void {
//event.currentTarget is a reference to what you attached the listener to
switch(event.currrentTarget){
case RabbitG1_mc:
//..do your code
break;
case RabbitG2_mc:
//..do your code
break;
}
}

ActionScript 3.0 Objects Null on Stage

I'm creating a game where the user bakes a cake. If the user drags something (for example a jug of water) onto the next object (e.g saucepan) it should disappear from stage. The section of code in question is:
function mouseDownHandler(event:MouseEvent):void {
event.currentTarget.startDrag(true);
}
function mouseUpHandler(event:MouseEvent):void{
var obj = event.currentTarget;
var target = obj.dropTarget;
if (target != null){
test_match(target, obj);
}
obj.stopDrag();
trace(dropTarget);
}
function test_match(target, obj){
if (target == saucePan && obj == jug)
{
removeChild(obj);
}
}
The trace inside the mouseUpHandler function shows up "null" whenever I drop the jug on an object on the stage, hense why I don't think the code executes and removes the jug from stage.
obj.dropTarget vs. dropTarget
These are two different things.

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;
}
}