Actionscript 3 mouse_over play movie, mouse_out reverse movie - actionscript-3

I'm trying to make some flash buttons with a mouse_over animation that plays in reverse on mouse_out. Now I have it working for one of my three movie clip instances.
I am using e.currentTarget.play() instead of having a function for each movie clip, but how do I do the same for my playReverse function? I tried putting e.currentTarget.prevFrame() instead of mc1.prevFrame() but it did not work. My code is as follows:
mc1.addEventListener(MouseEvent.MOUSE_OVER,mover);
mc2.addEventListener(MouseEvent.MOUSE_OVER,mover);
mc3.addEventListener(MouseEvent.MOUSE_OVER,mover);
mc1.addEventListener(MouseEvent.MOUSE_OUT,mout);
mc2.addEventListener(MouseEvent.MOUSE_OUT,mout);
mc3.addEventListener(MouseEvent.MOUSE_OUT,mout);
function mover(e:MouseEvent):void {
stopPlayReverse();
e.currentTarget.play();
}
function mout(e:MouseEvent):void {
this.addEventListener(Event.ENTER_FRAME, playReverse, false, 0, true);
}
function playReverse(e:Event):void {
if (mc1.currentFrame == 1) {
stopPlayReverse();
} else {
mc1.prevFrame();
}
}
function stopPlayReverse():void {
if (this.hasEventListener(Event.ENTER_FRAME)) {
this.removeEventListener(Event.ENTER_FRAME, playReverse);
}
}
Any idea how I can fix this?

Your function playReverse only use mc1 how can it work with the others movie clip.
If you choose to do it that way you can keep a track of the current MovieClip playing in reverse.
You will have to add more logic if you want that the play in reverse always finish when passing over one clip to another.
var currentMovieClip:MovieClip=null;
function mout(e:MouseEvent):void {
var mc:MovieClip = e.currentTarget as MovieClip;
if (mc !== null) {
currentMovieClip = mc;
this.addEventListener(Event.ENTER_FRAME, playReverse, false, 0, true);
}
}
function playReverse(e:Event):void {
if (currentMovieClip==null) {
return;
}
if (currentMovieClip.currentFrame == 1) {
stopPlayReverse();
} else {
currentMovieClip.prevFrame();
}
}
Another way that implies that you can have each clip to finish their play in reverse
function mover(e:MouseEvent):void {
stopPlayReverse(e.currentTarget as MovieClip);
e.currentTarget.play();
}
function mout(e:MouseEvent):void {
var mc:MovieClip = e.currentTarget as MovieClip;
if (mc !== null) {
mc.addEventListener(Event.ENTER_FRAME, playReverse, false, 0, true);
}
}
function playReverse(e:Event):void {
var mc:MovieClip = e.currentTarget as MovieClip;
if (mc.currentFrame == 1) {
stopPlayReverse(mc);
} else {
mc.prevFrame();
}
}
function stopPlayReverse(mc:MovieClip):void {
if ((mc!==null) && mc.hasEventListener(Event.ENTER_FRAME)) {
mc.removeEventListener(Event.ENTER_FRAME, playReverse);
}
}

Related

AS3 : EventListener won't be removed in an [IF]

