how to change actionscript 1-2 to actionscript 3 - actionscript-3

In flash, I created a button and gave the button this code (in AS1-AS2)
on (release)
{
gotoAndPlay(5);
tellTarget("/Anim") //'Anim' is just short form for 'an animation'
{
gotoAndPlay(5);
} // End of TellTarget
}
Since you can't give specific buttons actions in AS3, I gave the button an instance name (the buttons instance name is now 'runButton') and then decided to do this in the actions layer.
runButton.addEventListener(MouseEvent.CLICK, startAnimation);
function startAnimation(event:MouseEvent){
gotoAndPlay(5);
tellTarget("/Anim")
{
gotoAndPlay(5);
} // End of TellTarget
}
but it is giving me an error saying that a '{' is expected after the
function startAnimation(event:MouseEvent):void{
line and it is saying that there is an unexpected '}' on the last line. Any idea how to fix this?
Note: Anim is a movieclip on the main timeline. When I double click the Anim movieclip, it has it's own timeline. I want that timeline to play along with the main timeline, hence the 'gotoandPlay(5) and then the other gotoAndPlay after doing 'tellTarget(Anim').

Use "with" instead of tellTarget. But I do not recommend this at all.
Instead:
this[ "/Anim" ].gotoAndPlay(5);

Similar to Discipol's answer though I think you'll need to cast to a movie clip first:
MovieClip(this[ "/Anim" ]).gotoAndPlay(5);

