how to stop a movieclip on the Y-axis with buttons? - actionscript-3

I have two buttons that moves a movieclip up/down the Y-axis. How do I get the movieclip to stop at a certain height, and still be able to move it in the opposite direction?
I need this to work like this:
When you press the down-button, the movieclip goes downwards, but not past Y=500.
When you press the up-button, the movieclip goes upwards, but not past Y= 300.
I get the movieclip to stop at the correct point (500), but when it reaches this point it's stuck..
so it won't go upwards again if I press the up-button.
can someone help me please?:)
here's my code so far:
1) decrease = the down-button
2) increase = up-button
3) stempel = the movieclip I want to stop on the Y-axis
var moveStempel = 0;
decrease.addEventListener(MouseEvent.MOUSE_DOWN, decreasePressed);
decrease.addEventListener(MouseEvent.MOUSE_UP, removeEnterFrame);
increase.addEventListener(MouseEvent.MOUSE_DOWN, increasePressed);
increase.addEventListener(MouseEvent.MOUSE_UP, removeEnterFrame);
function decreasePressed(e:MouseEvent):void
{
moveStempel = 2;
addEnterFrame();
}
function increasePressed(e:MouseEvent):void
{
moveStempel = -2;
addEnterFrame();
}
// ADD ENTER FRAME
function addEnterFrame():void
{
this.addEventListener(Event.ENTER_FRAME, update);
}
function removeEnterFrame(e:MouseEvent):void
{
this.removeEventListener(Event.ENTER_FRAME, update);
}
function update(e:Event):void
{
if (stempel.y < 500)
{
stempel.y += moveStempel;
trace("inside");
}
else if (stempel.y > 500)
{
stempel.stop();
trace("outside");
}

In your code right now, once stempel has a y value greater than 500, it will never be able to move again.
There are two conditions when stempel can move: if it's moving down, it can't be at the bottom of the allowed area, and if it's moving up, it can't be at the top of the allowed area.
if ((stempel.y < 500 && moveStempel == 2) || (stempel.y > 300 && moveStempel == -2))
{
stempel.y += moveStempel;
trace("inside");
}
else
{
stempel.stop();
trace("outside");
}

Related

How to change frames when i move my mouse left or right (actionscript)

I am using a fish as a mouse cursor but when i move it around my stage it only faces one direction. what I want it to do is change direction when i move it left or right.
This should allow you to control the timeline of the fish movieclip:
It works by listening for a change in the position of the mouse, which after detecting the speed in which it does this, moves the timeline of the desired movieclip forwards or backwards depending on the new direction of the mouse.
Taken from the following thread: https://forums.adobe.com/thread/1450102?tstart=0
var mc:MovieClip = MovieClip(this); // <- The timeline you want to control with mouse position
var maxScrollSpeed:int=100; // max fps for mc above
var m:Number;
var b:Number;
var prevFPS:int;
paramF(0,-maxScrollSpeed,stage.stageWidth,maxScrollSpeed);
this.addEventListener(MouseEvent.MOUSE_MOVE,scrollF);
function scrollF(e:Event):void
{
var fps:int = Math.round(m*mouseX+b);
if(prevFPS&&prevFPS!=fps)
{
if(fps!=0)
{
if(fps>0)
{
playF(mc,mc.currentFrame,mc.totalFrames,fps);
}
else
{
playF(mc,mc.currentFrame,1,-fps);
}
}
else
{
stopF(mc);
}
}
prevFPS=fps;
}
function playF(mc:MovieClip, m:int, n:int, fps:int):void
{
var playFFF2:Function = function(mc:MovieClip):void
{
if (mc.m<mc.n)
{
mc.nextFrame();
}
else
{
mc.prevFrame();
}
if (mc.currentFrame == mc.n)
{
clearInterval(mc.int);
}
//updateAfterEvent();
};
mc.m = m;
mc.n = n;
mc.fps = fps;
mc.gotoAndStop(mc.m);
clearInterval(mc.int);
mc.int = setInterval(playFFF2, 1000/mc.fps, mc);
}
function stopF(mc:MovieClip):void
{
clearInterval(mc.int);
}
function paramF(x1:Number,y1:Number,x2:Number,y2:Number):void
{
m=(y1-y2)/(x1-x2);
b=y1-m*x1;
}
Store the mouseX position in a variable. When the mouse moves, compare the new mouseX position with your stored variable (you can do this with the ENTER_FRAME or MOUSE_MOVE events). If the new position is greater than the previous position, set the scaleX to 1, if the new position is less than the previous position set the scaleX to -1 (or vice versa).
Update the stored value and repeat.

flash as3 hitdetection function triggering other function

I am trying to code a script in which a movieclip drops a rope and catches fishes that follows it up if it touches it. here is the issue , i am using hitTestObject to detect collision . Ofcourse the problem is that i trigger the function when it touches but as soon as it doesnt touch the function for moving the movie starts so basically the fish goes up for few seconds and then starts moving straight again .
To try and fix that i tried to make a boolean variable which changes to true or false according to hit and accordingly makes the movieclip moves but also doesnt work because as soon as one mc is not touching the other it changes from true to false or 1 to 0 ..tried both (as in with boolean variable and Number variable) . Any help or putting me on the right direction would be highly appreciated . Thank you so much
// fish capture code
this.addEventListener(Event.ENTER_FRAME,handleCollision);
function handleCollision(e:Event):void
{
if (ropeHit.hitTestObject(fishy_1_a))
{
stopFish1();
trace(movefish1);
}
else
{
moveFish1();
}
}
//code enemy fishy
//fish 1 A
function moveFish1()
{
if (fishy_1_a.x < 800)
{
fishy_1_a.x += xSpeed;
}
else if (fishy_1_a.x >= 800)
{
fishy_1_a.x = -100;
}
}
function stopFish1()
{
fishy_1_a.y -= xSpeed;
}
Define some flag, that you can test:
function handleCollision(e:Event):void {
//Check if fishy is caught
if (!fishy_1_a.catched && ropeHit.hitTestObject(fishy_1_a)) {
//Change flag
fishy_1_a.catched = true;
trace("Gotcha!");
}
if (fishy_1_a.catched) {
stopFish1();
}else {
moveFish1();
}
}

AS3 : How to remove movieclip properly without Error 1009 overflow?

I have a class Catcher which lets you control a movieclip in a game. I'm trying to program the game so it finishes and you can restart. So I need to remove everything and go back to the menu. Should be a simple thing to solve but I can't seem to find out how.
So far I just have ourCatcher.parent.removeChild(ourCatcher); to remove my movieclip from the stage. And an if statement to stop one of the functions which drops things onto the stage. SoundMixer.stopAll(); to stop the music.Then I just have it going to frame 3 which is the gameover screen.
It looks fine but I get constant 1009 errors overflowing in the error console and when I restart the game, it's super slow. It seems the function for movement within Catcher is still running and creating an error because the Catcher was removed from stage and is null now.
I know I need to un-reference everything to do with the Catcher but I can't find out any documentation online to do it in my situation. Everyone seems to have different methods which I've tried and don't work.
The two functions in the Catcher class I'm using to move the character :
public function Catcher(stageRef:Stage)
{
stop();
this.stageRef = stageRef;
key = new KeyObject(stageRef);
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
//movement
public function loop(e:Event):void
{
if (key.isDown(Keyboard.A))
vx -= walkSpeed;
else if (key.isDown(Keyboard.D))
vx += walkSpeed;
else
vx *= friction;
//update position
x += vx;
//speed adjustment
if (vx > maxspeed)
vx = maxspeed;
else if (vx < -maxspeed)
vx = -maxspeed;
//stay inside screen
if (x > stageRef.stageWidth)
{
x = stageRef.stageWidth;
vx = -vx
}
else if (x < 0)
{
x = 0;
vx = -vx;
}
if (key.isDown(Keyboard.A))
{
scaleX = -1;
}
else if (key.isDown(Keyboard.D))
{
scaleX = 1;
}
movement();
// Jumping
jump += gravity;
if (y > stage.stageHeight /1.5)
{
jump = 0;
canJump = true;
}
if (key.isDown(Keyboard.SPACE) && canJump)
{
jump = -10;
canJump = false;
}
y += jump;
}
The other class where I'm removing the things from the stage is called CatchingGame and it has a function which drops objects, I put the game over code there for when playerlives == 0 .
if (playerLives == 0 )
{
stop();
ourCatcher.parent.removeChild(ourCatcher);
SoundMixer.stopAll();
gotoAndStop(3);
}
I've probably made an elementary mistake since this is my first flash game. Any help is greatly appreciated as this is pretty much the last step in finishing my game.
Instead of just removing the child by referencing its parent to remove itself (I had to test to make sure this actually worked). Create a function in same place that you create/instantiate the Catcher that removes first the eventListener ENTER_FRAME, then removes the Catcher.
if (playerLives == 0 ) {
stop();
removeCatcher();
SoundMixer.stopAll();
gotoAndStop(3);
}
// new location in the main code where the catcher is created
function removeCatcher():void {
ourCatcher.cleanUp();
removeChild(ourCatcher);
}
// in the Catcher class
function cleanUp():void {
removeEventListener(Event.ENTER_FRAME, loop);
}
if (ourCatcher.parent) ourCatcher.parent.removeChild(ourCatcher);
else trace("Catcher without a parent still plays! DEBUG THIS!");
Basically, you are most likely losing control flow of your catcher, that is, it seemingly tries to remove itself from the stage twice. After it removes itself first time, its parent becomes null, hence the 1009. And, seeing as you've hit a 2028, the same reason applies, your catcher is no longer a child of anywhere.

How to make carousel loop back to beginning

I have a 800w movieclip containing 4 panels next to each other, each with 200 width (See picture here). When I click and drag then mouse_out, it detects the direction of the mouse and move the panels by 200 either left or right depending on the direction.
My problem is I want this to loop, so when it gets to the very left panel, it'll continue on to the left, and visa versa when it gets to the very right panel, I should be able to continue with the click and drag motion.
I'm not sure if this is considered a carousel.
Anyhow this is what I have so far. I've made 2 comments "What happens now" toLeftTween() and toRightTween() to indicate where I'm stuck.
import com.greensock.*;
import com.greensock.easing.*;
var selectX:Number = 0;
var mouseX1:int = 0;
var mouseX2:int = 0;
var mcPosX:int = 0;
var contents:MovieClip = all_mc;
var draggable:Boolean = true;
contents.buttonMode = true;
contents.mouseChildren = false;
contents.x = 0;
contents.y = 70;
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
function mouseDownHandler(e:MouseEvent):void {
//select the correct point on mc
selectX = contents.x - mouseX;
//for prediction direction later - mouse point 1
mouseX1 = stage.mouseX;
//trace("1: " + mouseX1);
// move mc with mouse
if (draggable) {
addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
} else {
trace("unable to drag");
}
}
function mouseUpHandler(e:MouseEvent):void {
//for prediction direction later - mouse point 2
mouseX2 = stage.mouseX;
//trace("2: " + mouseX2);
//remove mc move with mouse
removeEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
//check for direction of the mc based on mouseX1 and mouseX2
mouseDirection();
}
function onEnterFrameHandler(e:Event):void {
contents.x = parent.mouseX + selectX;
}
function mouseDirection():void {
if (mouseX1 > mouseX2) {
trace("to the left");
toLeftTween();
} else if (mouseX1 < mouseX2) {
trace("to the right");
toRightTween();
} else {
trace("nothing happened");
}
}
function toLeftTween():void {
if(contents.x<1 && contents.x>199) {
mcPosX = 0;
trace("to left - Panel 1");
} else if(contents.x<-1 && contents.x>-199) {
mcPosX = -200;
trace("to left - Panel 2");
} else if(contents.x<-201 && contents.x>-399) {
mcPosX = -400;
trace("to left - Panel 3");
} else if(contents.x<-401 && contents.x>-599) {
mcPosX = -600;
trace("to left - Panel 4");
} else if(contents.x>-600) {
//What happens now?
}
var toLeftTween:TweenLite = new TweenLite(contents,0.25, {x:mcPosX});
}
function toRightTween():void {
if(contents.x<-601 && contents.x>-799) {
mcPosX = -600;
trace("to right - Panel 4");
} else if(contents.x<-401 && contents.x>-599) {
mcPosX = -400;
trace("to right - Panel 3");
} else if(contents.x<-201 && contents.x>-399) {
mcPosX = -200;
trace("to right - Panel 2");
} else if(contents.x<-1 && contents.x>-199) {
mcPosX = 0;
trace("to right - Panel 1");
} else if(contents.x<-2) {
//What happens now?
}
var toRightTween:TweenLite = new TweenLite(contents,0.25, {x:mcPosX});
}
Good work. The solution is actually quite simple, when you see it.
You need to check the distance between your starting mouse point and your current mouse point, every frame, which it looks like you're doing with selectX and mouseX. Your problem is that when you go past a certain distance, you have no logic to handle your loop.
Because it's a loop, you want to check whether the distance between your starting point and current point is greater than the width of your carousel movieclip, which is 800. If so, you need the logic to loop back on itself. (However, I'm not sure why your toLeftTween and toRightTween functions check that contents.x is in a negative range....I suppose that's because of the registration point on the movieclip?)
(Edit: I see what you did - why you have the negative numbers. You're sliding the movieclip to the left as needed. Now that I'm looking at the way you did this, the modulus won't actually work because you're checking a range between -600 and 200, instead of a range between 0 and 800...)
You'll need something like this.
function toLeftTween():void {
// If contents.x is divisible by the width of the movieclip, it's greater than the mc width.
// We check this here, and grab the remainder.
if (contents.x > 800 || contents.x < -600)
contents.x = contents.x % 800; // Modulus operator. Returns remainder.
if(contents.x<1 && contents.x>199) {
mcPosX = 0;
trace("to left - Panel 1");
} else if(contents.x<-1 && contents.x>-199) {
mcPosX = -200;
trace("to left - Panel 2");
} else if(contents.x<-201 && contents.x>-399) {
mcPosX = -400;
trace("to left - Panel 3");
} else if(contents.x<-401 && contents.x>-599) {
mcPosX = -600;
trace("to left - Panel 4");
} else if(contents.x>-600) { // I think you flipped a sign here... -lunchmeat
//What happens now?
// Due to the modulus, we should never find ourselves in this situation!
}
var toLeftTween:TweenLite = new TweenLite(contents,0.25, {x:mcPosX});
}
That should do the trick, more or less. You'll need to add this to both tween functions. (It might need a little tweaking.) Let me know if you run into any problems. Good luck!
if you want something like
(Note:numbers stands for panels, and index 0 is initial point.)
for index 0
1 - 2 - 3 - 4
for index 1
2 - 3 - 4 - 1
for index -1
4 - 1 - 2 - 3
Seems like you heading wrong way.
First if u need continues loop you have to move movieclips that is out of view to the end. And you need a clone of first element at the end of items for continues look. I would prefer to use bitmapData of content so you wont need a clone of first element and it ll compute faster and the way is easier.

AS3: How to make this mouse position detection work properly?

I'm new to AS3 so please bare with my basic questions.
What I want to do is have a left arrow MC on the left side of the stage and right arrow MC on the right side of stage. When the mouse is over the left 1/3 of the stage, the left arrow appears, on the right 1/3 of the stage, the right arrow appears, but the middle 1/3 the arrows fade out.
I do NOT want to make large invisible MCs and detect the mouse movement that way. I just want it to be relative to the mouse position on the stage.
I thought it would be very easy, but the eventListener fires everytime the mouse moves, so the left and right arrow MC animation is constantly being triggered, and they look like they are "shaking" for a lack of a better word.
What I have so far is the following. Could someone please give me some help with this?
var stagePos:int = stage.width/3;
addEventListener(MouseEvent.MOUSE_MOVE, arrowDetectHandler);
function arrowDetectHandler(e:MouseEvent) {
var mouseArrow:int = mouseX;
if (mouseArrow<stagePos) {
arrowLeft_mc.gotoAndPlay("Show");
trace ("left arrow show");
} else if (mouseArrow>stagePos && mouseArrow<stagePos*2) {
arrowLeft_mc.gotoAndPlay("Hide");
arrowRight_mc.gotoAndPlay("Hide");
trace ("nothing happens");
} else if (mouseArrow>stagePos*2) {
arrowRight_mc.gotoAndPlay("Show");
trace ("right arrow show");
}
}
if...else seem to be ok. The only thing which may couse the problem is mc.gotoAndPlay. Try to use alpha property instead:
var stagePos:int = stage.width/3;
addEventListener(MouseEvent.MOUSE_MOVE, arrowDetectHandler);
function arrowDetectHandler(e:MouseEvent) {
var mouseArrow:int = mouseX;
if (mouseArrow<stagePos) {
arrowLeft_mc.alpha = 1; //alpha is 1, arrow is shown
trace ("left arrow show");
} else if (mouseArrow>stagePos && mouseArrow<stagePos*2) {
arrowLeft_mc.alpha = 0; //alpha is 0, arrow is hidden
arrowRight_mc.alpha = 0;
trace ("nothing happens");
} else if (mouseArrow>stagePos*2) {
arrowRight_mc.alpha = 1;
trace ("right arrow show");
}
}
The trouble is the speed with which your code is getting called repeatedly.
If you you are listening to MouseEvent.MOUSE_MOVE then it will happen way too fast for any 'gotoAndPlay' business to finish.
Since you don't want to do the invisible MovieClips ( which gives you the very handy MouseEvent.ROLL_OVER and MouseEvent.ROLL_OUT events ) then you are left polling to evaluate coordinates like you have in your code.
You need to remember the last 'answer' your code gave and then ignore the case that is already true next time. You'll have to bear with my preference for switch statements.
var stagePos:int = stage.width/3;
var _arrowShowing : int = 0;
addEventListener(MouseEvent.MOUSE_MOVE, arrowDetectHandler);
function arrowDetectHandler(e:MouseEvent)
{
var mouseArrow:int = mouseX;
switch( true )
{
case ( !_arrowShowing == 1 && mouseArrow < stagePos ) :
_arrowShowing = 1;
arrowLeft_mc.gotoAndPlay("Show");
trace ("left arrow show");
break;
case ( !_arrowShowing == 0 && mouseArrow > stagePos && mouseArrow < stagePos * 2 ) :
_arrowShowing = 0;
arrowLeft_mc.gotoAndPlay("Hide");
arrowRight_mc.gotoAndPlay("Hide");
trace ("nothing happens");
break;
case ( !_arrowShowing == 2 && mouseArrow>stagePos*2 ) :
_arrowShowing = 2;
arrowRight_mc.gotoAndPlay("Show");
trace ("right arrow show");
break;
}
}