How to only execute something every 30 frames - actionscript-3

My question is this, I want to add a rock every second (30 frames per second), I have different levels, this means I have different amounts of rocks in each level and I have different amount of speeds, so I want to add 10 rocks in a total of 30 seconds in level 1
in level 2 it's 20 rocks in a total of 20 seconds etc. I'm open to completly changing it, I just want the best solution. I want it to be dynamic so I can make a lot of levels. How should I got about doing this
I don't want to keep a counter and every time it's at 30 then add a rock and reset it.
Thank you in advance
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);
}
}

A Timer may work better for you're needs than a frame handler. I'd recommend using math to calculate your level parameters instead of hard-coded switch statements, then you can add as many levels as you'd like (or have your game go indefinitely)
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
}

You can use a Timer, and create an instance of a_class during each tick:
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.
}
The timer delay is "asteroids per millisecond", so if you want to create 10 over 30 seconds you would set it to 30000/10 = 3000.
However, this approach works best when there is a smooth framerate- it will execute once per second, but the number of frames of animation can vary if Flash is running at less than 30fps. If your game works how I think it does, this could result in asteroids being "bunched up". So, keeping a counter might be the better solution here, unless you plan on handling the rest of your game logic (i.e. asteroid movement speed) in a way that can account for variations in frame rate.
If you want to use a counter:
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.
}

You can also use flash.utils.setInterval function .
setInterval(trace , 1000 , "trace message once per second");

If you use TweenLite, you can use the delayedCall function, it can use time or frames,
// delayedCall(delay:Number, onComplete:Function, onCompleteParams:Array = null, useFrames:Boolean = false):TweenMax
TweenLite.delayedCall(30, addAstroid, null, true);
More info, see the docs: http://www.greensock.com/as/docs/tween/com/greensock/TweenMax.html#delayedCall()

Related

Countdown timer in a flash game

I'm making a simple helicopter game to try and get into making flash games. I wanted to make a countdown timer that will count down from 3 seconds, then start the loop, but I'm not sure how to go about is. I don't use the frames in flash, rather I use action script (3) to make an "ENTER_FRAME" loop, if that helps. It looks like this:
addEventListener(Event.ENTER_FRAME, mainLoop);
I'm sure I need to put the timer above it, I'm just not sure how to make a timer. Any advice will probably help, as I'm new to AS3, thanks.
To make a countdown timer, you can use a Timer, like this :
trace('3');
// create a timer with : delay: 1 second, repeats: 3
var timer:Timer = new Timer(1000, 3);
timer.addEventListener(
TimerEvent.TIMER,
// on every repeat
function(e:TimerEvent):void {
trace(Math.abs(timer.currentCount - 3)); // gives : 2, 1, 0
}
)
timer.addEventListener(
TimerEvent.TIMER_COMPLETE,
// at the timer end
function(e:TimerEvent):void {
// do other instructions
trace('go');
}
)
// start the timer
timer.start();
Hope that can help.
I hope i can help you with your code. What im getting is that you try to make 3 seconds count down then start somewhere.
yes you need a timer :
var theTime:Timer
theTime = new Timer(countDownLoading*1000); //1000 is in milisecond
var countDown = 1;
var totalCountDown = 3; // How long it'g gonna count
var countDownLap = totalLoading;
theTime.addEventListener(TimerEvent.TIMER,tick); //adding timer event
function tick(e:TimerEvent){
if(countDownLap == 0)//if the cound down is 0
{
time.stop();
gotoAndStop(2);
trace("Finish counting");
} else { //not counting down yet, then lets count
countDownLap = countDownLap - countDown; //
trace(countDownLap);
}
//timer goes like the ticking clock so if the count down is not 0.
//everytime the ticking starts the cound down (3) - 1
}
I hope this help.

Making health reduce by 1 every second

I'm programming a tamagotci style game and I need to health by one, every second. I already have a score number in place that is changed when you feed the target. I would be incredibly grateful if someone could give me a hand in editing the current code I have at the moment, to reduce health by 1 every second. Here is my code if anyone needs to see it;
health=100
txtform.font = "Arial";
txtform.color = 0x000000;
txtform.size = 24;
txtform.bold = true;
healthdisplay.defaultTextFormat=txtform;
addChild(healthdisplay);
healthdisplay.text=("Health: " + health)
healthdisplay.x=75
healthdisplay.y=-20
healthdisplay.autoSize=TextFieldAutoSize.CENTER;
}
public function IncreaseHealth(points:int){
health+=points
healthdisplay.text=("Health: " + health)
healthdisplay.defaultTextFormat=txtform;
}
Make a function DecreaseHealth() that you call every second. Something like:
var timer:Timer = new Timer(1000); // 1 second = 1000 milliseconds.
timer.addEventListener(TimerEvent.TIMER, DecreaseHealth);
timer.start();
Where DecreaseHealth() has the following signature:
function DecreaseHealth(event:TimerEvent):void
{
health -= 1;
// Do printing or whatever else here.
}

