AS3 display final time - actionscript-3

I have a function that keeps track of the time elapsed in my main game file that looks like this:
public function timeElapsed(milliseconds:int):void
{
var time:Date = new Date(milliseconds);
var minutes:String = String(time.minutes);
var seconds:String = String(time.seconds);
var miliseconds:String = String(Math.round(time.milliseconds)/100);
if(minutes.length != 2)
{
minutes = '0' + minutes;
}
if(seconds.length != 2)
{
seconds = '0' + seconds;
}
trace(minutes + ":" + seconds + "." + miliseconds);
}
What I'm trying to figure out now is how to get it to display the FINAL time, when the player is killed. I have functions handling calls to other files for various events, but at the moment I'm drawing a complete blank on how to get the time to go from here, to displaying on the game over screen, which is it's own separate file.
Any thoughts?

For calculation of time elapsed in the game, you don't need Date class. You should use getTimer() - used to compute relative time. At the start of game register current time elapsed, and format difference as you want.
var start: int = getTimer();
//later, check difference
myTextField.text = timeElapsed(start);
function timeElapsed(start : int):String{
var dt: int = getTimer() - start;
//format result as you wish
return someFormatResult;
}
Display final time, do you want visualise result of time formatting? You could use simple TextField.

Related

Error 1009-handling

I want to make counterdown in quiz. In my quiz, after endtime it will go to another frame. The time is about 10 minutes, exactly. In this code I just write in 31 second to make it simple.
This is my code
import flash.events.*;
import flash.utils.Timer;
import flash.utils.getTimer;
stop()
var totSec:int = 31;
var totTime:Number = 1000 * totSec;
var secTimer:Timer = new Timer(1000,totSec);
secTimer.start ();
secTimer.addEventListener (TimerEvent.TIMER, updateClock);
function updateClock (t:TimerEvent) {
var timePassed:int = totTime - getTimer();
var second:int = Math.floor(timePassed/1000);
var minute:int = Math.floor(second/60);
//trace ("second : " + second);
second %= 60;
var sec:String = "";
sec = String(second);
if (second < 10)
{
sec = "0" + second;
}
var showTime:String = minute + " : " + sec;
timeDisplay.text = String(showTime)
if (minute == 0 && second == 0 )
{
gotoAndPlay(525);
//addEventListener (Event.ENTER_FRAME, stopTime);
trace ("Times up");
secTimer.start ();
}
}
But, when the frame go to frame 525, I get this error
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at adminserver/updateClock()
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
The issue:
Your timer actually ticks one more time after you do the following:
gotoAndPlay(525);
//addEventListener (Event.ENTER_FRAME, stopTime);
trace ("Times up");
secTimer.start(); <---------not sure what this is about?
So when it ticks again, you've actually gone to a different frame (525) where your timeDisplay text field no longer exists (presumably) - so the code errors.
when you change frames, code attached to listeners keeps running even if that code wasn't on the current frame
The Cleanest Solution
Instead of doing your own math to figure out when the timer is done, use the actual timer event for such:
secTimer.addEventListener(TimerEvent.TIMER_COMPLETE, .....
This way, you know the timer is done before your code runs and you change frames.
Here is a full example, along with some tips:
stop();
var totSec:int = 31;
//no need for this var, total time in your case is secTimer.repeatCount * secTimer.delay
//var totTime:Number = 1000 * totSec;
var secTimer:Timer = new Timer(1000,totSec);
secTimer.addEventListener(TimerEvent.TIMER, updateClock);
//listen for the complete event when the timer is all done
secTimer.addEventListener(TimerEvent.TIMER_COMPLETE, timerComplete);
secTimer.start();
function updateClock (e:TimerEvent) {
//the timer's currentCount will be how many times the timer has ticked,
//which in this case will be seconds elapsed.
//If you subtract that from the total repeat count, you'll get the seconds left,
//no need to use getTimer, which is now allows you to pause your timer if you'd like (can't pause using getTimer)
var second:int = secTimer.repeatCount - secTimer.currentCount;
var minute:int = Math.floor(second/60);
//trace ("second : " + second);
second %= 60;
var sec:String = String(second);
if (second < 10){
sec = "0" + second;
}
var showTime:String = minute + " : " + sec;
timeDisplay.text = String(showTime);
}
function timerComplete(e:TimerEvent):void {
trace ("Times up");
//secTimer.start(); //you don't really want to start the timer again - which does nothing anyway without a secTimer.reset() first
//you should also remove the listeners on the timer so it can freed for garbage collection
secTimer.removeEventListener(TimerEvent.TIMER, updateClock);
secTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, timerComplete);
gotoAndPlay(525);
}
I think that to avoid that error, you should stop that Timer before going to another frame :
// ...
trace ("Times up");
secTimer.stop();
gotoAndPlay(525);
// ...
Hope that can help.