I have searched how to pass arguments through EventListeners, and I used the method without calling an anonymous function to remove the EventListener later.
The issue is that the EventListener will be removed if out the IF function, but not if it is in the IF function.
How could I do that ?
The code :
function dragShip(m:MouseEvent):void
{
var func:Function = dispositionShip(m.target);
if (isDragging == false)
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, func);
m.target.startDrag(true);
isDragging = true;
}
else
{
stage.removeEventListener(KeyboardEvent.KEY_DOWN, func);
isDragging = false;
placeShip(m.target , mouseX , mouseY , m.target.rotation);
}
// if the EventListener is put here, it gets removed, but not if put just in the else
}
NOTE : dispositionShip()returns a function.
Edit : Here is the following part of the code :
function dispositionShip(shipTarg):Function
{
return function(k:KeyboardEvent):void
{
rotateShip(k,shipTarg);
};
}
function rotateShip(k:KeyboardEvent,ship:Object):void
{
if (k.keyCode == 39)
{
ship.rotation += 90;
}
else if (k.keyCode == 37)
{
ship.rotation -= 90;
}
}
Moreover, if I replace rotateShip(k,shipTarg); by a simple trace, it also does not work.
Everytime you call
function dispositionShip(shipTarg):Function
{
return function(k:KeyboardEvent):void
{
rotateShip(k,shipTarg);
};
}
You're creating a new anonymous Object of type Function that calls rotateShip(), so when you call stage.removeEventListener(KeyboardEvent.KEY_DOWN, func); your func is a different Object to the func you passed into addEventListener(), so it doesn't match the orginal listener and doesn't get removed.
A better way to do this would be to store the current mouse target in a member var. IE:
var currentShip:Object;
function dragShip(m:MouseEvent):void
{
if (isDragging == false)
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPress);
m.target.startDrag(true);
isDragging = true;
currentShip = m.target;
}
else
{
stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyPress);
isDragging = false;
placeShip(m.target , mouseX , mouseY , m.target.rotation);
currentShip = null;
}
}
function keyPress(k:KeyboardEvent):void
{
rotateShip(k,currentShip);
}

Sprite movement basically right but

This is basically just drag and double click to set (so drag is temporarily disabled) but the sprite doesn't keep with the mouse- can someone point me to better code- otherwise I'll with go with this- so much more to do.
//The initial event performed when the button is first clicked;
internal var m_nDoubleClickSpeed:Number = 300;
internal var m_toMouse:Number;
internal var moveready:Boolean = false;
internal var initalx:uint;
internal var initialy:uint;
internal var move:Boolean;
internal function clickDoubleClick(e:MouseEvent):void {
if (isSet == false) {
this.startDrag();
}
if (isNaN(m_toMouse)==false) {
clearTimeout(m_toMouse);
HandleDoubleClick();
} else {
m_toMouse = setTimeout(HandleSingleClick, m_nDoubleClickSpeed);
}
}
internal function HandleSingleClick():void {
trace("HandleSingleClick");
trace("isSet");
trace(isSet);
this.stopDrag();
m_toMouse = NaN;
}
internal function HandleDoubleClick():void {
if (isSet == false) {
isSet = true;
this.stopDrag()
} else {
isSet = false;
}
trace("HandleDoubleClick");
m_toMouse = NaN;
}
internal function goodX(inX:Number):Number {
if (inX < 0) {
return 0;
}
if (inX > (stage.stageWidth) ) {
return (stage.stageWidth);
}
return inX;
}
internal function goodY(inY:Number):Number {
if (inY < 0) {
return 0;
}
if (inY > stage.stageHeight) {
return stage.stageHeight;
}
return inY;
}
I'm not sure if I understood you correctly. So you want to start drag on single click and drag until doubleclicked right? If so you can try something like that:
public class ClickAndDrag extends Sprite
{
private var clickTimeout:uint;
private var doubleClickSpeed:int = 500;
private var clickedOnce:Boolean;
private var mouseOnClick:Point;
private var isDragging:Boolean;
public function ClickAndDrag()
{
graphics.beginFill(Math.random()*0xffffff, 1);
graphics.drawCircle(0, 0, 20);
graphics.endFill();
this.buttonMode = true;
addEventListener(MouseEvent.MOUSE_DOWN, handleMouseDown);
}
private function handleMouseDown(e:MouseEvent):void
{
if (isDragging)
{
if (clickedOnce)
handleDoubleClicked();
else
{
//if it's not clicket within next doubleClickSpeed ms then doubleClickSpeed will be set to false;
clickedOnce = true;
clickTimeout = setTimeout( handleClickTimeout, doubleClickSpeed );
}
}
else
{
handleClickAndDrag();
}
}
//clicked once when dragging
private function handleClickOnce():void
{
graphics.clear();
graphics.beginFill(Math.random()*0xffffff, 1);
graphics.drawCircle(0, 0, 20);
graphics.endFill();
}
//clicked once when not dragging
private function handleClickAndDrag():void
{
isDragging = true;
this.addEventListener(Event.ENTER_FRAME, handleFrame);
mouseOnClick = new Point(this.mouseX, this.mouseY);
}
//doubleclicked when dragging
private function handleDoubleClicked():void
{
clearTimeout(clickTimeout);
clickedOnce = false;
this.removeEventListener(Event.ENTER_FRAME, handleFrame);
isDragging = false;
}
private function handleClickTimeout():void
{
clickedOnce = false;
handleClickOnce();
}
private function handleFrame(e:Event):void
{
this.x = stage.mouseX - mouseOnClick.x;
this.y = stage.mouseY - mouseOnClick.y;
}
}
It basically waits for mousedown and if it's already dragging it checks if you clicked once (changes color) ot twice (stops dragging). Or if it's not dragging yet then it starts dragging. You may also want to handle leaving the stage (Event.MOUSE_LEAVE).

