actionscript-3drag-and-dropairdragflash-cs5.5

My startDrag rectangle isn't where I set it to be


I've made a rectangle, a rectangular sprite and a circular sprite. The rectangular sprite has the exact same properties of my rectangle, and I set my circle to be positioned in the center of the stage, which is the middle of both of these rectangles.

After tracing the values of the rectangle, I can safely say that the rectangle is the same as the rect sprite. So then of course, if I wanted to drag the circle around the rectangle, it should stay within the bounds of it, right?

stop();
var isDragging:Boolean;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.display.Sprite;
import flash.geom.Point;


var px:Number = boundingBox.x;
var py:Number = boundingBox.y;
var h:Number = boundingBox.height;
var w:Number = boundingBox.width;
var box:Rectangle = new Rectangle(px,py,w,h);
trace(box);

var blob:Sprite = new Sprite();
blob.graphics.beginFill(0x000000);
blob.graphics.lineStyle(1.2, 0xFFFFFF);
blob.graphics.drawCircle(stage.stageWidth/2, stage.stageHeight/2, 18);
blob.graphics.endFill();
addChild(blob);

var box2:Sprite = new Sprite();
box2.graphics.lineStyle(1, 0xFFCC00);
box2.graphics.drawRect(px,py,w,h);
addChild(box2);

blob.addEventListener(MouseEvent.MOUSE_DOWN, drag);

function drag(event:MouseEvent):void {
   event.target.startDrag(false, box);
   isDragging = true

}

Well that doesn't seem be the case. Maybe I'm just a noob but I have no idea what's going on. When I run the scene, everything looks normal.

Preclick

The orange/dotted line is two rectangles I made, one is a movie clip that I used to set the properties of the rectangle I made in AS3 (dotted) and the orange is the AS3 sprite.

The circle is in the middle of the stage and it all looks as exactly how I wanted to be programmed.

But as soon as I click on it, it teleports over here.

pls fix

And when I try to drag it, it seems as if the box's top left corner has been translated to that point all the way down there, and it only drags around in the bottom-right quadrant of the stage, and even drags further off screen.

I'm not sure if the rectangle that I put into the startDrag function is somehow distorted from the actual rectangle.

I have no idea why this happens, because when I tried to do this using a movie clip that I added to the stage, everything worked fine. But as soon as I try to do it programmatically, everything goes tits up.

I'd appreciate some help on why this isn't working. Thanks for reading.


Solution

  • There's your problem:

    blob.graphics.drawCircle(stage.stageWidth/2, stage.stageHeight/2, 18);
    

    You draw this circle and only seem to care about the circle:

    if I wanted to drag the circle around the rectangle, it should stay within the bounds of it, right?

    No. Just because you added something to the .graphics doesn't mean As3 automagically knows that this is what should stay within the bounding Rectangle that's being passed to startDrag().

    The thing that stays within the bounding Rectangle is the registration point of the Sprite. That registration point is not where you drew the circle. It is in fact still at its default position of 0/0 in your first image. I added a green star at the registration point of blob. I also added a red rectangle that connects the registration point and your point. Think of this as some jelly that both your circle and the registration point are stuck in. This should help illustrate that just because you drew a circle somewhere doesn't mean that you are only dealing with that circle:

    image 1 with guides

    But as soon as I click on it, it teleports over here.

    As soon as you click, the movement limitation of startDrag() is applied. The registration point has to be in the Rectangle that you specified and that's exactly what happens. The whole red jelly blob is moved over so that the green star is in the Rectangle:

    image 2 with guides

    To solve this, first create your blob in a reasonable fashion, which means drawing the circle around the registration point at 0/0 and then moving the Sprite object around if you want to have the circle at another position. This way, there's no red jelly and the green star is right at the center of the circle. The visual helpers that I added become superfluous, because your perception of the situation now matches with how it actually is.

    const RADIUS:Number = 18;
    var blob:Sprite = new Sprite();
    blob.graphics.beginFill(0x000000);
    blob.graphics.lineStyle(1.2, 0xFFFFFF);
    blob.graphics.drawCircle(0, 0, RADIUS);
    blob.x = stage.stageWidth/2;
    blob.y = stage.stageHeight/2;
    blob.graphics.endFill();
    addChild(blob);
    

    This will keep the blob within the bounds for the most part or more precisely: its center point. If you want to keep the entire circle within the bounds, you'd have to subtract the circle from the bounding Rectangle Minkowski-style. Mink-what? yeah...err, that's a fancy way of saying: make the bounding Rectangle smaller by the radius, so that this smaller boundary can be applied to the center of the radius to ensure that the whole circle stays within the bigger original boundary.

    In your case Rectangle's inflate() should do:

    var px:Number = boundingBox.x;
    var py:Number = boundingBox.y;
    var h:Number = boundingBox.height;
    var w:Number = boundingBox.width;
    var box:Rectangle = new Rectangle(px,py,w,h);
    box.inflate(-RADIUS, -RADIUS);
    trace(box);