-
[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!
-
var x:Number = 1; x /= 0;
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
-
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!
-
bump for help!
I can't find the answer in any of the tutorials I've searched through.
-
var x:Number = 1; x /= 0;
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
-
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!
-
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
-
var x:Number = 1; x /= 0;
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.
-
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|