tellTarget is deprecated since Flash 5. (http://help.adobe.com/en_US/as2/reference/flashlite/WS5b3ccc516d4fbf351e63e3d118cd9b5f6e-7a2b.html)
function startAnimation(event:MouseEvent):void{
runButton.gotoAndPlay(5);
//that slash in the beginning of name (/Anim) I have no idea what to do with,
//basically it used to tell a moveiclip named "/Anim" to "gotoAndPlay" however,
//that is an invalid name so you probably have to change the name of it inside
//Flash unless I'm missing some kind of awesome legacy from old AS1/AS2.
runButton.Anim.gotoAndPlay(5);
}
runButton.addEventListener(MouseEvent.CLICK, startAnimation);

Okay found the answer, turns out I needed to change
tellTarget("/Anim") //'Anim' is just short form for 'an animation'
{
gotoAndPlay(5);
} // End of TellTarget
to just
Anim.gotoAndPlay(5)
and it worked.

Related

Why onPress function doesn't Work?

Here is my code :
stop();
btn_start.onPress = function()
gotoAndStop("gameon")
I have An error and it sounds like: "
Access of possibly undefined property onPress through a Reference with static type
flash.display:SimpleButton.
I converted the text into a Button, I gave him an id, I don't know what to do, don't judge, I'm begginer.
Thanks!
You problem is that your are trying to use the ActionScript 2's onPress() function inside an ActionScript 3 code which didn't support that kind of functions.
In ActionScript 3 you should use event listeners to catch an event on an object.
In your case, you can use, for example, a MouseEvent.CLICK event listener like this :
btn_start.addEventListener(MouseEvent.CLICK, on_Press);
function on_Press(e:MouseEvent): void
{
gotoAndStop('gameon');
}
And for more about migration from ActionScript 2 to ActionScript 3, take a look here.
Hope that can help.

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.

in AS3, removeEventListener(Event.ENTER_FRAME) is not working

I have been dealing with this problem for days already. I am at my wits' end!
I can't seem to find a definitive answer anywhere on any of the forums, documentation, etc.
Everything looks fine at first run, or when I load a next level for the user to play. But if the user hits the ESC key to load a different level, the ENTER FRAME listener does not get removed and it duplicates all the triggers in it, showing the player going really fast, and all funky, because it builds on top of the previously instantiated ENTER FRAME listener.
I don't know if I have a problem of an anonymous function, or an unknown instance being referenced in my removeEvent... command... Bottom line, I give up and I need this working HELP!!!
Here's the code:
function initPlay():void
{
//code here determining what display object to add to the list and assign it to the currentLevel variable (a movieclip)
if(userIsLoadingOtherLevel){
removeEnterFrameListener();
addChild(currentLevel);
}
if(userIsGointToNextLevel)
addChild(currentLevel);
currentLevel.addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame(event:Event):void
{
//collision detection, parallax scrolling, etc, etc is done here.
if(allCoinsCollected)
loadNextLevel();
if(ESCKeyPressed)
ESCKeyPressHandler();
}
function loadNextLevel():void
{
removeChild(currentLevel);
newLevelToLoad++
removeEnterFrameListener();
initPlay();
}
function ESCKeyPressHandler():void
{
removeChild(currentLevel);
initPlay();
}
function removeEnterFrameListener();
{
currentLevel.removeEventListener(Event.ENTER_FRAME,onEnterFrame)
trace("currentLevel.hasEventListener(Event.ENTER_FRAME) = "+currentLevel.hasEventListener(Event.ENTER_FRAME)); //outputs TRUE if called from loadNextLevel but FALSE if called from initPlay() !!!
}
}
I also tried to add and remove the eventListener to stage, MovieClip(Root), or nothing at all and the result is always the same.
I know that there may be other ways to design such a process, but please note I am not really flexible at the moment on doing this because the project is very long (about 4000 lines of code) and removing the ENTER FRAME this way, crazy or not should still work!!
THANK YOU in advance for anyone willing to help.
The problem appears to be the nested functions inside the initPlay() method.
Each time you call initPlay() you are defining new functions. Some of these nested functions call initPlay() themselves.
Functions are objects (memory references). So each time you call initPlay() you are making new references to new functions. So when you try to remove an event listener, you're only able to remove one of these event handlers (the one in the current scope of execution).
I'm not sure if I'm explaining this clearly, perhaps this example will help. I'll use numbers to represent the references to each function, and a simple scenario that is similar to yours:
function example():void
{
addEventListener(MouseEvent.CLICK, mouseClickHandler);
function mouseClickHandler(event:Event):void
{
if (someCondition)
{
example();
}
else
{
removeEventListener(MouseEvent.CLICK, mouseClickHandler);
}
}
}
When we run this function the first time, a new function is defined within the scope of the example() function. Lets use the number 1 to represent the reference to this nested function. someCondition is true on the first time around, and so the example() function is called again.
On the second execution of the example() function, a new reference to the mouse event handler is created (#2). We also add the event listener again. At this point, there are two event handling functions in memory, and both will be executed when the event is dispatched.
Let's say that in the second invocation of example() that someCondition is false and now we want to remove the listener. When we call:
removeEventListener(MouseEvent.CLICK, mouseClickHandler);
It's referring to event handler #2. Event handler #1 still exists, and because it's hidden in the scope of the first invocation of example() it can't be removed here.
My simple example breaks down after this... but I hope it makes it clear why your event handlers shouldn't be nested inside a function. Admittedly, this is difficult to describe and even more so in a real world example like yours. But I'm pretty confident that this is the source of most, if not all, of the issues you describe.
Here's how I was able to get around this without changing the scope of the nested functions (although I agree that would be the preferred solution) by creating a boolean variable called "loadingNewGame" and changing it to true from outside the onEnterFrame (in fact, this assignment was done from initPlay() and then from onEnterframe I called removeEnterFrameListener() function. This did the trick.
here's the code in case anybody is interested:
// package, and other code here.
var loadingNewGame:Boolean = new Boolean(false);
function initPlay():void
{
//code here determining what display object to add to the list and assign
//it to the currentLevel variable (a movieclip)
if(userIsLoadingOtherLevel)
{
loadingNewGame = true;
removeEnterFrameListener();
addChild(currentLevel);
}
if(userIsGointToNextLevel)
addChild(currentLevel);
loadingNewGame:Boolean = false;
currentLevel.addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onEnterFrame(event:Event):void
{
if(loadingNewGame)
removeChild(currentLevel);
//collision detection, parallax scrolling, etc, etc is done here.
if(allCoinsCollected)
loadNextLevel();
if(ESCKeyPressed)
ESCKeyPressHandler();
}
function loadNextLevel():void
{
removeChild(currentLevel);
newLevelToLoad++
removeEnterFrameListener();
initPlay();
}
function ESCKeyPressHandler():void
{
initPlay();
}
function removeEnterFrameListener();
{
currentLevel.removeEventListener(Event.ENTER_FRAME,onEnterFrame)
trace("currentLevel.hasEventListener(Event.ENTER_FRAME) = "+currentLevel.hasEventListener(Event.ENTER_FRAME));
//outputs true
}

Having trouble advancing frame in AS3 to advance frames

I'm creating a quiz with buttons and I'm new to ActionScript 3.0, but very familiar with 2.0.
I have a variable inside of a MC called NextQuestion. When it reaches a certain frame, it changes to 1, then back to 0.
On the main timeline, when NextQuestion == 1, it's supposed to NextFrame();. I can't get it to work though, this is the last thing I'm having trouble with.
This is my main code with 4 buttons, 3 wrong, 1 right. The feedback MC plays an animation, and when it finishes, it sets the VAR NextQuestion to 1, which is supposed to make the main timeline advance to the NextFrame.
stop();
right.addEventListener(MouseEvent.CLICK, rightClick1);
wrong1.addEventListener(MouseEvent.CLICK, wrongClick1);
wrong2.addEventListener(MouseEvent.CLICK, wrongClick1);
wrong3.addEventListener(MouseEvent.CLICK, wrongClick1);
feedback1.addEventListener(Event.ENTER_FRAME, answerRight1);
function answerRight1()
{
if (feedback1.NextQuestion == 1)
{
trace(feedback1.NextQuestion);
nextFrame();
}
else
{
trace("do nothing");
}
}
function rightClick1(ev:MouseEvent):void
{
trace(feedback1.NextQuestion);
feedback1.gotoAndPlay("right1");
}
function wrongClick1(ev:MouseEvent):void
{
trace("wrong");
feedback1.gotoAndPlay("wrong");
}
Any help is greatly appreciated! :)
The nextFrame() method in AS3 doesn't loop trough your movieClips, it just set's the movie clip to the next frame provided there is a next frame, otherwise it does nothing.
you might want to re-write the nextFrame() to:
if (totalFrames == currentFrame)
{
gotoAndStop(1); // or gotoAndPlay(1) if you need
}
else
{
nextFrame();
}
Thats regarding why the movie clip might not start from the beginning.
Another thing that look weird is that you need a FRAME_ENTER event to check if the answer is correct. You must have a lot of spam in the output log. I'd recommend you to totally ditch the ENTER_FRAME event listener for this and do it all with the CLICKED event and dispatching the event from the feedback1 object.
As much as I understand the movie clip plays when you click a button and when the animation is over you want to either progress to next frame or do nothing. If so, on the feedback1 object add a following line in the end of animation for label "right1":
dispatchEvent(new Event("right"));
and instead of the line feedback1.addEventListener(Event.ENTER_FRAME, answerRight1); have:
feedback1.addEventListener("right", answerRight1);
That way you won't need to check the answer on every frame and you don't need to check if the answer is right or not, because when the dispatchEvent(new Event("right")); fires - it's always right.
Hope I didn't misunderstand your question :)

actionscript 3.0 function mouseevent event handler

I have a function that uses a mouse event and it removes and adds things onto the stage:
beginBut.addEventListener(MouseEvent.CLICK, bgnListener);
function bgnListener (event:MouseEvent) {
removeEventListener(Event.ENTER_FRAME, setScreen);
removeChild(beginBut);
removeChild(myWord);
healthBar.addEventListener(Event.ENTER_FRAME, healthLose);
ball.addEventListener(Event.ENTER_FRAME, moveBall);
myGem.addEventListener(Event.ENTER_FRAME, addGem);
myScore.addEventListener(Event.ENTER_FRAME, scoreCount);
healthBar.width+=1000;
}
However after some other things happen, I need this event to occur again. I have already
added beginBut but when I use
beginBut.addEventListener(MouseEvent.CLICK, bgnListener);
the event adds and removes the things automatically when the function that adds beginBut back occurs and not when I actually click on beginBut. I have also tried
bgnListener();
but it says that there is the wrong number of arguments. I already searched all over and I can't seem to fix this. Any help would be greatly appreciated.
If you call bgnListener() like you are now, you'll get an argument mismatch error because the function is expecting to receive a MouseEvent.
If you want to be able to call bgnListener() on its own like that, you can define a default value for your argument event, which can be null:
function bgnListener(event:MouseEvent = null)
{
// ...
}