moving around the stage(doing a full lap) before ending at a certain point - actionscript-3

How do I make that the object that I click, start moving in circles ( 2,3 ) around the stage
before arriving at its end position.Like in this picture
the way I figured out it could be is something like this:
private function onClick( ev:MouseEvent ):void
{
var currentObj:Sprite = ev.currentTarget as Sprite;
TweenLite.to(currentObj, 1, {x:first_X, y:first_Y, onComplete:goToPosition2 });
function goToPosition2():void
{
TweenLite.to(currentObj, 1, {x:secontd_X, y:second_Y, onComplete:goToPosition3 });
}
function goToPosition3():void
{
TweenLite.to(currentObj, 1, {x:third_X, y:third_Y, onComplete:goToPosition4 });
}
..
..
.
.
.
//and so on and so on
}
yet I somehow feel that this is very wrong way of doing it.

A bit interesting, another way of solving it can be to create a movieclip that contains a 'handle' clip inside that follows a motion path. Call this the 'driver clip'.
Then to get a shape/another moiveclip to follow along it, start the driver clip playing at frame 1 and add an event handler. In the event handler, on every frame sync the x and y of the object you want to the driver clip's handle clip inside. Also can set the visibility of that handle clip to false to hide it. When the driver clip reaches the end frame, you can remove the event listener and the shape will be in its finish position.
This method would work for a very irregular shape that would take too long to manually plot in code (assuming you're using the flash ide).

Simple way: contain your object within a parent MovieClip, near its periphery. On click, rotate the parent and also increase its scale, so that your object traces a spiral path.

Related

setchildindex is creating problems

I have made a simple drag and match game for kids.
I used setchildindex for movie clips to be dragged but when I click next button and go to another frame but movie clips are remaining in the same stage. What should i do?
Here is my code I used: (drag_1, this.numChildren0);.
When I reload it's not working.
drag_1.buttonMode = true;
drag_1.addEventListener(MouseEvent.MOUSE_UP, dropMe_1);
drag_1.addEventListener(MouseEvent.MOUSE_DOWN, dragMe_1);
var back_1X:Number = back_1.x;
var back_1Y:Number = back_1.y;
var hit_2X:Number = hit_2.x;
var hit_2Y:Number = hit_2.y;
function dragMe_1(event:MouseEvent)
{
drag_1.startDrag()
setChildIndex(drag_1, this.numChildren-1);
}
function dropMe_1(event:MouseEvent)
{
drag_1.stopDrag();
if(drag_1.hitTestObject(drop_2))
{
TweenMax.to(drag_1, 0.5, {
x:hit_2X,
y:hit_2Y,
ease:Cubic.easeOut
});
drag_1.mouseEnabled = false;
SoundMixer.stopAll();
}
else
{
TweenMax.to(drag_1, 0.5,
{
x:back_1X,
y:back_1Y,
ease:Bounce.easeOut
});
}
}
You need to remove the MovieClips using removeChild().
Now, why do you need to do that here? Well, this is one of those odd problems you get when you mix the timeline with code. When you place a symbol on the timeline keyframe, the Flash Player will instantiate that symbol when it reaches that frame. After that, any frame on the timeline that updates the symbol (tweens, effects, etc) will do just that, and any frame that lacks the symbol will remove it. However, the Flash Player is very picky about identifying that symbol on each frame of the timeline. When you move it using setChildIndex you are basically breaking the timeline link, and the Flash Player no longer identifies it and removes it based on the keyframes. You'll also find that if you revisit a keyframe that had that symbol, the Flash Player will instantiate a second one regardless if the one you moved is still there. As you can see, it can get pretty messy.

"Smooth and Regular" scroll in flash

I am working on a news ticker in Flash AS3. The code is reading some RSS from CNN and generates a MovieClip with headline text one after another. Now this movieclip starts scrolling from right to left. For scrolling I am using TweenLite. I don't want any easing, just want a regular and smooth scrolling.
I have used both options:
TweenLite.to(news_mc, 60, {x:minX} );
and
TweenLite.to(news_mc, 60, {x:minX, ease:Linear.easeNone} );
But, in both case, the animation is not smooth. It starts scrolling speedily and at last it becomes very slow.
I've seen something similar to this. Are you implementing your TweenLite call in a loop? You should only be calling for a tween on the target object once. Only once that tween is finished or you want a brand new tween on that object should you call TweenLite.to with that target object again.
Seeing as how you're only after a linear tween, would it not be simpler to simply increment/decrement the target's X every frame? Something like this:
this.addEventListener(Event.ENTER_FRAME, onEnterFrame)
private function onEnterFrame(e:Event):void
{
if(news_mc.x > minX)
{
news_mc.x -= 3 //This is a shot in the dark, tweak this for your values
}
else
{
news_mc.x = maxX
}
}

How to make a stick man running when pressing a key?

I created a movieclip named stickman. In that, I created an animation by drawing a sequence of move in everyframe, so that stickman can run. Now what I want is that when I press a key, the stick man will run from left to right and when I release the key, it will stop. This is my code:
RunningMan.stop();
stage.addEventListener(KeyboardEvent.KEY_DOWN,keypresseddown);
function keypresseddown(event:KeyboardEvent):void
{
var key:uint = event.keyCode;
switch (key) {
case Keyboard.LEFT :
{
RunningMan.play();
RunningMan.x-=10;
RunningMan.scaleX=-1;
if(RunningMan.x<=0)
{
RunningMan.x=0;
}
};
case Keyboard.RIGHT :
{
RunningMan.play(); //play animated run
RunningMan.x+=10;
RunningMan.scaleX=1;
if(RunningMan.x>=stage.width)
{
RunningMan.x=stage.width;
}
};
default: RunningMan.stop();
}
}
However, when I pressed and held a key, it moved from left to right without animated run.
How can I fix it?
Thanks in advance.
EDIT:
I have a movieclip called character containing 3 movieclip named: standing, running and jumping, respectively. When I pressed up arrow key, it would jump, but if I released the key right away, it did not jump high as the jump movieclip could not finish its frames. This is the code:
if (key.isDown(Keyboard.LEFT))
{
gotoAndStop("running");
BGround.x+=speed;
scaleX=-1;
if(BGround.x>=stage.stageWidth)
BGround.x=stage.stageWidth;
}
else if (key.isDown(Keyboard.RIGHT))
{
gotoAndStop("running");
BGround.x -= speed;
scaleX=1;
}
else
if (key.isDown(Keyboard.UP))
{
gotoAndStop("jumping");
}
else
gotoAndStop("standing");
How can I fix that?
First of all, I hope RunningMan is an instance of the class, not the class itself. And if it is an instance, you should really follow common naming conventions for when you share your code with others (like you are doing now) so it would be runningMan.
So 1st, make the 1st frame of the runnigMan's timeline a picture of the man standing still and name it "still" or something. then name the second "running" and extend that like 20 frames or however long your animation is. at the last frame you will have to use timeline code. just one line of gotoAndPlay("running") will cause those frames of 2 to 20 (or whatever) to loop. When you tell the timeline to go to frame 1 from outside the timeline code, it wont loop anymore and will stay on the frame of the man standing still. So from outside when you want the loop to start:
runningMan.gotoAndPlay("running"); // frame 2
To stop:
runningMan.gotoAndStop("still"); // frame 1
Or you could do it from inside the RunningMan class
public function startRunAnimation():void{
this.gotoAndPlay("running");
}
public function stopRunAnimation():void{
this.gotoAndStop("still");
}
And you could use them just by replacing these function names with the ones you have if your code ex( instead of play() it would be startRunAnimation() )
EDIT
What you could do for this problem is to have a boolean variable for when your character is in the air (somewhere in your code where you do collision detection with the ground or where you handle gravity - however it is set up) so that this part of your code know when your character is in the air. And then you could simple test for this however way you need it.
...
if (key.isDown(Keyboard.UP) || this.inAir==true)
{
gotoAndStop("jumping");
}
else
gotoAndStop("standing");
Although if your character does not inheirt from a collidable object that has gravity, friction etc... then you would have to make the inAir property of whatever other class, public or make getter function for it - so that you can access it here. I hope this helps.

Removing Children in AS3

My flash game exists of a timeline with multiple frames (I know I should avoid the timeline)
The point of the game is a point and click adventure. The object that you are able to pick up get spawned and destroyed accordingly as you enter and leave the room. now my problem is when entering frame 14 (accessibel from frame 12) it creates a piece of paper which you are able to pick up if you have another item. Now my problem is when you can't or don't pick up the paper and go back to frame 12 (only exit is to frame 12), you can't click on any other object and you are basicly stuck on frame 12. When leaving and entering other rooms it works properly but for some reason it doesn't for on the paper on frame 14.
My code to remove objects works as following
In my Main.as Documentclass I have a function that called as soon as the game starts which does the following
if (lastframe == 14)
{
trace (prop.numChildren);
while (prop.numChildren )
{
prop.removeChildAt(0);
}
}
The lastframe variable is established when moving from frames
this function is found on the frame itself (each exit function on it's own respective frame)
function exitKantine(event:MouseEvent):void
{
Main.lastframe = 14;
gotoAndStop(12);
}
The function to remove the prop actually removes it but then causes all other clickable objects to be unusable.
Thanks for looking at my question and thanks in advance for your suggestions
I would say instead of removing children, add it once in the beginning, add all the listeners in the beginning, and toggle the visibility instead of trying to addChild and removeChild every time you want to hide it. Use an array so you can have a few happening at the same time.
something like this:
private function init():void
{
assignVars();
addListeners();
stage.addChild // make sure this is in document class or you are passing stage to the class using it
}
for (var i = 0; i < _thingsAry.length; i++)
{
if (_thingsAry[i] == 14)
{
_thingsAry[i].visible = false;
trace("the visibility of _thingsAry[" + i + "] is " + _thingsAry[i].visible
}
}

Timeline instances not on first frame

It's been a while since I've had to write Actionscript that really needs to integrate with the timeline (in this case, controlling a series of frames that must happen in a certain sequence) and I am trying to figure out what to do.
In the first few frames, I have a button "next_1".
At frame 10, I need to have another button "next_2". I really really need this button to not be on frame one (I could possibly just make it invisible, but that's going to create a clickable area that I don't want).
The problem is, anything I don't put on "frame_1" renders as null in my Document class.
Is there any solution to this? I would rather not have to write my script on the timeline if possible (it seems easier in the long run to keep it in a document class)...
Items on the timeline are created on the fly, so if the playhead has not reached frame 10, next_2 is not created.
Easiest Document-class solution:
Create an array of frame labels like ["label1", "label2"]
Create sectionIndex var and set it to 0
Create a next button on its own layer so it is always showing.
When the next button is clicked, increment sectionIndex, then gotoAndPlay(myLabels[sectionIndex])
Okay, directly lifted from "Real World Flash Game Development":
/**************************************************
* FRAME LABELS *
**************************************************/
private function enumerateFrameLabels():void {
for each (var label:FrameLabel in currentLabels) {
addFrameScript(label.frame-1, dispatchFrameEvent);
}
}
private function dispatchFrameEvent():void {
dispatchEvent(new Event(currentLabel, true));
}
This dispatches an event at each frame label on the timeline.
Then you can just add event listeners for each frame:
addEventListener("name_of_my_framelabel", frameHandler);
addEventListener("another_framelabel", frameHandler);
And write a switch statement to add event listeners for the buttons when they actually show up on the timeline.
private function frameHandler(e:Event):void {
switch(e.type) {
case 'screen_2':
stop();
next_2.addEventListener(MouseEvent.CLICK, click2, false, 0, true)
break;
}
}