I cannot remove a listener
Hello there. I've nearly finished doing an AS3 game in which you should move a frog in X axis in order to catch the flies that fall down.
But each time I press in a button which leads you to "play again"
I got a function which gets called twice and affects the gameplay
The line i'm talking about is this one:
Code:
stage.addEventListener(Event.ENTER_FRAME , mover);
I know it should be removed by calling:
Code:
stage.removeEventListener(Event.ENTER_FRAME , mover);
but, wherever I write it, no matter where, it simply doesn't work
If I write it before i need ;obviously the function gets null and you can't move the frog
And if I write it when I need it; the "compilador" shows me an error which says that I'm trying to access to an undefined property
Where is my mistake ?
this is the code:
For the 1st AS frame: (to start playing the game)
Code:
//PARA QUE NO ARRANQUE DE UNA
stop();
//PARA MODIFICAR EL TEXTO DINAMICO DEL BOTON
start_mc.but_txt.text="Comenzar";
//PARA QUE LE BOTON ESTE HABILITADO
start_mc.buttonMode=true;
//ASI PODEMOS TOCAR SIN QUE INFLUYA LO DE ADENTRO DEL BOTON
start_mc.mouseChildren=false;
function comenzarjuego (e:MouseEvent):void{
gotoAndStop("juego");
}
start_mc.addEventListener(MouseEvent.CLICK,comenzarjuego);
For the 2nd AS FRAME, the one with the troublesome line
Code:
stage.addEventListener(Event.ENTER_FRAME , mover);
here:
Code:
//A LA RANA LE DAMOS LA CLASE QUE LE CREAMOS
var agarrador:Agarrador;
//PARA CREAR VARIOS ENEMIGOS
var crearIDenemigo:uint;
//VA A SERVIR PARA CADA CUANTO APARECEN
var velocidadJuego:uint;
var atrapadasText:TextField;
var erradasText:TextField;
var score:uint=0;
//PARA EMPEZAR CON EL JUEGO
function iniciarJuego():void{
//SPAWNEO A MI PERSONAJE
agarrador=new Agarrador();
//LA POSICION DE MI PERSONAJE
agarrador.x=400;
agarrador.y=510;
//PARA QUE NO APAREZCA DE UNA EN EL STAGE
addChild(agarrador);
//PARA ESPECIFICAR CADA CUANTO APARECE UN ENEMIGO
//A MENOR VALOR MAS RAPIDO APARECEN
velocidadJuego=500;
//PARA EL INTERVALO DE ENEMIGOS EN APARECER
crearIDenemigo=setInterval(crearID,velocidadJuego);
//ESCONDE EL MOUSE
Mouse.hide();
erradasText=new TextField();
erradasText.x=50;
erradasText.y=50;
addChild(erradasText);
atrapadasText=new TextField();
atrapadasText.x=250;
atrapadasText.y=50;
addChild(atrapadasText);
erradasText.text=atrapadasText.text="0";
//PARA MOVER LA RANITA CON EL TECLADO
//IMPORTAS LOS EVENTOS DE TECLADO
import flash.events.KeyboardEvent;
//LA SIGUIENTE LINEA ES PARA QUE NO PIERDA EL FOCUS
//AL HABER HECHO CLICK EN EL BOTON "COMENZAR"
stage.stageFocusRect = false;
stage.focus = stage;
//YA ESTAMOS SOBRE EL TECLADO EN SI
stage.addEventListener(KeyboardEvent.KEY_DOWN, presionoTecla);
stage.addEventListener(KeyboardEvent.KEY_UP, sueltoTecla);
//EL LISTENER PARA LA FUNCION MOVER QUE VA A ESCUCHAR A CADA FRAME
stage.addEventListener(Event.ENTER_FRAME , mover);
//LAS VARIABLES TRUE O FALSE DE MOVIMIENTO A IZQ./DER. DE LA RANITA
var izquierda:Boolean;
var derecha:Boolean;
// Lo de la rotación y el flip me salió a mi solito (H)
//DOS VARIABLES QUE LAS USO PARA MARCAR QUE YA ROTO UNA VEZ
//QUE ES COMO LO QUIERO PORQUE SINO EN VEZ DE MOVERSE
//EL PERSONAJE RODARIA CADA VEZ
var inclinadoIzq:Boolean;
var inclinadoDer:Boolean;
// PARA SABER CUANDO SUELTO TECLA Y NO ESTA PULSADA
var pulsadoLeft:Boolean;
var pulsadoRight:Boolean;
//PARA IMPEDIR QUE CUANDO YO QUIERA
//QUE AL SOLTAR LA TECLA LA RANA VUELVA A SU POSICION
//ESTA SE PONGA A ROTAR PARA EL OTRO LADO SIN PARAR
//EN TRUE ESTA ACTIVADO
var bloqueadorRight = true;
var bloqueadorLeft= true;
function mover(e:Event):void {
if (derecha&&inclinadoDer==false) {
agarrador.rotation+=20;
//CON inclinadoDer Y EN TRUE YA SE MARCA QUE SE HIZO
//Y NO VUELVA A HACERSE GRACIAS QUE EL IF LO PIDE
//EN FALSE
inclinadoDer = true;
}
if (derecha) {
agarrador.x+=15
//MUEVE EN X Y AL ESCALAR CON +1 ES LO CONTRARIO AL -1
//QUE SUCEDE CON LA IZQUIERDA QUE ES COMO HACER FLIP
agarrador.scaleX=+1;
//QUIERO QUE LA POSICION SE ARREGLE CUANDO SUELTO (DERECHA)
pulsadoRight=true;
//SACO EL BLOQUEO
bloqueadorRight = false;
}else {
pulsadoRight=false;
}
//CUANDO ESTA SIN EL BLOQUEO Y LA TECLA DESPULSADO {
if (pulsadoRight==false&&bloqueadorRight==false){
//ES ROTACION -10 PORQUE AL HACER (derecha) LE SUME +10
agarrador.rotation-=20;
//Y LUEGO DE QUE ARREGLE LA POSCION PONGO A
//bloqueadorRight EN TRUE PARA QUE NO SIGA HACIENDO -10
//GRACIAS A LA CONDICION DEL IF,QUE LO PIDE EN FALSE
bloqueadorRight = true;
inclinadoDer = false;
}
//////////////////////TODO LO MISMO PARA LA IZQUIERDA AHORA
//////////////////////AL REVES EL MOV. EN X Y LA ROTACION
if (izquierda) {
agarrador.x-=15;
pulsadoLeft=true;
//SCALE EN -1 PORQUE LA RANA
//DE POR SI YA VIENE DE LADO DERECHO
agarrador.scaleX=-1
bloqueadorLeft = false;
}else {
pulsadoLeft=false;
}
if (izquierda&&inclinadoIzq==false) {
agarrador.rotation-=20;
inclinadoIzq = true;
}
if (pulsadoLeft==false&&bloqueadorLeft==false){
agarrador.rotation+=20;
bloqueadorLeft = true;
inclinadoIzq = false;
}
//PARA QUE NO SE VAYA DEL STAGE
if(agarrador.x > stage.stageWidth - agarrador.width / 2){
agarrador.x-=15
}
if(agarrador.x < agarrador.width / 2){
agarrador.x+=15
}
//OTRA SOLUCION /*
/*var agarradorRightSide = agarrador.x + agarrador.width;
if (agarradorRightSide >= 800) {
agarrador.x = 759 - agarrador.width;
}
else if (agarrador.x <= 0) {
agarrador.x = 1;
} */
}
function sueltoTecla(event:KeyboardEvent):void {
switch (event.keyCode) {
case Keyboard.LEFT :
izquierda=false;
break;
case Keyboard.RIGHT :
derecha=false;
break;
default :
break;
}
}
function presionoTecla(event:KeyboardEvent):void {
switch (event.keyCode) {
case Keyboard.LEFT :
izquierda=true;
break;
case Keyboard.RIGHT :
derecha=true;
break;
default :
break;
}
}
//
}
//ESTAMOS CREANDO A LOS ENEMIGOS , DE LA CLASE CAYENDO
function crearID():void{
var enemigo:Cayendo=new Cayendo()
//QUE ESTE EN Y FUERA DE LA PANTALLA Y ALEATORIAMENTE EN X
enemigo.y=-50;
enemigo.x=Math.random()*stage.stageWidth;
enemigo.addEventListener(Event.ENTER_FRAME,dropEnemy);
// ESTO ES PARA AGREGARLOA LA DISPLAY LIST Y QUE APAREZCA SINO NO CAE
addChild(enemigo);
}
function dropEnemy(e:Event):void{
//esto es para hacer mas facil la caida y que caiga de a 10 x frame
//y se le podria agregar cosas de hit detection
// CADA movieclip clase CAYENDO esta observado por el enterframe
var mc:Cayendo=Cayendo(e.target);
//PARA LA VELOCIDAD DE LA CAIDA DE LOS ENEMIGOS
//A MAYOR VALOR MAS RAPIDO CAEN
mc.y+=10
//CONTACTO CON LA RANA O NO ATAJADA POR ELLA
if(mc.hitTestObject(agarrador)){
//FUNCION
atrapadas(mc);
}else if(mc.y>stage.stageHeight){
//FUNCION
erradas(mc);
}
}
function atrapadas(mc:Cayendo):void{
//HAY QUE DETENER EL EVENTO DE ENTERFRAME DE QUE CAIGAN MAS
mc.removeEventListener(Event.ENTER_FRAME,dropEnemy);
removeChild(mc);
atrapadasText.text=String(Number(atrapadasText.text)+1);
}
function erradas(mc:Cayendo):void{
//HAY QUE DETENER EL EVENTO DE ENTERFRAME DE QUE CAIGAN MAS
mc.removeEventListener(Event.ENTER_FRAME,dropEnemy);
removeChild(mc);
erradasText.text=String(Number(erradasText.text)+1);
//PARA EL GAME OVER
if(erradasText.text=="5"){
gameOver();
}
}
function gameOver():void{
//ACA PARA QUE CALCULE EL PUNTAHE
score=Number(atrapadasText.text);
removeChild(agarrador);
clearInterval(crearIDenemigo);
removeChild(atrapadasText);
removeChild(erradasText);
//removimos todos los child pero POR AHI SOBRABA ALGUNO
while(numChildren>0){
//SI REMOVES EL 0 NO CORRES PELIGRO DE QUE SE CORRAN
getChildAt(0).removeEventListener(Event.ENTER_FRAME,dropEnemy);
//CON ESTO SE VAN CHUPANDO TODS A LA POSICION DE CERO Y ASI SE ELIMINAN
removeChildAt(0);
}
gotoAndStop("game over");
Mouse.show();
}
iniciarJuego();
stage.removeEventListener(Event.ENTER_FRAME , mover);
/*I get this solution from this forum before
You are adding an additional EventListener for the function "mover"
without removing the previous one. So on every frame, the "mover" function
gets called twice.
You could remove it by calling
"stage.removeEventListener(Event.ENTER_FRAME , mover);"
*/
And finally for the 3st AS FRAME: (game over and play again)
Code:
start_mc.but_txt.text="Jugar de nuevo";
//PARA QUE LE BOTON ESTE HABILITADO
start_mc.buttonMode=true;
//ASI PODEMOS TOCAR SIN QUE INFLUYA LO DE ADENTRO DEL BOTON
start_mc.mouseChildren=false;
start_mc.addEventListener(MouseEvent.CLICK,comenzarjuego);
score_txt.text="GAME OVER\nHas comido "+score+" moscas!."
/*function comenzarjuego (e:MouseEvent):void{
gotoAndStop("juego");
}*/ //NO HACE FALTA REESCRIBIRLA
I apologize for the lots of comments in the code, cuz I need to write them to explain what I did because this is for a school subject
The 'mover' function allows the player to move the frog and 'agarrador' designates that "frog" inside the code.
I need some help