I'm building a rich media Flash banner ad. I have 3 to 4 round MovieClip buttons that move around with an AS3 parallax effect. It looks like an EnterFrame loop creates the effect in AS3. But the individual Movieclip buttons won't function when I assign MouseEvent Click events. I want the parallax movement to stop and playhead advance to a specific label on main timeline when the MC's are clicked.
I'm sure this can be done but I lack the expertise. Here is the code:
//add an event listener to trigger every frame
addEventListener(Event.ENTER_FRAME, onFrame);
//set a constant that marks the centre of the stage
//the stage is 600 x 400, so we halve that
const stageCentre:Point=new Point(180,300);
//set an easing constant
const ease:Number=0.2;
function onFrame(e:Event) {
//create a point to store the distances the mouse is from the centre
var mouseOffset:Vector3D=new Vector3D(stageCentre.x-mouseX,stageCentre.y-mouse Y, 0);
//move each background layer by a different percentage of offset
//the easing constant is used here to create smoother results
//foreground moves the most; 75% of the mouse offset
clip1_mc.x+=(stageCentre.x+mouseOffset.x*0.70 - clip1_mc.x)*ease;
clip1_mc.y+=(stageCentre.y+mouseOffset.y*0.50 - clip1_mc.y)*ease;
//mid-ground moves a medium amount; 50% of the mouse offset
clip2_mc.x+=(stageCentre.x+mouseOffset.x*1.00 - clip2_mc.x)*ease;
clip2_mc.y+=(stageCentre.y+mouseOffset.y*1.00 - clip2_mc.y)*ease;
//background moves the least; 25% of mouse offset
clip3_mc.x+=(stageCentre.x+mouseOffset.x*1.75 - clip3_mc.x)*ease;
clip3_mc.y+=(stageCentre.y+mouseOffset.y*1.00 - clip3_mc.y)*ease;
}
//Click on button to go to and Play "kelsey" label (this does NOT work)
clip1_mc.kelsey_btn.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event:MouseEvent):void
{
MovieClip(root).gotoAndStop("kelsey");
}
Make sure the clip1_mc is on the top most layer, it is probably overlapped by other clips that are catching up the mouse click events.
If you have buttons in all layers you will need to disable mouse events for everything except the buttons. For example, if you have a "button" and a "background" in each movieclip and you want to only keep the buttons clickable, do something like this inside of that movieclip:
background.mouseEnabled = false;
background.mouseChildren = false;
This way the background will not listen for any mouse interactions
add removeEventlistener when the mouse clicks the movieclip
clip1_mc.kelsey_btn.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event:MouseEvent):void
{
this.removeEventListener(Event.ENTER_FRAME, onFrame);
MovieClip(root).gotoAndStop("kelsey");
}
Related
i will make my hammer(movie clip) following cursor and every time I click the mouse / mouse down, the hammer will come down exposed cursor and return to original position. But i just can make the hammer(movie clip) following cursor. How can I do?
hammer.startDrag(true);
enter image description here
After I received your file here is the new code :
Mouse.hide(); //Hide the mouse cursor
//The stage listen the mouse movement
stage.addEventListener(MouseEvent.MOUSE_MOVE, functionA);
function functionA(evt:MouseEvent){
//On mouse movement, the hammer position will change
hammer.x = mouseX; //If you want you can add an offset (ex : stage.mouseX - 5; )
hammer.y = mouseY;
//That's exactly the same as hammer.startDrag(true); but with something more cool, it's you can add an offset for X/Y axes.
}
//The stage is listening on mouse button down
stage.addEventListener(MouseEvent.MOUSE_DOWN, functionName2);
function functionName2(evt:MouseEvent){
//On mouse button down, we enter the movieclip "hammer" and on the timeline we go to and play (gotoAndPlay :D) the label "HammerDown"
//Now if you double click on the hammer on the stage, you will enter the movieclip and you will find a layer call "Labels"
//I called it like that, the name is not important. In Flash you can add a name to a key frame or a group of keys. Maybe you don't see
//any advantage for now but trust me, that's much more upgradable like that. So in my first answer on Stackoverflow I wrote to you
//to type : gotoAndPlay( 1 ), the number was the key's number, but this time I've change it to "HammerDown" wich is the name of my label
//on the layer labels inside hammer's movieclip.
//So at the end what happen is : When the stage receive a mouse down event, the script enter "hammer" movieclip and gotoAndPlay the animation
//start from the first key of "HammerDown" label. That's what the line below means.
hammer.gotoAndPlay( "HammerDown" ); //2 is the number of the key wich contains the hammer with down position
//To give a label's name to a key or a group of key, just click on a keyframe, go to Propriety -> Label -> Name and that's it!
}
//On mouse button up
stage.addEventListener(MouseEvent.MOUSE_UP, functionName3);
function functionName3(evt:MouseEvent){
//On mouse up the script enter hammer's movieclip and gotoAndPlay the animation inside "hammer" movieclip, wich start from "HammerUp".
//The trick is that the animation will be stop because at the same time, the script read the stop(); and so the animation is stop inside "Hammer".
hammer.gotoAndPlay("HammerUp"); //1 is the number of the key wich contains the hammer with up position
}
And here is your file with my editing :
File
What you can do is to use a movieclip with the hammer. Inside this movieclip you have your timeline, on the first keyn of the timeline you stick the hammer with the "up" position and on this same key you type the following code
stop();
And then on the next key you create a new frame with the hammer down, you also add :
stop();
That will stop the frame reader on the first key and what we are going to do is to instance the movieclip on the stage and make it follow the mouse.
//Instance the hammer
var hammer:Hammer = new Hammer(); //Hammer is the name of you class on the movieclip in your flash library
stage.addChild(hammer); //instance on the stage
//Add an event listener on the stage wich is trigger when the mouse move
stage.addEventListener(MouseEvent.MOUSE_MOVE, functionName);
function functionName2(evt:MouseEvent){
hammer.x = stage.mouseX; //If you want you can add an offset (ex : stage.mouseX - 5; )
hammer.y = stage.mouseY;
}
Now the hammer should be moving and following the mouse :
//On mouse button down
hammer.addEventListener(MouseEvent.MOUSE_DOWN, functionName2);
function functionName2(evt:MouseEvent){
evt.target.goToAndStop(2); //2 is the number of the key wich contains the hammer with down position
}
//On mouse button up
hammer.addEventListener(MouseEvent.MOUSE_UP, functionName3);
function functionName3(evt:MouseEvent){
evt.target.goToAndStop(1); //1 is the number of the key wich contains the hammer with up position
}
The advantage of this technic is that if you feel friendly with Flash animation, you can create a small animation between keys with "goToAndPlay(x)", that's not only "up/down", you can add some fun.
Good luck!
I have made an as3 android app where I have used swipe gesture for going next frame and previous frame. but I want when I jump to next or previous frame it swipes smoothly.I have tried to use tween max but it is not working.I have found that tween plugins always work for movie clips.So how can I make the swipe smooth.Can I make it smooth without tween plugins?here is my code....
Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener (TransformGestureEvent.GESTURE_SWIPE, SwipeHandler);
function SwipeHandler(event:TransformGestureEvent):void
{
switch(event.offsetX)
{
// swiped right
case 1:
{
prevFrame();
break;
}
// swiped left
case -1:
{
if(currentFrame == 10)
{
stop();
}
else
{
nextFrame();
break;
}
}
}
}
In order for you to be able to smooth swap you need to have both frames on your screen, which is not the case with genuine Flash frames. Smooth transitions are animated via ENTER_FRAME handlers, with a potential hide of actual frame change process. So, in order to do a smooth transition, you need to move a picture of one frame to the left, and for the other frame to move in from the right instead of plain nextFrame(). Let's say you have a 60fpa stage, and try to smooth transition left. You will need two screen-sized objects, one depicting current frame and one the frame to be displayed, ready to be displayed as a single transition. An example:
var transition:Sprite;
var bitmaps:Array;
var leftSide:Bitmap
var rightSide:Bitmap;
// initialization code, best placed in constructor
leftSide=new Bitmap();
rightSide=new Bitmap();
bitmaps=[];
transition=new Sprite();
transition.addChild(leftSide);
transition.addChild(rightSide);
rightSide.x=stage.stageWidth; //left side and right side should be aside each other
This is the declaration of the needed structures. The plan is to show the transition, giving it two Bitmaps that will be linked to two different BitmapData objects that'll hold pictures of new frame and old frame. We will draw our current frame on current frame's bitmapdata, then take a stored next frame bitmap data and the do transition.
function swipeHandler((event:TransformGestureEvent):void {
var doSwitch:Boolean=false;
var targetFrame:int=currentFrame;
switch(event.offsetX) {
// swiped right
case 1: {
if (currentFrame>2) {
// let's say we're not allowed to swipe right from frame 2
targetframe=currentFrame-1;
doSwitch=true;
}
break;
}
// swiped left
case -1: {
if(currentFrame < 10) {
targetFrame=currentFrame+1;
doSwitch=true;
}
break;
}
}
if (!doSwitch) return;
// prepare transition
if (!bitmaps[targetFrame]) bitmaps[targetFrame]=new BitmapData(stage.stageWidth,stage.stageHeight,false,0xffffff);
// ^ make a new bitmap if there's none for target frame
if (!bitmaps[currentFrame]) bitmaps[currentFrame]=new BitmapData(stage.stageWidth,stage.stageHeight,false,0xffffff);
// the same for source frame
bitmaps[currentFrame].fillRect(bitmaps[currentFrame].rect,0xffffff);
bitmaps[currentFrame].draw(stage); // draw current frame on the bitmap
// with this and stored bitmaps, old frame would remain drawn on the cached bitmap
// and able to be used as a transition image
if (targetFrame>currentFrame) {
leftSide.bitmapData=bitmaps[currentFrame];
rightSide.bitmapData=bitmaps[targetFrame];
transition.x=0;
// here is the place to initialize TweenMax tween to move "transition"
// and don't forget to removeChild(transition) at the end of the tween
} else {
rightSide.bitmapData=bitmaps[currentFrame];
leftSide.bitmapData=bitmaps[targetFrame];
transition.x=-1*stage.stageWidth;
// same here for tweening
}
stage.addChild(transition);
gotoAndStop(targetFrame);
}
This places a prepared transition object on screen above all the underlying items, effectively masking the exact frame switch, done by gotoAndStop() call. This object's x coordinate can be tweened afterwards, and the object should be removed from stage once the tween is ofer.
Hope this helps.
I am working on a zooming square navigation project (visually like Windows Metro, but squares take over the screen when clicked on). I'm having trouble getting the squares to the top layer (setChildIndex). Here is the code for when a square is clicked on:
function zoom(event:MouseEvent):void {
// saves location and size of icons
returnto = event.currentTarget;
returntoX = event.currentTarget.x;
returntoY = event.currentTarget.y;
returntoWidth = event.currentTarget.width;
returntoHeight = event.currentTarget.height;
// turn off button behaviours
event.currentTarget.buttonMode = false;
event.currentTarget.alpha = 1;
event.currentTarget.removeEventListener(MouseEvent.MOUSE_OVER, rollover);
event.currentTarget.removeEventListener(MouseEvent.CLICK, zoom);
event.currentTarget.removeEventListener(MouseEvent.ROLL_OUT, rollout);
// put clicked box on top
setChildIndex(returnto, numChildren-1);
// fade out icon decor
TweenLite.to(returnto.decor, .25, {alpha:0});
// make square take over screen, call finished when done
TweenLite.to(returnto, 1, {x:stage.x,y:stage.y, width:stage.stageWidth, height:stage.stageHeight, ease:Expo.easeInOut, onComplete:finished});
}
the squares are all inside a main movieclip (named navigation) on the stage (so the first square is navigation.sq_1)
I am not a Flash developer, so I'm really struggling with AS3. Hopefully this is enough info for someone to help. Thanks!
S
Just try to add your returnto clip with addChild() method:
// put clicked box on top
addChild(returnto);
Display List's default behavior when addChild() is to put the child on top of all childs. Other children's indexes are recounted.
I'm developing an ActionScript 3.0 app for Blackberry Playbook.
I'm using Loader Class to show an image.
I want to show another image, at the same place, when the user clicks on this image.
How can I do that? I would like to make a transition between these two images. The second image will go from 0 alpha to 100 alpha.
It all depends on the transition you want to do. For the simplest alpha, you can go through a Tweener engine like irot suggested, or you can do something simple yourself.
Simple:
Basically, when you click on the image, load in the next one (or have it already loaded). Start an enterframe listener to load it up. Something like:
// we're assuming that "image2" is the second image and it has an alpha
// of 0.0 and visible of false. "image1" is the first image and currently
// on stage
// the on click handler for the image
private function _onImageClick( e:MouseEvent ):void
{
// add a enter frame to the stage - I'm going to assume you
// have access through this.stage
this.stage.addEventListener( Event.ENTER_FRAME, this._onEnterFrame );
// make our second image visible so we can fade it up
this.image2.visible = true;
}
// called every frame
private function _onEnterFrame( e:Event ):void
{
// image2 is the second image
this.image2.alpha += 0.05; // slow fade
if( this.image2.alpha >= 1.0 )
{
this.image2.alpha = 1.0;
// hide the first image
this.image1.alpha = 0.0;
this.image1.visible = false;
// remove the enter frame event listener
this.stage.removeEventListener( Event.ENTER_FRAME, this._onEnterFrame );
}
}
Bit more complicated: Check out the BitmapData class and it's merge() or pixelDisolve() functions: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html
Are you familiar with any Tween engines? I would recommend TweenLite if you are not.
What I would usually do is load all the images I plan to use and then stack two or more of them where I want them. Only one of these images will be visible at any time (alpha = 1).
On your click handler, you can do one of two things:
Tween the visible image's alpha down to 0, then have an onComplete handler tween your next image's alpha up to 1
Alternatively, you could just have two tweens running at once. One would tween the visible image's alpha down to 0, the other tweening the next image's alpha up to 1
irot
I'm trying to do a bottom menu like in www.zara.com.
My code have a transparent movieclip that shows the menu when mouse rolls over it, and hide when mouse rolls out.
The menu appears over that transparent movieclip, so I can use the roll over and out actions to maipulate the menu with the transparent MC.
The problem here is when mouse Roll Over my menu MC and it behaves as rolling out the transparent movieclip.
How can I make mouse rolls over a movieclip over another movieclip without roll out the first one?
Is it to confuse?
Thanx!
When a MovieClip B appears on top of another MovieClip A, MovieClip A will fire the MouseEvent.ROLL_OUT event. This is because MovieClip B is preventing MovieClip A from receiving any MouseEvents (since it is on top).
If you do not need to receive any MouseEvents from MovieClip B, you can set its mouseEnabled property to false, then MovieClip A underneath it will receive MouseEvents.
Also, depending on whether it makes sense in your particular case or not, you can make MovieClip B a child of MovieClip A, so that when MovieClip B obscures MovieClip A, the ROLL_OUT event will not be fired.
I hope this helps answer your question.
Here is a quick and dirty trick originaly from javascript technique
1.) build extra logic into the clipA rollout which waits a small period of time and then checks if the mouse is on the menu or not before closing it.
// define a boolean value for the moust beeing on the menu
public var menuOver:Boolean = false;
public function onMenuOver( event:MouseEvent ):void
{
menuOver = true;
// other menu code here
}
public function onMenuOut( event:MouseEvent ):void
{
menuOver = false;
// other menu code here
}
public function onMainClipOver( event:MouseEvent ):void
{
// show menu code here
}
public function onMainClipOut( event:MouseEvent ):void
{
setTimeout(execMainClipOut,100);
}
/**
* close the menu only if the mouse is not over the menu
*/
public function execMainClipOut()
{
if(!menuOver){
// close the menu
}
}
Ooh! I just remembered something interesting that might solve your problem.
When a MouseEvent.ROLL_OUT event is fired, the listener function is called with a MouseEvent object that has the relatedObject property. This is a reference to the object that is gaining mouse focus (getting rolled over) -- in your case, you could ignore the event if this property is set to your other MovieClip object, then fire the event manually when your other MovieClip object rolls out (so that it rolls out both of them).
as mentioned above, relatedObject works PERFECTLY
so for example if you have MovieClip A and then have Movieclip B on top.
You want Movieclip B to show on rolling over MovieClip A and hiding when rolling out of Movieclip A,
what generally happens is that Movieclip B will show but then when you hover over B, Moveclip B will dissappear, as B lies on top of A, rollout event takes place
so on Movieclip A rollout even just use
if((event.relatedObject == MoveClipB)
{
//if its rolling over B, which is a related object, dont do anything
}
else
{
//Hide B
}
Events for B still work when this is used