How to get a time as a variable in Flash CS6

I am trying to get a time that is in a text document to become a variable in a Flash CS6 AS3 project. I can't seem to find where the problem is and the error messages aren't really helping. The highlighted parts are the changed lines.
Here is the newest code:
this.onEnterFrame = function()
{
var StartTime:URLLoader = new URLLoader();
StartTime.dataFormat=URLLoaderDataFormat.VARIABLES;
StartTime.addEventListener(Event.COMPLETE, onLoaded);
function onLoaded(e:Event):void {
}
StartTime.load(new URLRequest("ResponseTime.txt"));
var today:Date = new Date();
var currentTime = today.getTime();
var targetDate:Date = new Date();
var timeLeft = e.data - currentTime;
var sec = Math.floor(timeLeft/1000);
var min = Math.floor(sec/60);
sec = String(sec % 60);
if(sec.length < 2){
sec = "0" + sec;
}
min = String(min % 60);
if(min.length < 2){
min = "0" + min;
}
if(timeLeft > 0 ){
var counter:String = min + ":" + sec;
time_txt.text = counter;
}else{
var newTime:String = "00:00";
time_txt.text = newTime;
delete (this.onEnterFrame);
}
}
Newest Error:
1120: Access of undefined property e. (Line 17).
First of all, this does nothing :
var StartTime();
It's not correct AS3 code.
Then, AS3 loaders being asynchronous, you must way for the loader to finish load so you can get your variable. I mean that all your code after StartTime.load(...) must be inside the function onLoaded.
This way, when the loader finish loading, you'll have you variable.
That say, URLVariable is NOT a loader. It is an object you can use to put your variable into, and feed them to a loader.
If you want to download some file, use URLLoader (with URLRequest). On this page, there is a good example on how you can do that (skip the part about the dataFormat, though). The date you're requesting will be available in the data property of the event, eg :
var timeLeft = e.data - currentTime;
I'm not asking where currentTime is from, since it's out of the scope of that question.
Good luck.

Countdown in AS3 is looping out of control

