I'm modifying a Javascript game and need to add a countdown timer (from 3:00 minutes to 0 seconds) at the top of the game board. I have both the game and timer written, the timer will start when the user clicks the "start" button for the game. (ie the game is timed to end after 3 minutes)
My issue is that, since JavaScript is not multi-threaded, my game countdown timer will not be allowed to run (tick) while a user is concurrently playing my game. Is that correct?
It just seemed to me that there would be some way to get this to work, outside of using the new multi-threading JavaScript libraries.
Here's my timer:
<script type="text/javascript">
// set minutes
var mins = 3;
// calculate the seconds (don't change this! unless time progresses at a different speed for you...)
var secs = mins * 60;
function countdown() {
setTimeout('Decrement()',1000);
}
function Decrement() {
if (document.getElementById) {
minutes = document.getElementById("minutes");
seconds = document.getElementById("seconds");
// if less than a minute remaining
if (seconds < 59) {
seconds.value = secs;
} else {
minutes.value = getminutes();
seconds.value = getseconds();
}
secs--;
setTimeout('Decrement()',1000);
}
}
function getminutes() {
// minutes is seconds divided by 60, rounded down
mins = Math.floor(secs / 60);
return mins;
}
function getseconds() {
// take mins remaining (as seconds) away from total seconds remaining
return secs-Math.round(mins *60);
}
</script>
<script>
countdown();
</script>
<div id="timer">
<input id="minutes" value="3" type="text" style="width: 14px; border: none; background-color:none; font-size: 16px; font-weight: bold;">:<input id="seconds" value="00" type="text" style="width: 26px; border: none; background-color:none; font-size: 16px; font-weight: bold;"> remaining
</div>
Here's the portion of my game that kicks everything off:
<script>
$(function(){
$("#button-start").click(game.start);
});
</script>
How do I have the game.start
method run as well as the countdown()
method from my timer? Everytime I try to run both of the methods when "start" is clicked, the JavaScript doesn't run at all. Nothing works and it freezes up, I assume from two methods trying to run at once?
Unless your game uses some sort of a busy loop, ie, something like this:
while (1) {
// process next event
}
… then you shouldn't need to worry about it. Your JavaScript engine will automatically interleave user events with timer events, so the timer shouldn't get starved.
You should just use setTimeout
, then it won't block
var initialTime = new Date();
function updateTimer() {
if (new Date() - initialTime > (1000 * 1000 * 60 * 3) ) {
document.getElementById('clock').innerHTML = formatTime();
setTimeout(updateTimer, 1000);
}
}
updateTimer();
Just don't use a busy loop
one way:
var S_LEFT = 180;
function myTicker(){
console.log('tick');
S_LEFT -= 1;
if(S_LEFT === 0) doSomething();
$('#seconds').html(S_LEFT);
};
$('#start').on('click', function(){
window.setInterval(myTicker, 1000);
});
@Juan Mendes's way using setTimeout and no Jquery:
var S_LEFT = 180;
function tick(){
console.log('tick');
S_LEFT -= 1;
if(S_LEFT === 0){
alert('Boom');
} else {
document.body.innerHTML = S_LEFT;
window.setTimeout(tick, 1000);
}
};
//document.addEventListener('DOMContentLoaded',tick,false);
tick();
I was using setTimeout('Decrement()',1000);
when I should have been using setTimeout(Decrement,1000);
Removing the single quotes and parenthesis after "Decrement" solved my problem.
All of these answers seem way too complex for me.
Why not simply get a timestamp in seconds upon first starting the timer using
var beginTimestamp = Math.floor(Date.now() / 1000)
Then make your end
var endTimestamp = beginTimestamp + (3*60)
Then on update, get the number of seconds remaining with
var numSecondsRemaining = endTimestamp - Math.floor(Date.now()/1000)
and finally
if(numSecondsRemaining <= 0) { /* end game */ }
To format, just do
var date = new Date(numSecondsRemaining*1000);
var minutes = "0" + date.getMinutes();
var seconds = "0" + date.getSeconds();
var formattedTime = minutes.substr(-2) + ':' + seconds.substr(-2);
This approach isn't affected by any funkiness that setTimeout might be prone to. It's also much smaller, and requires basically no math.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.