I am fairly new to actionscript 3 and I would like to know how can I make EventListener to work only once. Right now it works after every click, but I need to get it work only with first click.
After click it displays a ball on the stage where the click was made. I need to get to the point where only one ball appears and after that click should do nothing.
my code:
stage.addEventListener(MouseEvent.CLICK, onClick,false,0,true);
function onClick(evt:MouseEvent):void {
var ball:MovieClip = new Ball();
ball.x = stage.mouseX;
ball.y = stage.mouseY;
addChildAt(ball,0);
}
You need to call removeEventListener() as follows:
stage.addEventListener(MouseEvent.CLICK, onClick,false,0,true);
function onClick(evt:MouseEvent):void {
stage.removeEventListener(MouseEvent.CLICK, onClick);
var ball:MovieClip = new Ball();
ball.x = stage.mouseX;
ball.y = stage.mouseY;
addChildAt(ball,0);
}
One possible solution is to remove the EventListener.
stage.addEventListener(MouseEvent.CLICK, onClick,false,0,true);
function onClick(evt:MouseEvent):void {
stage.removeEventListener(MouseEvent.CLICK, onClick);
var ball:MovieClip = new Ball();
ball.x = stage.mouseX;
ball.y = stage.mouseY;
addChildAt(ball,0);
}
Another solution is a simple bool variable, in case you need the eventlistener for something else.
var clickedOnce:Boolean = false;
stage.addEventListener(MouseEvent.CLICK, onClick,false,0,true);
function onClick(evt:MouseEvent):void {
if(!clickedOnce){
clickedOnce = true;
var ball:MovieClip = new Ball();
ball.x = stage.mouseX;
ball.y = stage.mouseY;
addChildAt(ball,0);
}
}
Related
How do I loaded MovieClips in the position of the mouse with a different name on each click? or I have to make several different MovieClips to laod?
please help me :)
Is this what you're trying to do?
var counter:int = 0;
stage.addEventListener(MouseEvent.CLICK, click);
function click(event:MouseEvent):void
{
var mc:MovieClip = new MovieClip(); // Or new YourExportedLibraryClip();
mc.name = 'mc_' + (counter++);
mc.x = stage.mouseX;
mc.y = stage.mouseY;
stage.addChild(mc);
}
First I really want to thank you for all the help you have given me so far, since I did not know anything about AS3 (basics gotoAnd stuff only) I came to Stackoverflow searching for some code already made but I was encouraged by some members to make the code by myself, now after almost 2 weeks and thanks to a lot of great people my soccer penalty kick game is almost finished, I really love this place.
I know I have to work on some collisions and other stuff since currently the game is not the best (remember I’m just a newbie), but Unfortunately while checking the game functioning by playing it over and over again, I have found the following:
1- When you get 3 fails, then game is over and a play again button appears after some animation, you click on it and everything seems to be fine, but when you continue playing the second time you reach 3 fails, when you click the button a new cursor appears??? Please help
2- I tried millions of times to make the ball move with speed and to animate its trajectory but was unable to make it, any help on this will be highly appreciated. I have speed variables and gravity but I didn’t know how to use them
3- I'm getting a actionscript error related to a removeChild, I tried many times removing some lines but I´m unable to fix it.
4- I'm using too many timers, I don't know if this is recommendable.
Here is the .fla file https://rapidshare.com/files/1702748636/kicks.fla just in case anybody want to try the game (this is really simple since it is my 1st AS project) and want to help me with the code and help me improving the game, and here is the code if somebody does not need to get into the file (I know this place is full of really smart people), once I finish it I know I will be able to do a lot of stuff with AS3.
var score:Number;
var angle:Number;
var speed:Number;
var cursor:MovieClip;
var failed:Number;
var ballRotation:Boolean = false;
function initializeGame( ):void
{
ball.x = 296.35;
ball.y = 353.35;
score=0;
failed=0;
cursor = new Cursor();
addChild(cursor);
cursor.enabled = true;
Mouse.hide();
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragCursor);
stage.addEventListener(MouseEvent.CLICK, kick);
}
function dragCursor(event:MouseEvent):void
{
cursor.x = this.mouseX;
cursor.y = this.mouseY;
}
initializeGame();
var mouse = this.Mouse;
function kick(evt:Event)
{
removeChild(cursor);
pateador_mc.play();
var timer:Timer = new Timer(500,1);
timer.addEventListener(TimerEvent.TIMER, delayedAction);
timer.start();
function delayedAction(e:TimerEvent)
{
moveBall();
}
}
speed=-100000;
var ease:int = 100;
var gravity:Number = 0.5;
function moveBall()
{
var targetX:Number = mouseX;
var targetY:Number = mouseY;
var angle = Math.atan2(targetY,targetX);
ball.x = mouseX + Math.cos(angle);
ball.y = mouseY + Math.sin(angle) ;
ballRotation = true;
stage.removeEventListener(MouseEvent.CLICK, kick);
if (ballRotation==true)
{
keeper.gotoAndStop(1 + Math.floor(Math.random() * keeper.totalFrames));
ball.play();
}
if (ball.hitTestObject ( keeper)){
ball.y=keeper.x-ball.height- ball.width;
trace ("Tomela");
}
if (ball.hitTestObject(goalie) && ball.y>69 /*&& ball.y<178 && ball.X>139 && ball.x<466*/)
{
gol_mc.play();
score ++;
showScore();
var timer3:Timer = new Timer(3000,1);
timer3.addEventListener(TimerEvent.TIMER, delayedAction3);
timer3.start();
function delayedAction3(e:TimerEvent)
{
ball.x = 296.35;
ball.y = 353.35;
stage.addEventListener(MouseEvent.CLICK, kick);
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragCursor);
addChild(cursor);
keeper.gotoAndStop(1);
}
}
else
{
fails_mc.play();
failed++;
var timer2:Timer = new Timer(3000,1);
timer2.addEventListener(TimerEvent.TIMER, delayedAction2);
timer2.start();
function delayedAction2(e:TimerEvent)
{
ball.x = 296.35;
ball.y = 353.35;
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragCursor);
stage.addEventListener(MouseEvent.CLICK, kick);
addChild(cursor);
keeper.gotoAndStop(1);
}
trace(failed);
if (failed==3) {
gameFinished();
trace("YOU LOST");
}
}
function showScore():void{
goles_txt.text ="" +score;
}
trace (score);
function gameFinished(){
gameOver.play ();
stage.removeEventListener(MouseEvent.CLICK, kick);
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragCursor);
timer2.stop();
Mouse.show();
this.mouseX=cursor.x ;
this.mouseY=cursor.y;
again_btn.addEventListener(MouseEvent.MOUSE_DOWN, playAgain);
}
function playAgain():void{
gameOver.gotoAndPlay(31);
fails_mc.gotoAndStop(1);
keeper.play();
var timer4:Timer = new Timer(1000,1);
timer4.addEventListener(TimerEvent.TIMER, delayedAction3);
timer4.start();
function delayedAction3(e:TimerEvent)
{
initializeGame();
}
}
}
I’ll really appreciate it guys , I promise I won’t be bothering again for a long time
1/3.
Problem 1 & 3 are the same problem. Looks like your trying to remove the cursor from the stage (removeChild) every click (so it will error after the first click because it's no longer a child of anything). Your adding it back on your delayedAction2 which doesn't run unless your hit test is true and only after 3 seconds. On initialize game you create a whole new cursor and add that to the stage which is why you get a duplicate after the first game.
Rather than removeChild the cursor, it might better to just set it's visibility to false/true and only create it once.
You'll need to use an EnterFrame handler, or timer, or tween for this. I can post an example later.
I can't figure out why you're using timers at all or need to delay your functions, except maybe to allow time for the kick animation?
You're code is very disorganized, naming functions things like 'delayedAction' is bad as it doesn't really tell you anything about the purposed of the function. You also have way too much functions inside of other functions. Here is a quick refactoring of your code I've done to hopefully teach a few things. I've also added the tween for the ball animation.
import flash.events.Event;
import fl.transitions.Tween;
import fl.transitions.TweenEvent;
var score:Number;
var cursor:MovieClip;
var failed:Number;
var ballRotation:Boolean = false;
var ballTweenX:Tween;
var ballTweenY:Tween;
var targetCursor = new Cursor(); //only want one of these and you want it to exist the whole time so keep out here.
addChild(targetCursor);
initializeGame();
function initializeGame( ):void
{
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragCursor);
stage.addEventListener(MouseEvent.CLICK, kick);
ball.x = 296.35;
ball.y = 353.35;
score=0;
failed=0;
targetCursor.visible = true;
Mouse.hide();
}
function dragCursor(event:MouseEvent):void
{
targetCursor.x = this.mouseX;
targetCursor.y = this.mouseY;
}
function kick(evt:Event)
{
//removeChild(targetCursor);
targetCursor.visible = false;
pateador_mc.play();
stage.removeEventListener(MouseEvent.CLICK, kick); //move this here, because you don't the option kick again while already kicking
stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragCursor); //added this, you probably don't want the target moving after the click...
setTimeout(moveBall, 500);//cleaner and more efficient than using a timer for a one time delayed call.
}
function moveBall()
{
var targetX:Number = mouseX;
var targetY:Number = mouseY;
var angle = Math.atan2(targetY,targetX);
targetX = mouseX + Math.cos(angle);
targetY = mouseY + Math.sin(angle) ;
ballRotation = true;
ballTweenX = new Tween(ball, "x", null, ball.x, targetX, .3, true);
ballTweenY = new Tween(ball, "y", null, ball.y, targetY, .3, true);
ballTweenY.addEventListener(TweenEvent.MOTION_FINISH, ballTweenDone,false,0,true);
if (ballRotation==true)
{
keeper.gotoAndStop(1 + Math.floor(Math.random() * keeper.totalFrames));
ball.play();
}
}
function stopBallTween():void {
ballTweenX.stop();
ballTweenY.stop();
}
function ballTweenDone(e:TweenEvent):void {
if (ball.hitTestObject ( keeper)){
ball.y=keeper.x-ball.height- ball.width;
trace ("Tomela");
}
if (ball.hitTestObject(goalie) && ball.y>69 /*&& ball.y<178 && ball.X>139 && ball.x<466*/)
{
gol_mc.play();
score ++;
showScore();
}else
{
fails_mc.play();
failed++;
trace(failed);
if (failed==3) {
gameFinished();
trace("YOU LOST");
return; //added this because you don't want the rest of this function running if it's a game over
}
}
setTimeout(resetShot, 3000); //you had the code I put in resetShot repeated twice
trace(score);
}
function resetShot():void {
ball.x = 296.35;
ball.y = 353.35;
targetCursor.visible = true;
keeper.gotoAndStop(1);
stage.addEventListener(MouseEvent.MOUSE_MOVE, dragCursor);
stage.addEventListener(MouseEvent.CLICK, kick);
}
function showScore():void{
goles_txt.text ="" +score;
}
function gameFinished(){
gameOver.play();
stage.removeEventListener(MouseEvent.CLICK, kick);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, dragCursor);
Mouse.show();
//this.mouseX=cursor.x ;
//this.mouseY=cursor.y; //These are read only properties, your can't set the mouse position...
again_btn.addEventListener(MouseEvent.MOUSE_DOWN, playAgain);
}
function playAgain(e:Event = null):void{
gameOver.gotoAndPlay(31);
fails_mc.gotoAndStop(1);
keeper.play();
setTimeout(initializeGame, 1000);
}
Here is piece of class which called right after i already drawn some objects in it, problem is when i have sprite.addChild(textfield) included it starting to blink alot.
addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandler);
addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
}
private function mouseOverHandler(e:MouseEvent):void{
//creating a new tooltip instance
var tooltip:Sprite = new Sprite();
/*//we tell the holder to hold our tooltip
holder = tooltip;
//adding text to the tooltip
//tooltip.myText = "ASS";
//positioning the tooltip on the stage
holder.x = stage.mouseX;
holder.y = stage.mouseY - 15;
//adding the tooltip to the stage*/
textfield.selectable = false;
textformat.align = TextFormatAlign.CENTER;
textformat.size = 12;
textformat.color = 0x000000;
textfield.defaultTextFormat = textformat;
textfield.x = x;
textfield.y = y;
textfield.width = width;
textfield.height = height;
textfield.text = myName;
sprite.graphics.lineStyle(2,0x00BB00);
sprite.graphics.beginFill(0xFFFFFF, 1);
sprite.graphics.drawRect(x, y, width, height);
sprite.graphics.endFill();
sprite.addChild(textfield);
sprite.x = stage.mouseX;
sprite.y = stage.mouseY - 15;
tooltip.addChild(sprite);
//holder.addChild(tooltip);
addChild(sprite)
}
private function mouseOutHandler(e:MouseEvent):void{
//we remove the holder when the cursor is outside our button
removeChild(sprite);
}
//we create this function to move the tooltip everytime the cursor is moved
private function mouseMoveHandler(e:MouseEvent):void{
sprite.x = stage.mouseX;
sprite.y = stage.mouseY - 15;
}
Even i'm not sure about that, this might explain your problem. You can give more information for better solution.
"when you add sprite, it calls mouseOutHandler, cause you add your sprite under your cursor. And you remove the sprite with //removeChild(sprite); and mouseOverHandler calls again. And it goes like that."
how can i change the cursor when my cursor is only within this pop out panel and not in the main stage ?
private function launchPopUp(e:MouseEvent):void
{
panel = new Panel();
panel.width = stage.stageWidth;
panel.height = stage.stageHeight;
panel.setStyle("borderAlpha", 1);
PopUpManager.addPopUp(panel, this, true);
PopUpManager.centerPopUp(panel);
}
Would appreciate if anyone could help.
You can use the following code to change the mousecursor. The trick is to hide the mousecursor and replace it with a sprite.
function launchPopUp(e:MouseEvent):void
{
panel = new Panel();
panel.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveFunc);
panel.addEventListener(MouseEvent.MOUSE_OUT, mouseOutFunc);
panel.width = stage.stageWidth;
panel.height = stage.stageHeight;
panel.setStyle("borderAlpha", 1);
PopUpManager.addPopUp(panel, this, true);
PopUpManager.centerPopUp(panel);
}
function mouseMoveFunc(e:MouseEvent):void
{
Mouse.hide();
customMouseSprite.visible = true;
customMouseSprite.x = e.stageX;
customMouseSprite.y = e.stageY;
}
function mouseOutFunc(e:MouseEvent):void
{
Mouse.show();
customMouseSprite.visible = false;;
}
You also need to call the mouseOutFunc when the popup is closed. the customMouseSprite has to be on the top layer of your stage. customMouseSprite can either be a sprite or movieclip (in fact any displayobject).
I have a movieClip with two buttons inside.
The problem is that when the mouse is over these two buttons, the code that manages the movieClip stops working, as if the mouse is not over the MC (the buttons are children of the MC, shouldn't it work regardless?).
Could you please share some advice?
Thanks
/*mc follows mouse. I can't click btns because when mouse rollover btns the mc moves*/
function showImgOptions (e:Event):void{
if (mc.hitTestPoint(mouseX,mouseY,false)){
mc.y = mc.y;
mc.x = mc.x;
}else{
var delayX:int = mc.x - mouseX;
var delayY:int = mc.y - mouseY;
mc.x -= delayX / 6;
mc.y -= delayY/6;
}
}
mc.btn1.addEventListener (MouseEvent.CLICK, closeClick);
mc.btn2.addEventListener (MouseEvent.CLICK, zoomClick);
function closeClick (e:MouseEvent):void{}
function zoomClick (e:MouseEvent):void{}
stage.addEventListener (Event.ENTER_FRAME, showImgOptions);
addChild (mc);
Changed the code to:
var mc:menuMC = new menuMC();
addChild(mc);
var p:Point = mc.localToGlobal(new Point(mc.mouseX,mc.mouseY));
/*mc follows mouse. I can't click btns because when mouse rollover btns the mc moves*/
function showImgOptions (e:Event):void
{
if (! mc.hitTestPoint(p.x,p.y,false))
{
mc.y = mc.y;
mc.x = mc.x;
}else{
//move mc towards mc.parent's mouseX and mouseY
var delayX:int = mc.x - mouseX;
var delayY:int = mc.y - mouseY;
mc.x -= delayX / 6;
mc.y-=delayY/6;
}
}
mc.btn1.addEventListener (MouseEvent.CLICK, closeClick);
mc.btn2.addEventListener (MouseEvent.CLICK, zoomClick);
function closeClick (e:MouseEvent):void
{
}
function zoomClick (e:MouseEvent):void
{
}
stage.addEventListener (Event.ENTER_FRAME, showImgOptions);
And now I get this error:
TypeError: Error #1010: A term is undefined and has no properties.
Here you can download an FLA. Test it and try to click on the buttons 1 and 2, inside the MC following the mouse
hitTestPoint expects stage coordinates:
The x and y parameters specify a point in the coordinate space of the Stage, not the display object container that contains the display object (unless that display object container is the Stage).
Use localToGlobal to get the stage coordinates:
var p:Point = mc.localToGlobal(new Point(mc.mouseX, mc.mouseY));
if(!mc.hitTestPoint(p.x, p.y,false))
{
//move mc towards mc.parent's mouseX and mouseY
}
Solved it!!
Changed the code. I don't know if this helps anybody, but I hope so. Thanks to you all.
stage.addEventListener(Event.ENTER_FRAME, moveMC);
var mc:menuMC = new menuMC();
addChild(mc);
function moveMC(e:Event):void {
if (mc.hitTestObject(big_mc)) {
mc.visible = true;
} else {
mc.visible = false;
}
if (mc.hitTestPoint(mouseX,mouseY,false)) {
mc.y = mc.y;
mc.x = mc.x;
} else {
var delayX:int = mc.x - mouseX;
var delayY:int = mc.y - mouseY;
mc.x -= delayX / 6;
mc.y-=delayY/6;
}
}
mc.btn1.addEventListener(MouseEvent.CLICK, onBtn1);
mc.btn2.addEventListener(MouseEvent.CLICK, onBtn2);
function onBtn1(e:MouseEvent):void {
trace("do something");
}
function onBtn2(e:MouseEvent):void {
trace("do something else");
}