Since Im new in AS3 and I just converted AS2 to AS3. The countdown doesnt work. Right now the 4 digits are looping out of control (The three digits animation is fine - ignore it)
See countdown - http://magnixsolutions.com/clients/OT/media-buys_scoreboard-redux_160x600_5-8-2009.html
FLA file - http://magnixsolutions.com/clients/OT/media-buys_scoreboard-redux_160x600_5-8-2009.fla
AS3
// stop the timeline
stop();
// first get this current year so this example
// remains valid for some time to come
var currentDate:Date = new Date();
var thisYear:int = currentDate.getFullYear();
var thisMonth:int = currentDate.getMonth();
var thisDate:int = currentDate.getDate();
var thisHour:int = currentDate.getHours();
var thisMinute:int = currentDate.getMinutes();
var thisSecond:int = currentDate.getSeconds() + 12;
var thisMSecond:int = currentDate.getMilliseconds();
// define the event date counting down to
// this is constant so it won't need to be
// calculated in the onEnterFrame function below
// currently counting down 'til christmas of 2003
// Date( year, month-1, date [, hour [, minute [, second [, millisecond]]]])
var eventDate = new Date(thisYear, thisMonth, thisDate, thisHour, thisMinute, thisSecond, thisMSecond);
var eventMillisecs = eventDate.getTime();
this.addEventListener(TimerEvent.TIMER, enterFrameHandler);
function enterFrameHandler(event:TimerEvent) {
// get the current date and time as it exists at
// this instance in time when the frame is entered
currentDate = new Date();
var currentMillisecs = currentDate.getTime();
// the milliseconds between the current time and the
// time of the event can then be calculated by simply
// subtracting the current time's milliseconds from the
// milliseconds of the time of the event
this.msecs = eventMillisecs - currentMillisecs;
// if the msecs variable is less than 0, that means the
// current time is greater that the time of the event
if (this.msecs <= 0){
// and the event time has been reached!
// play the next frame for the result of the countdown.
play();
// a return can be used to exit the function since
// in going to the next frame, there's no need to
// continue with the remaining operations.
return;
}
// if the date hasn't been reached, continue to
// devise seconds, minutes, hours and days from
// the calculated milliseconds
this.secs = Math.floor(this.msecs/1000); // 1000 milliseconds make a second
this.mins = Math.floor(this.secs/60); // 60 seconds make a minute
this.hours = Math.floor(this.mins/60); // 60 minutes make a hour
this.days = Math.floor(this.hours/24); // 24 hours make a second
// make sure each value doesn't exceed the range in
// which they exist. Milliseconds, for example, will
// be shown in a range of 0 - 999. The modulous
// operator, or %, well help in that. Here the values
// are also turned into strings preparing for the next step
this.msecs = int(this.msecs % 1000);
this.secs = int(this.secs % 60);
this.mins = int(this.mins % 60);
this.hours = int(this.hours % 24);
this.days = int(this.days);
// add on leading zeros for all the number values (which are
// now strings) that aren't 3 or 2 characters long based on the
// range being used to represent them. Because mseconds and
// days have up to 3 characters, a while loop is used to
// continuously add 0s until they have 3. Other values which
// only need 2 leading 0s can get by on a single if check
while (this.msecs.length < 3) this.msecs = "0" + this.msecs;
if (this.secs.length < 2) this.secs = "0" + this.secs;
if (this.mins.length < 2) this.mins = "0" + this.mins;
if (this.hours.length < 2) this.hours = "0" + this.hours;
while (this.days.length < 3) this.days = "0" + this.days;
// finally, display your values. If you want to put your values
// in a textField, you can pretty much just stop here and throw them
// into your textField as desired. This example, however will go a step
// further and use images for numbers for each numerical value in the
// countdown to the desired date.
// So, for that, loop through all the movies in this counter clip using the
// evaluateFrameFrom prototype method on each. A single check for a
// _parent variable is used to make sure the property found in a for
// loop is a movieclip and is within the timeline of this counter clip.
// TextFields and buttons would also be true here, but since the contents
// within counter are strictly those numbers movieclips, we won't have to
// be concerned with such complications. The only movieclips in this counter
// clip are the numbers movieclips with the frames of the imagery making up
// the numbers of 0-9.
for(var movie in this){
if (this[movie]._parent == this) this[movie].evaluateFrameFrom(this);
}
};
// this function is a MovieClip.prototype meaning its available to be used by
// all movieclips. It's a sneaky function that saves a lot of work by using
// name each numbers movieclip in the counter movieclip to determine which value
// it needs to display based on the times derived from the previous
// calculations of the onEnterFrame. What it does is seperates a movieclip's
// _name into a variable word and a number. The variable word will represent
// the variable to look up a value for in the passed variableClip and the
// number will be used to get a character from that value (a string) which
// represents which number this movieclip should display.
MovieClip.prototype.evaluateFrameFrom = function(variableClip){
// split this _name into an array of 2 values seperated by an underscore
var nameArray = this._name.split("_");
// the first value represents what variable in variableClip (counter clip)
// this movieclip is used to represent whether it be mins or hours etc.
var numberSet = variableClip[nameArray[0]];
// next a number representing which character in that first value this
// movieclip should display. this will be between 0 and 2 (any one of
// three values). number() is used to force it to be a number value.
var character:int = parseInt(nameArray[1]);
// a frame number can then be derived from the value of the numberset
// variable based on the character defined by character. number() is
// used to force it to a number value and 1 is added to offset the
// frame value by one since 0 is at frame 1 and 1 at frame 2 etc.
var frame = 1 + parseInt(numberSet.charAt(character));
// if the movieclip is not already at the frame, move it there!
if (this._currentframe != frame) this.gotoAndStop(frame);
};
and it is not showing any error messages within the codes.
I have created example of Countdown with milliseconds for you. Most valuable comments in the code.
//30fps update ratio
var rate:Number = 30, dt:Number;
var currentDate:Date = new Date();
//For testing - future date in 5 minutes
var targetDate:Date = new Date(currentDate.time + 5 * 60 * 1000);
var updateTimer:Timer = new Timer(1000 / rate);
var result:String = "";
var seconds:int, minutes:int, hours:int, days:int;
updateTimer.addEventListener(TimerEvent.TIMER, onTimer);
updateTimer.start();
//Display
var textField:TextField = new TextField();
addChild(textField);
function onTimer(e:TimerEvent):void {
//heavy lifting (new Date, leading zero formatting, etc) only every second
if ((updateTimer.currentCount - 1) % rate == 0) {
currentDate = new Date();
dt = targetDate.time - currentDate.time;
if (dt <= 0) {
updateTimer.removeEventListener(TimerEvent.TIMER, onTimer);
trace("the end!");
dt = 0;
}
seconds = dt / 1000;
minutes = seconds / 60;
hours = minutes / 60;
days = hours / 24;
hours %= 24;
minutes %= 60;
seconds %= 60;
result = days + ":" + ((hours < 10) ? "0" + hours : hours)
+ ":" + ((minutes < 10) ? "0" + minutes : minutes)
+ ":" + ((seconds < 10) ? "0" + seconds : seconds);
}
//Milliseconds, who cares?
textField.text = result + ":" + Math.random().toString().substr(2, 3);
}

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");
}