Actionscript 3.0 timer to save time

im doing a basic game in action script and now i want to do a timer.
I want that the timer starts count when the game starts and in the end of the game when the player can do ten points i want to say in textfield that if the time was more than 5 minutes it was very bad if the timer was less than 2minutes very good and things like this!
Im trying do this but the timer dont count, anyone can help?
Thanks!
theTime.addEventListener(Event.ENTER_FRAME,showTime);
function showTime(event:Event):void {
var myTime:Date = new Date();
var theMinutes=myTime.getMinutes();
theTime.text =theMinutes;
}
new Date(); gives a Date object which contains the current date and time. To keep track of passed time you need to keep track of start and end time and find their difference. You can do this by using time property. Something like this:
// Do this when you start the game.
var startTime:Number = (new Date()).time;
// Do this when the game is over
var endTime:Number = (new Date()).time;
const MILLI_SECOND_IN_5_MIN:Number = 5 * 60 * 1000;
const MILLI_SECOND_IN_2_MIN:Number = 5 * 60 * 1000;
var timeDiff:Number = endTime - startTime;
if (timeDiff < MILLI_SECOND_IN_2_MIN) {
trace("Good");
} else if (timeDiff > MILLI_SECOND_IN_5_MIN) {
trace("Bad");
}

Is this a good implementation of the gameloop

I have implemented a gameloop in Flash/Actionscript/Starling and I want to throw it at you to see if this is a valid implementation.
I wanted to have a variable time step approach.
private var _deltaTime:Number = 0;
private var _lastTime:Number = 0;
private var _speed = 1000 / 40;
private function onEnterFrame() {
var now = new Date().getTime();
var delta = now - _lastTime;
_deltaTime += delta - _speed;
_lastTime = now;
//skip if frame rate to fast
if (_deltaTime <= -_speed) {
_deltaTime += _speed;
return;
}
update();
}
private function update() {
updateGameState();
if (_deltaTime >= _speed) {
_deltaTime -= _speed;
update();
}
}
What I got sofar is that I have a constant speed (more or less).
My question is is there a better approach so that the movements will appear even
smoother.
What is really surprising to me is that even thou the FPS is pretty much constant (60FPS)
the movement is sometimes bumpy yet smoother than with the naive gameloop.
Youre on the right track - assuming that onEnterFrame is triggered in some way by Event.ENTER_FRAME - instead of skipping update, call it on every frame but pass in the time elapsed:
private function onEnterFrame() {
var now = new Date().getTime();
var delta = now - _lastTime;
_lastTime = now;
updateGameState(delta/1000);//divide by 1000 to give time in seconds
}
In updateGameState, you can utilise 'delta' to calculate movement etc, eg:
function updateGameState(timeElapsed:Number):void {
myAlien.x += myAlienSpeedPerSecond*timeElapsed;
}
This way you get smooth movement even when frame rate varies.
from the Starling introduction pages, it shows that time elapsed is built into the EnterFrameEvent class.
// the corresponding event listener
private function onEnterFrame(event:EnterFrameEvent):void
{
trace("Time passed since last frame: " + event.passedTime);
enemy.moveBy(event.passedTime * enemy.velocity);
}
http://wiki.starling-framework.org/manual/animation#enterframeevent

How to give a score based on time?

In the game I am making, I need to make a scoring system based on time.
If you get a match in the first second of gameplay. That match is worth more points, than if I get a match on the last second of gameplay.
So in other words, the faster you do the level, the more points you get. Does anyone know how to achieve this? I know the total time for each level.
The game is real time so it needs to be seen to show high scores early in the game with a decreasing score as time goes on.
Thanks.
Define a maximum time per level then do some math tricks:
score = Math.max(0, levelMaxTime - timeSpent) * levelScore;
Example:
timeSpent = 12; // The player completed the level in 12 seconds
levelMaxTime = 20; // The player has to completed the level within 30 seconds
levelScore = 50; // The player will be awarded of 50 points per remaining second
// Compute the final score
score = Math.max(0, levelMaxTime - timeSpent) * levelScore; // 400 points
You use the Timer Class for this. So you should end with something similar to :
private var delay:uint = 1000;
private var repeat:uint = 3;
private var timer:Timer = new Timer(delay, repeat);
Add listeners for the ticks...
timer.addEventListener(TimerEvent.TIMER, timerHandler);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, completeHandler);
// Reduce bonus with time by a percentage
private function timerHandler(e:TimerEvent):void { scoreBonus *= 0.9; }
// Set bonus to 0
private function completeHandler(e:TimerEvent):void { scoreBonus = 0; }
Now set the score bonus & start the timer at the point where you wish to begin the bonus from.
scoreBonus = 10;
timer.start();
So at any point of time, you just need to add the bonus to the total score.