A Flash Developer Resource Site

Results 1 to 9 of 9

Thread: [RESOLVED] Another parallax question... confining movement

  1. #1
    Senior Member
    Join Date
    Oct 2004
    Location
    London
    Posts
    186

    resolved [RESOLVED] Another parallax question... confining movement

    Hi,

    I have the script below which controls three movieclips on different layers to scroll up/down/left/right depending on the mouse position. These three layers are visible within a frame. The effect works nicely, except that there are no constraints to stop the movieclips scrolling infinitely.

    How do I make it so that the moviclips edges never come into view... i.e. the scrolling stops when the edge of the background clip touches the edge of the frame?

    Actionscript Code:
    var verticalCenter:Number = Stage.width/2;
    var horizontalCenter:Number = Stage.height/2;

    function parallax (layer, speed) {
        if (mask2.hitTest(_xmouse,_ymouse,true)) {
            var distanceX = _root._xmouse-verticalCenter;
            var distanceY = _root._ymouse-horizontalCenter;
            if (_xmouse > verticalCenter) {    
                layer._x -= distanceX*speed;
            } else {
                layer._x += distanceX*-speed;        
            }
            if (_ymouse > horizontalCenter) {
                layer._y -= distanceY*speed;
            } else {
                layer._y += distanceY*-speed;
            }
        }
    }

    trees1.onEnterFrame = function() { parallax(this, 1/40); }
    trees2.onEnterFrame = function() { parallax(this, 1/60); }
    trees3.onEnterFrame = function() { parallax(this, 1/80); }

    Many thanks for any input!

  2. #2
    var x:Number = 1; x /= 0;
    Join Date
    Dec 2004
    Posts
    549
    Actionscript Code:
    if(mc._width>=Stage.width){
        if(mc._x+(mc._width/2)<Stage._width)mc._x=Stage.width-(mc._width/2);
        if(mc._x-(mc._width/2)>0)mc.x=mc._width/2;
    }
    same concept goes for _y and height/_height

  3. #3
    Senior Member
    Join Date
    Oct 2004
    Location
    London
    Posts
    186
    Hi Zippy,
    thanks for helping out!

    I'm still having trouble with this... I adapted your code, but the movement is not quite right, because the different layers will reach the boundaries at different times (because they are travelling at different speeds).

    Here is what I tried:
    Actionscript Code:
    if (layer._width>=Stage.width) {
        if (layer._x + (layer._width/2) < (_root.mask2._width+limit)) layer._x = (_root.mask2._width+limit) - (layer._width/2);
       if (layer._x - (layer._width/2) > limit) layer._x = limit+(layer._width/2);
    }

    Here's a link to the file, in case you can help me out!

  4. #4
    Senior Member
    Join Date
    Oct 2004
    Location
    London
    Posts
    186
    bump for help!

    I can't find the answer in any of the tutorials I've searched through.

  5. #5
    var x:Number = 1; x /= 0;
    Join Date
    Dec 2004
    Posts
    549
    Code:
    var numberOfLayers=3
    //here you set your speeds.
    trees1.speed=1/40;
    trees2.speed=1/60;
    trees3.speed=1/80;
    //instead of tracking mouse distance on each frame, we'll keep track of
    	//the total distance that the movie clips have been offset by
    var totDistX=0;
    var totDistY=0;
    //minimum and maximum x/y
    var minDistX=Number.NEGATIVE_INFINITY;
    var maxDistX=Number.POSITIVE_INFINITY;
    var minDistY=Number.NEGATIVE_INFINITY;
    var maxDistY=Number.POSITIVE_INFINITY;
    //These are the viewing boundaries. They are currently set for the entire stage.
    	//Set them to whatever you require
    var leftBound=0;
    var rightBound=Stage.width;
    var topBound=0;
    var bottomBound=Stage.height;
    //Set these, too
    verticalCenter=Stage.height/2;
    horizontalCenter=Stage.width/2;
    
    for(i=1;i<=numberOfLayers;i++){
    	_root["trees"+i].initX=_root["trees"+i]._x;
    	_root["trees"+i].initY=_root["trees"+i]._y;
    	var temp=_root["trees"+i].getBounds();
    	minDistX=Math.max(minDistX,(temp.xMin-leftBound+_root["trees"+i]._x)/_root["trees"+i].speed);
    	maxDistX=Math.min(maxDistX,(temp.xMax-rightBound+_root["trees"+i]._x)/_root["trees"+i].speed);
    	minDistY=Math.max(minDistY,(temp.yMin-topBound+_root["trees"+i]._y)/_root["trees"+i].speed);
    	maxDistY=Math.min(maxDistY,(temp.yMax-bottomBound+_root["trees"+i]._y)/_root["trees"+i].speed);
    }
    onEnterFrame=function(){
    	if (mask2.hitTest(_xmouse,_ymouse,true)) {
            totDistX += _root._xmouse-verticalCenter;
            totDistY += _root._ymouse-horizontalCenter;
    		if(totDistX>maxDistX)totDistX=maxDistX;
    		else if(totDistX<minDistX)totDistX=minDistX;
    		if(totDistY>maxDistY)totDistY=maxDistY;
    		else if(totDistY<minDistY)totDistY=minDistY;
    		for(i=1;i<=numberOfLayers;i++){
    			_root["trees"+i]._x=_root["trees"+i].initX-totDistX*_root["trees"+i].speed;
    			_root["trees"+i]._y=_root["trees"+i].initY-totDistY*_root["trees"+i].speed;
    		}
        }
    }
    Basically, I used math to figure out the maximum distance it could go in any direction and still show all movie clips correctly.

    Hope this helps! Ask me if you have any questions about it.
    -Zippy Dee
    Ted Newman

  6. #6
    Senior Member
    Join Date
    Oct 2004
    Location
    London
    Posts
    186
    Oh my gosh, Ted!

    Thank you for taking the time to help me with this! I really appreciate it!
    Maths is really not my strong point, but I get the gist of what the code is doing. I will do my best to study it and understand it fully.

    I'm so happy it works!

    I was going to ask you where you set the xMax,xMin,yMin,yMax, but I see in the Flash Help that these are obtained from the getBounds command - something new to me!

    the .NEGATIVE_INFINITY and .POSITIVE_INFINITY are new to me too.

    Ah, so much left to learn!!

    Thank you so much! You're a star! I owe you! May the universe bring you good kama!

  7. #7
    Junior Member
    Join Date
    Jul 2010
    Posts
    6

    Unhappy Same issue here!

    Hey, I have the same problem, well not quite actually.

    I'm making this in AS 3 and I got the parallax movement, the panning and the limits down, but they function quite shabby.

    Download my SWF for an example: (CLICK start, then the window).

    double-u,double,u,doubleuDOTgetloudDOTnl/bestanden/Final/Expat_jungle.swf (no links )

    When you scroll up and down or left and right, the images will change a bit. The bottom image starts at x = 0 and y = 0, but when you scroll to the right and then back to the left, the image is cropped, just a tad. I assume this is due to the incremental movement and the limits.

    I put this code in a class, which is quite long:

    Actionscript Code:
    package
    {
        //Import Displays
        import flash.display.*;
       
        //Import Events
        import flash.events.*;
       
        //Import User Classes
        import com.greensock.*;
        import com.greensock.easing.*;
        import com.own.Globalvars;

        public class Mapmenu extends MovieClip
        {
            //Declare Maplevel vars
            public var mapLevel1:MapLevel1;
            public var mapLevel2:MapLevel2;
            public var mapLevel3:MapLevel3;
            public var mapLevel4:MapLevel4;
            public var mapLevel5:MapLevel5;
            //Declare Maplevel Containers
            public var mapLevelContainer:MovieClip;
            public var mapLevel1Container:MovieClip;
            public var mapLevel2Container:MovieClip;
            public var mapLevel3Container:MovieClip;
            public var mapLevel4Container:MovieClip;
            public var mapLevel5Container:MovieClip;
            //Declare interactive Premises
            public var homePremise:HomePremise;
                   
            //Declare Premise Menus
            public var premiseMenu:PremiseMenu;
                                   
            public function Mapmenu()
            {
                //Initialize init function
                initMap();
            }
           
            function initMap():void
            {
                //Put Maplevel movieclips in vars
                mapLevel1 = new MapLevel1();
                mapLevel2 = new MapLevel2();
                mapLevel3 = new MapLevel3();
                mapLevel4 = new MapLevel4();
                mapLevel5 = new MapLevel5();
               
                //Put them in Containers
                mapLevel1Container = new MovieClip();
                mapLevel1Container.addChild( mapLevel1 );                                  
                mapLevel2Container = new MovieClip();
                mapLevel2Container.addChild( mapLevel2 );
                mapLevel3Container = new MovieClip();
                mapLevel3Container.addChild( mapLevel3 );
                mapLevel4Container = new MovieClip();
                mapLevel4Container.addChild( mapLevel4 );
                mapLevel5Container = new MovieClip();
                mapLevel5Container.addChild( mapLevel5 );
               
                //Put the Containers on stage
                mapLevelContainer = new MovieClip;
                mapLevelContainer.addChild(mapLevel1Container);
                mapLevelContainer.addChild(mapLevel2Container);
                mapLevelContainer.addChild(mapLevel3Container);
                mapLevelContainer.addChild(mapLevel4Container);
                mapLevelContainer.addChild(mapLevel5Container);
                this.addChild(mapLevelContainer);
               
                //Position the Maplevels
                mapLevel1.y = -900;
                mapLevel2.y = -700;
                mapLevel3.y = -500;
                mapLevel4.y = -300;
                mapLevel5.y = 100;
               
                //Position the Containers
                mapLevel1Container.x = 0;
                mapLevel2Container.x = 0;
                mapLevel3Container.x = 0;
                mapLevel4Container.x = 0;
                mapLevel5Container.x = 0;
               
                //Position the main Container
                mapLevelContainer.x = 0;
               
                //Put Premise Movieclips in vars
                homePremise = new HomePremise();
               
                //Put Premise Menu Movieclips in vars
                premiseMenu = new PremiseMenu();
                           
                //Put Premisenames into a new string
                //homePremiseName = new String();
               
                //Set Buttonmode for Premises
                mapLevel5.homePremise.buttonMode = true;
                           
                addEventListener( Event.ENTER_FRAME, mapInteractivity );
                //Set up stageproperties
            }
           
            public function mapInteractivity(event:Event):void
            {
                //trace("container Y: " + mapLevelContainer.y);
                addEventListener( Event.ENTER_FRAME, scrollMovement );
                addEventListener (Event.ENTER_FRAME, premiseInteractivity );
            }
           
            private function scrollMovement ( event:Event ):void
            {
                var speed:Number = 10;
               
                if (mapLevelContainer.x < -50)
                {
                    //Find stage left quarter point        
                    var leftPt:uint = stage.stageWidth * .25;
                    //Find the difference between mouseX and leftPt
                    var leftDiff:int = mouseX - leftPt;
                    //Convert it to %
                    var leftPerc:Number = leftDiff / 160;
                    //Move it
                    if (leftDiff < 0)
                    {
                        mapLevelContainer.x -= leftPerc * speed;
                        mapLevel1Container.x -= leftPerc * (speed + 0);
                        mapLevel2Container.x -= leftPerc * (speed + 7);
                        mapLevel3Container.x -= leftPerc * (speed + 14);
                        mapLevel4Container.x -= leftPerc * (speed + 21);
                        mapLevel5Container.x -= leftPerc * (speed + 28);
                    }
                }
               
                if (mapLevelContainer.x > - 600)
                {
                    //Find stage right quarter point
                    var rightPt:uint = stage.stageWidth * .75;
                    //Find the difference between mouseX and rightPt
                    var rightDiff:int = mouseX - rightPt;
                    //Convert it to %
                    var rightPerc:Number = rightDiff / 160;
                    //Move it
                    if (rightDiff > 0)
                    {
                        mapLevelContainer.x -= rightPerc * speed;
                        mapLevel1Container.x -= rightPerc * (speed + 0);
                        mapLevel2Container.x -= rightPerc * (speed + 7);
                        mapLevel3Container.x -= rightPerc * (speed + 14);
                        mapLevel4Container.x -= rightPerc * (speed + 21);
                        mapLevel5Container.x -= rightPerc * (speed + 28);
                       
                    }
                }
               
                if (mapLevelContainer.y < 430)
                {
                    //Find stage up fifth point
                    var upPt:uint = stage.stageHeight * .2;
                    //Find the difference between mouseY and upPt
                    var upDiff:int = mouseY - upPt;
                    //Convert it to %
                    var upPerc:Number = upDiff / 160;
                    //Move it
                    if (upDiff < 0)
                    {
                        mapLevelContainer.y -= upPerc * speed;
                        mapLevel1Container.y -= upPerc * (speed + 0);
                        mapLevel2Container.y -= upPerc * (speed + 7);
                        mapLevel3Container.y -= upPerc * (speed + 14);
                        mapLevel4Container.y -= upPerc * (speed + 21);
                        mapLevel5Container.y -= upPerc * (speed + 28);
                    }
                }
               
                if (mapLevelContainer.y > 30)
                {
                    //Find stage down fifth point
                    var downPt:uint = stage.stageHeight * .8;
                    //Find the difference between mouseY and downPt
                    var downDiff:int = mouseY - downPt;
                    //Convert it to %
                    var downPerc:Number = downDiff / 160;
                    //Move it
                    if (downDiff > 0)
                    {
                        mapLevelContainer.y -= downPerc * speed;
                        mapLevel1Container.y -= downPerc * (speed + 0);
                        mapLevel2Container.y -= downPerc * (speed + 7);
                        mapLevel3Container.y -= downPerc * (speed + 14);
                        mapLevel4Container.y -= downPerc * (speed + 21);
                        mapLevel5Container.y -= downPerc * (speed + 28);
                    }
                }          
            }  
           
            public function premiseInteractivity ( event:Event):void
            {
                this.mapLevel5.homePremise.addEventListener(MouseEvent.MOUSE_OVER, onHomePremiseMouseover);
                this.mapLevel5.homePremise.addEventListener(MouseEvent.MOUSE_OUT, onHomePremiseMouseout);
                this.mapLevel5.homePremise.addEventListener(MouseEvent.CLICK, onHomePremiseClick);
            }
           
            public function onHomePremiseMouseover (event:MouseEvent):void
            {
               
               
                this.addChild(premiseMenu);
                premiseMenuPosition();
                //return homePremiseName;
                Globalvars.data.premiseName = "My home";
            }
           
            public function onHomePremiseMouseout (event:MouseEvent):void
            {
                this.removeChild(premiseMenu);
            }
           
            public function onHomePremiseClick (event:MouseEvent):void
            {
                trace("hoi");
            }
           
            public function premiseMenuPosition():void
            {
                addEventListener(Event.ENTER_FRAME, moveMouse);

                //premiseMenu.x = stage.mouseX;
                //premiseMenu.y = stage.mouseY;
                //Check if premiseMenu isn't out of bounds, if it is, place it back
                if (premiseMenu.y + premiseMenu.height > stage.stageHeight)
                {
                    premiseMenu.y = stage.stageHeight - premiseMenu.height;
                }
                if (premiseMenu.y < 0)
                {
                    premiseMenu.y = 0;
                }
               
                if (premiseMenu.x < 0)
                {
                    premiseMenu.x = 0;
                }
                if (premiseMenu.x + premiseMenu.width > stage.stageWidth)
                {
                    premiseMenu.x = stage.stageWidth - premiseMenu.width;
                }  
            }
           
            public function moveMouse(event:Event):void
            {
                //premiseMenu follows mouse
                var yEnd = mouseY;
                var xEnd = mouseX;
                var me = event.target;

                premiseMenu.x = (xEnd-me.x)/4;
                premiseMenu.y = (yEnd-me.y)/4;
            }
        }      
    }

    You can ignore the premiseMenu stuff, this is about the menu which pops up when you roll over the house.

    The main problem here is that the image is cropped and its offset. When I remove the limit, you can see that each image (level) is wider (width) than the other. The bottom level less wide than the top level. I think this is due to the different speeds, but when I need to design it will be quite cumbersome.

    Does anyone know how to resolve these problems? I have been at it for a few days, and at another Flash Community (FlashFocus) they don't really know the answer.

    Thanks in advance, if you can help me, A TON OF THANKS!

    All the best,

    Len

  8. #8
    var x:Number = 1; x /= 0;
    Join Date
    Dec 2004
    Posts
    549
    You can use the same concept as what I wrote above, only set the minDistX, maxDistX, minDistY, and maxDistY differently. You would probably want it to look at the dimensions of the background and work it from there. Obviously you wouldn't use _root["trees"+i] as your movie clips, and you would have to rewrite it into AS3, but the concept still works.

  9. #9
    Junior Member
    Join Date
    Jul 2010
    Posts
    6
    Thanks for your reply! I appreciate it.

    I'm bit of a new AS programmer (since a week or two) so I need some help if I want to get it right..

    I converted your code to the following:

    Actionscript Code:
    private function scrollMovement ( event:Event ):void
            {
                var numberOfLayers=5
                //here you set your speeds.
                mapLevel1Container.speed = 1/40;
                mapLevel2Container.speed = 1/60;
                mapLevel3Container.speed = 1/80;
                mapLevel4Container.speed = 1/90;
                mapLevel5Container.speed = 1/95;
                //instead of tracking mouse distance on each frame, we'll keep track of
                //the total distance that the movie clips have been offset by
                var totDistX = 0;
                var totDistY = 0;
                //minimum and maximum x/y
                var minDistX = 0;
                var maxDistX = 3000;
                var minDistY = 0;
                var maxDistY = 600;
                //These are the viewing boundaries. They are currently set for the entire stage.
                //Set them to whatever you require
                var leftBound = 0;
                var rightBound = stage.stageWidth;
                var topBound = 0;
                var bottomBound = stage.stageHeight;
                //Set these, too
                verticalCenter = stage.stageHeight / 2;
                horizontalCenter = stage.stageWidth / 2;

                for( i=1; i <= numberOfLayers; i++ ){
                    ["mapLevelContainer" + i].initX = ["mapLevelContainer" + i].x;
                    ["mapLevelContainer" + i].initY = ["mapLevelContainer" + i].y;
                    var temp = ["mapLevelContainer" + i].getBounds();
                    minDistX = Math.max( minDistX,( temp.xMin - leftBound + ["mapLevelContainer" + i].x) / ["mapLevelContainer" + i].speed);
                    maxDistX = Math.min( maxDistX,( temp.xMax - rightBound + ["mapLevelContainer" + i].x) / ["mapLevelContainer" + i].speed);
                    minDistY = Math.max( minDistY,( temp.yMin - topBound + ["mapLevelContainer" + i].y) / ["mapLevelContainer" + i].speed);
                    maxDistY = Math.min( maxDistY,( temp.yMax - bottomBound + ["mapLevelContainer" + i].y) / ["mapLevelContainer" + i].speed);
                }
            }
                public function onEnterFrame( event:Event ):void
                {
                    if (mask2.hitTest(mouseX, mouseY, true))
                    {
                        totDistX += mouseX - verticalCenter;
                        totDistY += mouseY - horizontalCenter;
                        if( totDistX > maxDistX )
                        {
                            totDistX=maxDistX;
                        }
                        else if( totDistX < minDistX )
                        {
                            totDistX=minDistX;
                        }
                        if( totDistY > maxDistY)
                        {
                            totDistY=maxDistY;
                        }
                        else if( totDistY < minDistY)
                        {
                        totDistY=minDistY;
                        }
                        for( i=1; i <= numberOfLayers; i++ )
                        {
                            ["mapLevelContainer" + i].x = ["mapLevelContainer" + i].initX - totDistX * ["mapLevelContainer" + i].speed;
                            ["mapLevelContainer" + i].y = ["mapLevelContainer" + i].initY - totDistY * ["mapLevelContainer" + i].speed;
                        }
                    }
                }

    I'm sure you know that this is absolutely wrong, but it's the best I can do..

    For instance, I don't know what initX means..

    Also, I don't understand why you use ["movieclipinstance" + i]. Is that a compatible AS3 syntax? And how would that look like if I don't use instances on the stage but use the addChild method?

    Next is the .getBounds() property. Does that still function?

    Then you set a hitTest on mask2. I assume mask2 is an instance on the stage, but I don't use any instances on the stage.

    As you can see I require a helping hand in converting this code to AS3 and getting it to work..

    Hope someone can help!

    Thanks in advance,

    Len

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
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center