How to get a time as a variable in Flash CS6 - actionscript-3

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.

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.

AS3 display final time

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.

Show my timer time during my basic game

Im doing a little game in actionscript, and i have a timer that starts when the gamer starts and end when the game ends.
But i want to show in a textfield the value of my timer during the game like 1,2,3,4,5,6, etc.
How can i can acess that timer propriety to get the value?
My timer code is this:
startTime = (new Date().time);
endTime = (new Date().time);
public function testTime():void
{
const 5_min = 5 * 60 * 1000;
const 2_min = 2 * 60 * 1000;
var timeDiff:Number = endTime - startTime;
if (timeDiff < 2_min) {
trace("Good!");
} else {
trace("Bad!");
}
}
And here (above) i create a txt field. Now, how i can show the timer value while playing the game?
var timer_txt:TextField;
pontuacao = new TextField();
timeDiff = 0;
timer_txt = new TextField();
timer_txt.text = String(timeDiff);
stage.addChild(timer_txt);
timer_txt.x = 470;
timer_txt.y = 320;
Well, first of all, in AS you cannot begin your variable names with a number, therefore this code should absolutely not compile (5_min, 2_min = WRONG!).
You have your startTime, which is ok. Now you will have to check the current time in some kind of event (Timer, EnterFrame) or interval (setInterval) and update the endTime value accordingly. Once you have it, you just count the difference and divide it by 1000 (I assume you don't want to show it in millis)
Something like this:
import flash.utils.setInterval;
var s:Number = new Date().getTime(); //start time
var e:Number; //end time
var d:Number; //difference
setInterval(function () {
e = new Date().getTime();
var oldDiff:Number = d;
d = int((e - s) / 1000);
if(oldDiff != d) trace(d + " seconds since launch");
},
100
);

AS3 - Yet another TypeError: Error #1009 Cannot acces

I am creating a "Space Invaders" game in AS3. Got everything working now, but keep ketting a #1009 error and i'm looking at it for quite a time now and i just don't see the problem. Some extra eyes could help out I think!
This is what the debugger says:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at testbestandkopie_fla::MainTimeline/winGame()[testbestandkopie_fla.MainTimeline::frame1:352]
at testbestandkopie_fla::MainTimeline/enemyHitTest()[testbestandkopie_fla.MainTimeline::frame1:338]
at testbestandkopie_fla::MainTimeline/onTick()[testbestandkopie_fla.MainTimeline::frame1:117]
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
Below I will paste the code that has to do with the error:
1: Creating the AS Linkage names:
//Sound FX-------------------------------------------------------------------------
var startFX:Sound = new startGameSound();
var laserFX:Sound = new laserSound();
var explosionFX:Sound = new explosionSound();
var musicFX:Sound = new backgroundMusic();
var loseFX:Sound = new endGameSound();
var winFX:Sound = new winGameSound();
var SfxTransform = new SoundTransform();
var myChannelMisc:SoundChannel = new SoundChannel();
var myChannelMusic:SoundChannel = new SoundChannel();
var myChannelWin:SoundChannel = new SoundChannel();
var myChannelLose:SoundChannel = new SoundChannel();
//---------------------------------------------------------------------------------
2: [Line 117] The AS line 117 is the highlighted one:
//Handlers Functions---------------------------------------------------------------
function onTick(e:TimerEvent) { //A continuous run of some functions below.
moveCharacter();
moveEnemyField();
playerCollisionDetectWall();
enemyCollisionDetectWall();
enemyCollisionDetectWallBottom();
moveLasers();
enemyHitTest(); <---- line 117
}
3: [Line 338] The function enemyHitTest(); where it starts the winGame(); function:
function enemyHitTest() {
//For each of the three enemys
for (var i:int = 0; i < enemyArray.length; i++) {
//the each of the six lasers
for (var j:int = 0; j < 6; j++) {
//don't consider lasers that aren't in play:
if (laserArray[j].y > SpelerMC.y) continue;
if (enemyArray[i].visible && enemyArray[i].hitTestObject(laserArray[j])) {
score += 10;
myChannelMisc = explosionFX.play();
SfxTransform.volume = 0.3;
myChannelMisc.soundTransform = SfxTransform;
scoreTxt.text = score.toString();
trace("Invader nummer " + i + " neergeschoten!");
enemyArray[i].visible = false;
//Now we remove the laser when hitting.
laserArray[j].x = j * 70 + 100;
laserArray[j].y = 895;
}
else if(score == 660) {
//If you reach a score of 660 (66 enemy's x 10 = 660) you win the game.
winGame(); <---- Line 338
}
}
}
}
4: [Line 352] Where the winGame(); function run's after getting 660 points at the enemyHit.
function winGame() {
winScreen.visible = true;
gameTimer.stop();
//Stop the music.
myChannelMusic.stop();
//Start the "You Win" music.
myChannelWin = winFX.play();
SfxTransform.volume = 0.02;
myChannelWin.soundTransform = SfxTransform; <---- line 352
}
So as you can see, it run's through these functions. I've already checked if something is wrong with my file in the Library, but the AS Linkage name is exactly the same as the var I defined above. Maybe a few extra eyes can see what's going wrong here, and explain me why..
Thanks in advance!
As per the livedocs :
winFX.play() method may return null if you have no sound card or if you run out of available sound channels. The maximum number of sound channels available at once is 32.
Check if either of the issues above is applicable to you....
As Mark said, the class winGameSound is the culprit here. The call winFX.play() returns a null, not a sound channel. So you can not apply a sound transform to the null object.
The only info one can currently get is that the class inherits Sound class & returns null with play() call.

Reference Shared Object AS3

I am trying to reference a shared object (one that saves data), but whenever I try to, I get a crash.
This code works fine:
var var1:Object = { value:1 };
var varRef:Object = var1;
if(var1.value == 1) {
varRef.value = 50;
}
trace(varRef.value); // outputs 50;
trace(var1.value); // outputs 50;
But when I try to use shared objects, it doesn't work.
import flash.net.SharedObject;
var iapso:SharedObject = SharedObject.getLocal("purchases");
var varRef:Object = iapso.data.testing;
varRef = 90
trace ("The shared value is " + iapso.data.testing);
trace ("This should mirror it" + varRef);
If you're able to figure out the issue, please post a fixed version.
Thanks.
You must come from a programming background where pointers can be dereferenced.
In this case, varRef is not varRef = &iapso. Setting its value does not change the value of iapso.data.testing;
Initially, you set varRef as a pointer to iapso.data.testing:
var varRef:Object = iapso.data.testing;
Then, you immediately change it to a constant value object literal 90:
varRef = 90;
This does not set the value of testing to 90 - this changes the value of varRef.
You could set varRef to iapso.data, then set testing as in:
var varRef:Object = iapso.data;
varRef.testing = 90;
Then, the following would produced expected results:
trace(iapso.data.testing); // 90
trace(varRef.testing); // 90
setting varRef will not update the value in iapso.data - numbers are copied, not referenced.
var bar:Object = { data:1 };
var foo:Object = bar.data;
trace(foo); //"1"
bar.data = 2;
trace(foo); //"1"
If you really want to use a reference, use data instead, eg:
import flash.net.SharedObject;
var iapso:SharedObject = SharedObject.getLocal("purchases");
var varRef:Object = iapso.data;
varRef.testing = 90
trace ("The shared value is " + iapso.data.testing);
trace ("This should mirror it" + varRef.testing);