Action Script 3. Timer MM:SS doesn't work

I'm creating app and I need to show game time MM:SS format. But I don't know why timer doesn't wrok It shows 0:00.359 (359 of miliseconds) and not change. Where is the problem? I can't find It. Thank you.
var timer:Timer; //import flash.utils.Timer;
var txtTime:TextField;
var tmpTime:Number; //this will store the time when the game is started
//your constructor:
public function MemoryGame()
{
timer = new Timer(1000); //create a new timer that ticks every second.
timer.addEventListener(TimerEvent.TIMER, tick, false, 0, true); //listen for the timer tick
txtTime = new TextField();
addChild(txtTime);
tmpTime = flash.utils.getTimer();
timer.start(); //start the timer
//....the rest of your code
}
private function tick(e:Event):void {
txtTime.text = showTimePassed(flash.utils.getTimer() - tmpTime);
}
//this function will format your time like a stopwatch
function showTimePassed(startTime:int):String {
var leadingZeroMS:String = ""; //how many leading 0's to put in front of the miliseconds
var leadingZeroS:String = ""; //how many leading 0's to put in front of the seconds
var time = getTimer() - startTime; //this gets the amount of miliseconds elapsed
var miliseconds = (time % 1000); // modulus (%) gives you the remainder after dividing,
if (miliseconds < 10) { //if less than two digits, add a leading 0
leadingZeroMS = "0";
}
var seconds = Math.floor((time / 1000) % 60); //this gets the amount of seconds
if (seconds < 10) { //if seconds are less than two digits, add the leading zero
leadingZeroS = "0";
}
var minutes = Math.floor( (time / (60 * 1000) ) ); //60 seconds times 1000 miliseocnds gets the minutes
return minutes + ":" + leadingZeroS + seconds + "." + leadingZeroMS + miliseconds;
}
//in your you-win block of code:
var score = flash.utils.getTimer() - tmpTime; //this store how many milliseconds it took them to complete the game.
Try
timer.currentCount
instead of
flash.utils.getTimer()
It will return the number of times the timer has fired the TIMER-Event.
You need not do this.
var time = getTimer() - startTime;
In your code, startTime is already time elapsed due to
showTimePassed(flash.utils.getTimer() - tmpTime);
OR
you can call
showTimePassed();
and change time calculation as
var time = getTimer() - tmpTime;