Search code examples
drag-and-dropstarling-framework

Starling ios drag object larger than screen and set boundaries


In Starling I have a very large MovieClip. The movieclip is avout 800% wider than the screen. If I use as3 I can set a boundary, in which I can drag the large MC. That way the MC cannot be dragged out of the screen (so an empty background is shown). Do you know if it is possible to do this in starling?

Pseudo-code below

    1. Add the mc to the stage
    2. Add eventlistener for touchEvent on MC
    3. Only drag the mc so its 0,0 coordinates are smaller than stage 0,0 coordinates
    4. Only drag the mc so its widthX,widthY are within stageWidthX, stageWidthY

Hope this makes sense? I just want to drag the large MC around so it always is within the screen area.

Cheers.

Ps: sorry for not including an example, but I have no clue as how to do this.


Solution

  • You can do this by examining the TouchPhase of the TouchEvent to see where the finger is dragging to, and then update the X position of the MovieClip only if the new position will falls within the stage boundaries.

    Here is an example, using a quad but would be just the same for a MovieClip:-

    package  
    {
        import starling.core.Starling;
        import starling.display.DisplayObject;
        import starling.display.Quad;
        import flash.geom.Point;
        import starling.display.Sprite;
        import starling.events.TouchEvent;
        import starling.events.Touch
        import starling.events.TouchPhase;
    
        public class QuadDrag extends Sprite
        {
            private var _startXPos:int = 0; // start of each drag
    
            public function QuadDrag() 
            {
                super();
    
                // create quad 8x stage size
                var quad:Quad = new Quad(Starling.current.stage.stageWidth*8, Starling.current.stage.stageHeight, 0xffffff);
                quad.setVertexColor(0, 0xff0000);
                quad.setVertexColor(1, 0x0000ff);
                quad.setVertexColor(2, 0xff0000);
                quad.setVertexColor(3, 0x0000ff);
                addChild(quad);
    
                // center quad on stage
                quad.x = Math.round(Starling.current.stage.stageWidth/2 - quad.width/2);
                quad.addEventListener(TouchEvent.TOUCH, onQuadTouch);
            }
    
            private function onQuadTouch(e:TouchEvent):void
            {
                var currentXPos:int = 0;
                var newXPos:int = 0;
                var touch:Touch = e.getTouch(stage);
                var target:DisplayObject = e.currentTarget as DisplayObject;
                if (touch == null)
                {
                    return;
                }
    
                var position:Point = touch.getLocation(stage);
    
                if (touch.phase == TouchPhase.BEGAN )
                {
                    // store start of drag x pos
                    _startXPos = target.globalToLocal(new Point(touch.globalX, touch.globalY)).x;
                }
                else
                if (touch.phase == TouchPhase.MOVED )
                {
                    // set limits for target x
                    var minX:int = -Math.round(target.width - Starling.current.stage.stageWidth);
                    var maxX:int = 0; 
    
                    // calculate new x based on touch's global coordinates
                    currentXPos = target.globalToLocal(new Point(touch.globalX, touch.globalY)).x;
                    newXPos = target.x + currentXPos - _startXPos;
    
                    if (newXPos <= maxX && newXPos>=minX) // set target's x if it falls within limits
                        target.x=newXPos;
                }
                else
                if (touch.phase == TouchPhase.ENDED )
                {
                    // touch released
                }
    
    
                return;
            }
        }
    
    }