I'm working on a mobile game and need the game clock to pause when the game loses focus, for example when call comes in. I have everything working except that when the game gains focus again the time adjusts to as if it had been running the whole time. If someone is on a 3 minute call when they get back they should find the game time where it was.
Here is my code:
public function showTime(event:Event){
gameTime = getTimer()-gameStartTime;
timeDisplay.text = "Time: "+clockTime(gameTime);
}
public function clockTime(ms:int) {
var seconds:int = Math.floor(ms/1000);
var minutes:int = Math.floor(seconds/60);
seconds -= minutes*60;
var timeString:String = minutes+":"+String(seconds+100).substr(1,2);
return timeString;
}
public function onActivate(event:Event):void {
addEventListener(Event.ENTER_FRAME, showTime);
}
public function onDeactivate(event:Event):void {
removeEventListener(Event.ENTER_FRAME, showTime);
}
I've been Googling this for two da开发者_运维问答ys and am stuck. Could someone please point me in the right direction? Some sample code would be a benefit too since I'm pretty new to AS3. Thanks!
Rich
You can check out this Stopwatch tutorial that I wrote a while back:
http://www.popamihai.com/2010/10/flex/using-the-timer-class-in-flex-to-display-a-simple-stopwatch/
It is written with Flex Builder 3 but you could easily copy/paste the code. Example with view source enabled is also included
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle"
backgroundColor="white" viewSourceURL="srcview/index.html" creationComplete="init()">
<mx:Script>
<![CDATA[
import flash.utils.getTimer;
import flash.utils.Timer;
import flash.events.TimerEvent;
private const TIMER_INTERVAL:int = 50;
private var timerAtStart:Number = 0;
private var timerAtPause:Number = 0;
private var t:Timer;
private var d:Date;
[Bindable] private var sec:int = 0;
[Bindable] private var min:int = 0;
[Bindable] private var mls:int = 0;
private function init():void {
t = new Timer(TIMER_INTERVAL);
t.addEventListener( TimerEvent.TIMER, updateTimer );
}
private function updateTimer( evt:TimerEvent ):void{
d = new Date( getTimer() - timerAtStart + timerAtPause);
min = d.minutes;
sec = d.seconds;
mls = d.milliseconds;
}
private function startPauseTimer( event:MouseEvent ):void{
if ( event.target.label == "start" ) {
event.target.label = "pause";
timerAtStart = getTimer();
t.start();
} else {
event.target.label = "start";
timerAtPause = min * 60000 + sec * 1000 + mls;
t.stop();
}
}
]]>
</mx:Script>
<mx:Label text="{min + ' : ' + sec + ' : ' + mls}" fontSize="16" fontWeight="bold"/>
<mx:HBox>
<mx:Button label="start" click="startPauseTimer( event )"/>
</mx:HBox>
</mx:Application>
You're calculating your time based on the current time - gameStartTime
. You either need to take the delay into account (calculate the total time stopped by using getTimer()
in the onActivate()
and onDeactivate()
functions, then add that difference to gameStartTime
), or if you don't want to change gameStartTime
, then you calcuate your time based on delta time. Something like:
private var m_prevTime:int = 0;
public function startGame():void
{
// set the prevTime only when you start the game, otherwise you'll
// take into account all the time for flash to get going, your init,
// opening screens etc
this.m_prevTime = getTimer();
}
public function showTime(event:Event)
{
// get the difference in time
var currTime:int = getTimer();
gameTime += currTime - this.m_prevTime // currTime - prevTime = delta time
this.m_prevTime = currTime; // hold the current time
// display it
timeDisplay.text = "Time: "+clockTime(gameTime);
}
public function onActivate(event:Event):void
{
// we're reactivating, so make sure prev time is updated
this.m_prevTime = getTimer();
addEventListener(Event.ENTER_FRAME, showTime);
}
You'll miss out on a frame's time when coming back from the update, but it's not noticable (or you can subtract a frame's time in the onActivate()
function)
Instead of using getTimer(), you should create a timer object and add an event listener to "tick" to update the clock. You can even set it to tick once per second so you don't have to convert the MS.
public function onActivate(event:Event):void {
myTimer.start();
}
public function onDeactivate(event:Event):void {
myTimer.stop();
}
See the timer reference: http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/utils/Timer.html
精彩评论