AS3 paralell movie clips + links

I'm a very beginner in as3. I want to make a box with two parallel movie clips loaded on mouse hover and rewinded on mouse out. I'd like to add links to movie clips, but after a long time I've ended up with nothing.
Code looks like this:
import flash.events.MouseEvent;
for (var fl_ChildIndex:int = 0;
fl_ChildIndex < this.numChildren;
fl_ChildIndex++)
{
this.getChildAt(fl_ChildIndex).addEventListener(MouseEvent.MOUSE_OVER, nawierzch);
}
function nawierzch(event:MouseEvent):void
{
this.addChild(event.currentTarget as DisplayObject);
}
zlec.stop();
zlec.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
zlec.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
zlec.addEventListener(MouseEvent.CLICK, onClick);
zlec.buttonMode = true;
zlec.mouseChildren = true;
function onClick(event:MouseEvent):void
{
trace("click")
var url:String = "http://www.motoopcja.pl";
var request:URLRequest = new URLRequest(url);
try {
navigateToURL(request, '_blank');
} catch (e:Error) {
trace("Error occurred!");
}
}
function onMouseOver(e:MouseEvent):void
{
var mc:MovieClip = MovieClip(e.currentTarget);
mc.removeEventListener(Event.ENTER_FRAME, rewind);
mc.play();
mc.addEventListener(Event.ENTER_FRAME, advance);
}
function onMouseOut(e:MouseEvent):void
{
var mc:MovieClip = MovieClip(e.currentTarget);
mc.removeEventListener(Event.ENTER_FRAME, advance);
mc.prevFrame();
mc.addEventListener(Event.ENTER_FRAME, rewind);
}
function advance(e:Event):void
{
var mc:MovieClip = MovieClip(e.currentTarget);
if (mc.currentFrame == mc.totalFrames)
{
mc.stop();
mc.removeEventListener(Event.ENTER_FRAME, advance);
}
}
function rewind(e:Event):void
{
var mc:MovieClip = MovieClip(e.currentTarget);
if (mc.currentFrame == 1)
{
mc.stop();
mc.removeEventListener(Event.ENTER_FRAME, rewind);
}
else
{
mc.prevFrame();
}
}
wykonaj.stop();
wykonaj.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver2);
wykonaj.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut2);
wykonaj.addEventListener(MouseEvent.CLICK, onClick2);
wykonaj.buttonMode = true;
wykonaj.mouseChildren = true;
function onClick2(e:MouseEvent):void
{
trace("click")
}
function onMouseOver2(e:MouseEvent):void
{
var mc:MovieClip = MovieClip(e.currentTarget);
mc.removeEventListener(Event.ENTER_FRAME, rewind);
mc.play();
mc.addEventListener(Event.ENTER_FRAME, advance);
}
function onMouseOut2(e:MouseEvent):void
{
var mc:MovieClip = MovieClip(e.currentTarget);
mc.removeEventListener(Event.ENTER_FRAME, advance);
mc.prevFrame();
mc.addEventListener(Event.ENTER_FRAME, rewind);
}
function advance2(e:Event):void
{
var mc:MovieClip = MovieClip(e.currentTarget);
if (mc.currentFrame == mc.totalFrames)
{
mc.stop();
mc.removeEventListener(Event.ENTER_FRAME, advance);
}
}
function rewind2(e:Event):void
{
var mc:MovieClip = MovieClip(e.currentTarget);
if (mc.currentFrame == 1)
{
mc.stop();
mc.removeEventListener(Event.ENTER_FRAME, rewind);
}
else
{
mc.prevFrame();
}
}
The problem can be that you don't import everything you need.
You must also be carefull not to remove an eventlistener that doesn't exist.
That can happen very often in your code. Here is an example:
zlec is rolled over.
zlec has the rewind eventlistener removed (doesn't exist).
I don't know if you have some outside AS3 that prevents it, but it can throw an error.
This is a much cleaner solution:
import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.net.navigateToURL;
import flash.events.Event;//imports
zlec.addEventListener(MouseEvent.ROLL_OVER,turnPar);
zlec.addEventListener(MouseEvent.ROLL_OUT,turnPar);
zlec.addEventListener(MouseEvent.CLICK,clickedBox);
zlec.buttonMode = true;//make the cursor change on roll over
for(var curChild:uint=0;curChild<this.numChildren) {
this.getChildAt(curChild).addEventListener(Event.ENTER_FRAME,playPar);
}
var theState:String = "MouseEvent.ROLL_OUT";//by default rewind to frame 1
function turnPar(event:MouseEvent):void { theState = event.type; }
function clickedBox(event:MouseEvent):void {
var url:String = "http://www.motoopcja.pl";//your website
var req:URLRequest = new URLRequest(url);//as URLRequest
navigateToURL(req,'_blank');//open in a new window
}
function playPar(event:Event):void {
if("MouseEvent.ROLL_OUT" == theState && event.currentTarget.currentFrame > 1) { event.currentTarget.prevFrame(); }
else if("MouseEvent.ROLL_OVER" == theState && event.currentTarget.currentFrame < event.currentTarget.totalFrames) { event.currentTarget.nextFrame(); }
}

Flash AS3 Press and Hold Button

I'm no expert in Flash but I found a way in AS2 to make a "press and hold" button. Now I'm working with AS3 and I'd like this code to be converted to AS3. Can someone help ?
stop();
function startTimer(mc, conversionTime) {
mc.onEnterFrame = function() {
if ((getTimer() / 1000) - conversionTime > 1) {
delete this.onEnterFrame;
gotoAndStop(3);
}
};
}
button1.onPress = function() {
var conversionTime:Number = getTimer() / 1000;
startTimer(this, conversionTime);
this.onRelease = function() {
if (this.onEnterFrame != null) {
gotoAndStop(2);
}
delete this.onEnterFrame;
};
};
Thanks !
In AS3 it would look like this:
mc.addEventListener(MouseEvent.MOUSE_DOWN, _mouseDown);
var myTimer:Timer = new Timer(5000,1);
myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, _buttonPressedEnoughLong);
private function _mouseDown(e:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, _mouseUp);
myTimer.start();
}
private function _mouseUp(e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, _mouseUp);
myTimer.reset();
}
private function _buttonPressedEnoughLong(e:TimerEvent) : void {
e.currentTarget.reset();
// Do stuff
}
You need to hold button 5 seconds, before event will fire.
Change mc.onEnterFrame = function() ... to:
mc.addEventListener(Event.ENTER_FRAME, onEvent);
function onEvent(e:Event)
{
if ((getTimer() / 1000) - conversionTime > 1)
{
this.removeEventListener(Event.ENTER_FRAME, onEvent);
gotoAndStop(3);
}
}
Change button1.onPress = function() ... to:
button1.addEventListener(MouseEvent.MOUSE_DOWN, onBtnDown);
function onBtnDown(e:MouseEvent)
{
var conversionTime:Number = getTimer() / 1000;
startTimer(this, conversionTime);
function onBtnUp(e:MouseEvent)
{
if (this.hasEventListener(Event.ENTER_FRAME))
{
gotoAndStop(2);
this.removeEventListener(Event.ENTER_FRAME, onEvent);
}
}
}

