Cómo ejecutar solo algo cada 30 cuadros

Mi pregunta es la siguiente, quiero agregar una roca cada segundo (30 fotogramas por segundo), tengo diferentes niveles, esto significa que tengo diferentes cantidades de rocas en cada nivel y tengo diferentes cantidades de velocidades, entonces quiero agregar 10 rocas en un total de 30 segundos en el nivel 1 en el nivel 2 son 20 rocas en un total de 20 segundos etc. Estoy abierto a cambiarlo por completo, solo quiero la mejor solución. Quiero que sea dinámico para poder hacer muchos niveles. ¿Cómo debo hacer esto?

No quiero mantener un contador y cada vez que esté en 30, agregue una roca y reinícielo.

Gracias de antemano

switch(difficulty)
            {
                case 1:
                    timer = 30;
                    numberOfRocks = 10;
                    break;
                case 2:
                    timer = 20;
                    numberOfRocks = 20;
                    break;
                case 3:
                    timer = 10;
                    numberOfRocks = 30;
                    break;
                case 4:
                    timer = 5;
                    numberOfRocks = 40;
                    break;
            }

            addEventListener(Event.ENTER_FRAME, loop)
        }
        private function loop(e:Event):void
        {   
            for (var i:int = 0; i < (timer * 30); i++)
            {
                    a_bitmap = new a_class();
                    a_bitmap.x = 750;
                    a_bitmap.y = Math.ceil(Math.random() * (600 - a_bitmap.height));
                    a_bitmap.height = 35;
                    a_bitmap.width = 35;
                    addChild(a_bitmap);
                    a_bitmap.name = "astroid" + i + "";
                    myArray.push(true);
            }
        }

preguntado el 29 de junio de 12 a las 19:06

"No quiero mantener un contador y cada vez que esté en 30, agregue una roca y reinícielo". - ¿Por qué diablos no? -

puedes usar esto setInterval or setTimeout -

4 Respuestas

Un temporizador puede funcionar mejor para sus necesidades que un controlador de cuadros. Recomiendo usar las matemáticas para calcular los parámetros de nivel en lugar de las declaraciones de cambio codificadas, luego puede agregar tantos niveles como desee (o hacer que su juego dure indefinidamente)

var rockLoadTimer:Timer;

function gameInit():void {
    //your games initialization code here

    //create a timer that fires every second when running
    rockLoadTimer = new Timer(1000);

    //the function to call every time the timer fires.  You could also listen for TIMER_COMPLETE is wanted to run a function once all rocks are loaded
    rockLoadTimer.addEventListener(TimerEvent.TIMER, addNextRock);
}

function startLevel(difficulty:int = 1):void {
    //your code here to clear the level 


    //repeat count is used as the amount of rocks to load this level - level number times 10
    rockLoadTimer.repeatCount = difficulty * 10;

    //the delay time is how quickly you want the rocks to load.  this is 5 seconds divided by the difficulty level
    //so the first level would be every 5 seconds, second would be every 2 and a half seconds, third level would be every second and two thirds. etc.  
    rockLoadTimer.delay = Math.round(5000 / difficulty);

    rockLoadTimer.reset();
    rockLoadTimer.start();

}

function addNextRock(e:Event = null):void {
    //your rock creation code here
}

Respondido el 29 de junio de 12 a las 20:06

Puedes utilizar una Timery crear una instancia de a_class durante cada tic:

var timer:Timer = new Timer(1000, 30); // One per second for 30 seconds
timer.addEventListener(TimerEvent.TIMER, addAsteroid);
timer.start();
function addAsteroid():void {
    a_bitmap = new a_class();
    // etc.
}

El retraso del temporizador es "asteroides por milisegundo", por lo que si desea crear 10 en 30 segundos, debe configurarlo en 30000/10 = 3000.

Sin embargo, este enfoque funciona mejor cuando hay una velocidad de fotogramas fluida: se ejecutará una vez por segundo, pero la cantidad de fotogramas de la animación puede variar si Flash se ejecuta a menos de 30 fps. Si su juego funciona como creo que lo hace, esto podría resultar en que los asteroides se "amontonen". Entonces, mantener un contador podría ser la mejor solución aquí, a menos que planee manejar el resto de la lógica de su juego (es decir, la velocidad de movimiento de los asteroides) de una manera que pueda tener en cuenta las variaciones en la velocidad de fotogramas.

Si desea utilizar un contador:

var creationCounter:Number = 0; // put this at class level

// Then in the ENTER_FRAME event:
creationCounter += asteroids_per_second / 30; 
while (creationCounter-- >= 1) {
    a_bitmap = new a_class();
    // etc.
}

Respondido el 29 de junio de 12 a las 21:06

¿Qué valor debo usar para createCounter? y supongo que 1 sería un buen valor para astroid_per_second? - corsé110

creationCounter debe ser una variable de nivel de clase para que su valor permanezca entre llamadas, y debe comenzar en 0. Y asteroids_per_second sería 1 si quieres un asteroide cada 30 fotogramas, o más alto si quieres aumentar la dificultad. - QuesoBrujo

También puede usar la función flash.utils.setInterval.

setInterval(trace , 1000 , "trace message once per second");

Respondido el 30 de junio de 12 a las 16:06

Si utiliza TweenLite, puedes usar el delayedCall función, puede usar tiempo o marcos,

// delayedCall(delay:Number, onComplete:Function, onCompleteParams:Array = null, useFrames:Boolean = false):TweenMax
TweenLite.delayedCall(30, addAstroid, null, true);

Más información, consulte los documentos: http://www.greensock.com/as/docs/tween/com/greensock/TweenMax.html#delayedCall()

Respondido el 30 de junio de 12 a las 09:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.