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?
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?
- No, that is not correct. Timers still run regardless. – Diodeus - James MacFarlane Commented Feb 28, 2013 at 21:16
- How are we suppose to help without your code? Are you using a for loop for the countdown instead of setTimeout? – Ruan Mendes Commented Feb 28, 2013 at 21:17
- "Playing the game" is not a synchronous, browser-freezing 3-minute-lasting script execution, is it? The timer will have a chance to fire during the event loop. – Bergi Commented Feb 28, 2013 at 21:26
- @Bergi It's an interactive game, it constantly changes images (once every 2 seconds) and requires the user to press keyboard buttons. – CODe Commented Feb 28, 2013 at 21:29
5 Answers
Reset to default 2You 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
Unless your game uses some sort of a busy loop, i.e., 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.
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 plex 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.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745338200a4623204.html
评论列表(0条)