Flash - Play movie clip in reverse?

I'm trying to get a movie clip to play in reverse when I mouse_out from it (it plays on mouse_over).
My actionscript is as follows:
mc.stop();
mc.addEventListener(MouseEvent.MOUSE_OVER,mover);
mc.addEventListener(MouseEvent.MOUSE_OUT,mout);
function mover(e:MouseEvent):void
{
mc.play();
}
function mout(e:MouseEvent):void
{
//Play in reverse
}
How would I achieve this?
Thanks
The best way would be to use an ENTER_FRAME event listener. Basically this is what you want to do
function mover(e:MouseEvent):void {
stopPlayReverse();
mc.play();
}
function mout(e:MouseEvent):void {
this.addEventListener(Event.ENTER_FRAME, playReverse, false, 0, true);
}
function playReverse(e:Event):void {
if (mc.currentFrame == 1) {
stopPlayReverse();
} else {
mc.prevFrame();
}
}
function stopPlayReverse():void {
if (this.hasEventListener(Event.ENTER_FRAME)) {
this.removeEventListener(Event.ENTER_FRAME, playReverse);
}
}
This would play your MovieClip in reverse until it hits frame 1, then it will stop.
If the motion allows, you can use a Tween (for example if you want to change the alpha, location or scale). On the MouseOut you can call .yoyo() for the Tween, which will play it in reverse.
Something like this:
var tween:Tween;
mc.addEventListener(MouseEvent.MOUSE_OVER,mover);
mc.addEventListener(MouseEvent.MOUSE_OUT,mout);
function mover(e:MouseEvent):void
{
tween = new Tween(obj, "alpha", None.easeNone, 1, 0, 1, true);
}
function mout(e:MouseEvent):void
{
tween.yoyo();
}
TweenLite.to(mc, 2, {frame:1});
If your tween is not all that serious you can literally make a whole new set of frames in reverse and just play it from that keyframe.
That's the poor man's reverse tween.
By using a boolean which works as a trigger and Event.ENTER_FRAME, you can do the following to reverse frames:
//Boolean and Event.ENTER_FRAME
var reversing:Boolean = false;
AddEventListener(Event.ENTER_FRAME, reverse);
function reverse(e:Event){
if(reversing)
{
//mc is displaying previous frame every frame
mc.prevFrame();
//until the currentFrame is 1
if(mc.currentFrame == 1)
reversing = false;
}
}
Your //Play in reverse would set reversing = true;
You can do it passing the movie clip object to find the correct object to reverse. This manner helps you to use with the child you want. You can get it with:
fMoveBack(this.getChildByName("my_clip"));
function fMoveBack(my_clip:MovieClip):void {
this.addEventListener(Event.ENTER_FRAME, playReverse(my_clip));
}
function playReverse(mc:MovieClip):Function {
return function playReverse(e:Event):void {
if (mc.currentFrame == 1) {
stopPlayReverse(mc);
} else {
mc.prevFrame();
}
};
}
function stopPlayReverse(mc:MovieClip):void {
if (this.hasEventListener(Event.ENTER_FRAME)) {
this.removeEventListener(Event.ENTER_FRAME, playReverse);
}
}