首先,您可以在JS Fiddle中找到我的代码示例,也可以在问题下方找到。
我正在开发一个个人培训网络应用程序,基本上你可以玩游戏,然后你可以按照随机顺序完成一系列任务。该程序创建sessionTasks
数组,其中放入tasks
数组的随机顺序任务,以符合五分钟限制。现在,tasks
数组只是我用四个任务创建的数组,以及用于测试的相应时间。
我遇到的问题如下:当你点击任务以便你可以继续前进到下一个任务时,下次你玩秒时会更快。我发现复制的方式是:
现在秒应该更快地移动。如果没有,重复你刚刚做的。这是不规则的,但通常在第二次尝试时就会这样做。
我不能为我的生活理解为什么它会像这样。我想也许是创造了更多使用#taskTimer
运行的计时器,但这对我没有意义。 Timer
函数有问题吗?我的代码出了什么问题?
mainMenu();
var totalSessionTasks, taskIterator, selectedTimeInSecs = 300;
var taskTimer = new Timer("#taskTimer", nextTask);
var globalTimer = new Timer("#globalTimer", function() {
});
var tasks = [
["First task", 0, 30],
["Second task", 0, 15],
["Third task", 0, 10],
["Fourth task", 3, 0]
];
var sessionTasks = [
]
function setUpSession() {
sessionTasks = []
if (tasks.length != 0) {
var sessionTasksSeconds = 0; //the seconds of the session being filled
var sessionTasksSecondsToFill = selectedTimeInSecs; //seconds left in the session to fill
var newTaskSeconds = 0; //seconds of the next task being added to the session
var sessionFull = false;
console.log('Session Empty');
while (sessionFull === false) {
var areThereAnyTaskThatFitInTheSession =
tasks.some(function(item) {
return ((item[1] * 60 + item[2]) <= sessionTasksSecondsToFill) && (item != sessionTasks[sessionTasks.length - 1]);
});
console.log(areThereAnyTaskThatFitInTheSession);
if (areThereAnyTaskThatFitInTheSession) {
do {
var randTaskNum = Math.floor(Math.random() * tasks.length);
} while (((tasks[randTaskNum][1] * 60 + tasks[randTaskNum][2]) > sessionTasksSecondsToFill) || (tasks[randTaskNum] == sessionTasks[sessionTasks.length - 1]))
sessionTasks.push(tasks[randTaskNum]);
newTaskSeconds = (tasks[randTaskNum][1]) * 60 + tasks[randTaskNum][2];
sessionTasksSecondsToFill -= newTaskSeconds;
sessionTasksSeconds += newTaskSeconds;
console.log(tasks[randTaskNum][0] + ": " + newTaskSeconds + "s");
console.log(sessionTasksSeconds)
} else if (sessionTasks.length == 0) {
note("All your tasks are too big for a game of " + selectedTimeInSecs / 60 + " minutes!");
break;
} else {
console.log('Session full');
sessionFull = true;
taskIterator = -1;
totalSessionTasks = sessionTasks.length;
console.log(totalSessionTasks);
globalTimer.set(0, sessionTasksSeconds);
nextTask();
globalTimer.run();
taskTimer.run();
}
}
} else {
note("You don't have have any tasks in your playlists!");
}
}
function nextTask() {
if (taskIterator + 1 < totalSessionTasks) {
taskIterator++;
$("#taskText").text(sessionTasks[taskIterator][0]);
globalTimer.subtract(0, taskTimer.getTotalTimeInSeconds())
taskTimer.set(sessionTasks[taskIterator][1], sessionTasks[taskIterator][2]);
$("#taskCounter").text(taskIterator + 1 + " of " + totalSessionTasks + " tasks");
} else {
mainMenu();
taskTimer.stop();
globalTimer.stop();
note("Thanks for playing!");
}
}
//timer object function
function Timer(element, callback) {
var ac, minutes, seconds, finalTimeInSeconds, displayMinutes, displaySeconds, interval = 1000,
self = this,
timeLeftToNextSecond = 1000;
this.running = false;
this.set = function(inputMinutes, inputSeconds) {
finalTimeInSeconds = inputMinutes * 60 + inputSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;
this.print();
}
this.add = function(inputMinutes, inputSeconds) {
finalTimeInSeconds += inputMinutes * 60 + inputSeconds;
finalTimeInSeconds = (finalTimeInSeconds < 0) ? 0 : finalTimeInSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;
this.print();
}
this.subtract = function(inputMinutes, inputSeconds) {
finalTimeInSeconds -= inputMinutes * 60 + inputSeconds;
if (finalTimeInSeconds <= 0) {
callback()
}
finalTimeInSeconds = (finalTimeInSeconds < 0) ? 0 : finalTimeInSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;
this.print();
}
this.reset = function() {
this.set(0, 0);
}
this.print = function() {
displayMinutes = (minutes.toString().length == 1) ? "0" + minutes : minutes; //ternary operator: adds a zero to the beggining
displaySeconds = (seconds.toString().length == 1) ? "0" + seconds : seconds; //of the number if it has only one caracter.
$(element).text(displayMinutes + ":" + displaySeconds);
}
this.run = function() {
if (this.running == false) {
this.running = true;
var _f = function() {
secondStarted = new Date;
self.subtract(0, 1);
interval = 1000;
}
ac = setInterval(_f, interval);
}
}
this.stop = function() {
if (this.running == true) {
this.running = false;
console.log(this + "(" + element + ") was stopped");
stopped = new Date;
interval = 1000 - (stopped - secondStarted);
clearInterval(ac);
}
}
this.getTotalTimeInSeconds = function() {
return finalTimeInSeconds;
}
this.reset();
}
function note(string) {
alert(string);
}
function mainMenu() {
//EMPTY BODY
$("body").empty();
$("body").append(
//BUTTONS
"<div id='playButton' class='mainButton'><div class='buttonText mainButtonText'>PLAY</div></div>"
);
//BINDS
$("#playButton").bind("click", function(){
playMain();
setUpSession();
});
}
function playMain() {
//EMPTY BODY
$("body").empty();
$("body").append(
//TASK TEXT
"<p class='text' id='taskText'>Lorem ipsum dolor sit amet.</p>",
//TIMERS
"<div id='taskTimerWrap'><p class='text timer' id='taskTimer'>00:00</p><p class='text' id='taskTimerText'>Task Time</p></div>",
"<div id='globalTimerWrap'><p class='text timer' id='globalTimer'>00:00</p><p class='text' id='globalTimerText'>Global Time</p></div>",
//TASK COUNTER
"<div class='text' id='taskCounter'>0/0 tasks completed</div>"
);
//BINDS
$("#taskText").bind("click", nextTask);
}
&#13;
#taskText {
text-align: center;
display: table;
vertical-align: middle;
height: auto;
width: 100%;
top: 50px;
bottom: 0;
left: 0;
right: 0;
position: absolute;
margin: auto;
font-size: 65px;
cursor: pointer;
}
#taskTimerWrap {
text-align: center;
top: 0;
right: 0;
left: 170px;
margin: 5px;
position: absolute;
-webkit-transition: all 0.5s ease;
}
.timer {
font-size: 64px;
margin: 0;
line-height: 0.88;
}
#taskTimerText {
font-size: 34.4px;
margin: 0;
line-height: 0.65;
}
#globalTimerWrap {
text-align: center;
top: 0;
left: 0;
right: 170px;
margin: 5px;
position: absolute;
}
#globalTimerText {
font-size: 28.5px;
margin: 0;
line-height: 0.78;
transform: scale(1, 1.2);
}
#taskCounter {
text-align: center;
bottom: 0;
right: 0;
left: 0;
width: auto;
position: absolute;
font-size: 30px;
color: #98D8D9;
-webkit-transition: all 0.5s ease;
}
#taskCounter:hover {
color: #F1F2F0
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
答案 0 :(得分:2)
在Timer.stop()
中,您可以更改用于下次运行的时间间隔。更改_f()
中的时间间隔变量并不会更改setInterval()
使用的时间间隔。
在这种情况下,您必须使用setTimeout()
代替:
function Timer(element, callback) {
var ac, minutes, seconds, finalTimeInSeconds, displayMinutes, displaySeconds, timeout = 1000,
self = this,
timeLeftToNextSecond = 1000;
this.running = false;
/* ... */
this.run = function() {
if (this.running == false) {
this.running = true;
var _f = function() {
secondStarted = new Date;
self.subtract(0, 1);
ac = setTimeout(_f, 1000);
}
ac = setTimeout(_f, timeout);
}
}
this.stop = function() {
if (this.running == true) {
this.running = false;
console.log(this + "(" + element + ") was stopped");
stopped = new Date;
timeout = 1000 - (stopped - secondStarted);
clearTimeout(ac);
}
}
/* ... */
}
答案 1 :(得分:1)
以下是jsfiddle
中的更新问题出在interval
Timer
上
此行在Timer.stop()
:
interval = 1000 - (stopped - secondStarted);
如果您想缩短时间间隔,可以添加play_count
属性:
...
//timer object function
function Timer(element, callback) {
var ac, minutes, seconds, finalTimeInSeconds, displayMinutes, displaySeconds, interval = 1000,
self = this,
timeLeftToNextSecond = 1000;
this.running = false;
play_count = 0; // play count property
...
this.run = function() {
if (this.running == false) {
this.running = true;
var _f = function() {
secondStarted = new Date;
self.subtract(0, 1);
interval = Math.max(1000 - play_count * 100, 500); // ** <-- shorten time interval
}
ac = setInterval(_f, interval);
}
}
this.stop = function() {
if (this.running == true) {
this.running = false;
console.log(this + "(" + element + ") was stopped");
// stopped = new Date;
// interval = 1000 - (stopped - secondStarted);
play_count++;
clearInterval(ac);
}
}
this.getTotalTimeInSeconds = function() {
return finalTimeInSeconds;
}
this.reset();
}
...
答案 2 :(得分:1)
正如我所看到的,您正在尝试从间隔回调函数中设置变量interval
的值。
var _f = function() {
secondStarted = new Date;
self.subtract(0, 1);
//interval = 1000; REMOVE THIS LINE
}
interval = 1000; //ADD IT HERE
ac = setInterval(_f, interval);
实际上执行setInterval
时,interval
的值不是 1000 。它尚未由_f
更新,因为该函数将在setInterval()
执行后运行。一旦使用现有值setInterval()
调用interval
,稍后更改它对创建的间隔没有影响,因为setInterval()
函数已经设置了创建的间隔的延迟时间。由于此行,interval
的值会从其初始值 1000 更改:
interval = 1000 - (stopped - secondStarted); //I'm not sure what you are trying to do with this, possibly removing this line will also fix your problem.)
这是JS Fiddle。
mainMenu();
var totalSessionTasks, taskIterator, selectedTimeInSecs = 300;
var taskTimer = new Timer("#taskTimer", nextTask);
var globalTimer = new Timer("#globalTimer", function() {
});
var tasks = [
["First task", 0, 30],
["Second task", 0, 15],
["Third task", 0, 10],
["Fourth task", 3, 0]
];
var sessionTasks = [
]
function setUpSession() {
sessionTasks = []
if (tasks.length != 0) {
var sessionTasksSeconds = 0; //the seconds of the session being filled
var sessionTasksSecondsToFill = selectedTimeInSecs; //seconds left in the session to fill
var newTaskSeconds = 0; //seconds of the next task being added to the session
var sessionFull = false;
console.log('Session Empty');
while (sessionFull === false) {
var areThereAnyTaskThatFitInTheSession =
tasks.some(function(item) {
return ((item[1] * 60 + item[2]) <= sessionTasksSecondsToFill) && (item != sessionTasks[sessionTasks.length - 1]);
});
console.log(areThereAnyTaskThatFitInTheSession);
if (areThereAnyTaskThatFitInTheSession) {
do {
var randTaskNum = Math.floor(Math.random() * tasks.length);
} while (((tasks[randTaskNum][1] * 60 + tasks[randTaskNum][2]) > sessionTasksSecondsToFill) || (tasks[randTaskNum] == sessionTasks[sessionTasks.length - 1]))
sessionTasks.push(tasks[randTaskNum]);
newTaskSeconds = (tasks[randTaskNum][1]) * 60 + tasks[randTaskNum][2];
sessionTasksSecondsToFill -= newTaskSeconds;
sessionTasksSeconds += newTaskSeconds;
console.log(tasks[randTaskNum][0] + ": " + newTaskSeconds + "s");
console.log(sessionTasksSeconds)
} else if (sessionTasks.length == 0) {
note("All your tasks are too big for a game of " + selectedTimeInSecs / 60 + " minutes!");
break;
} else {
console.log('Session full');
sessionFull = true;
taskIterator = -1;
totalSessionTasks = sessionTasks.length;
console.log(totalSessionTasks);
globalTimer.set(0, sessionTasksSeconds);
nextTask();
globalTimer.run();
taskTimer.run();
}
}
} else {
note("You don't have have any tasks in your playlists!");
}
}
function nextTask() {
if (taskIterator + 1 < totalSessionTasks) {
taskIterator++;
$("#taskText").text(sessionTasks[taskIterator][0]);
globalTimer.subtract(0, taskTimer.getTotalTimeInSeconds())
taskTimer.set(sessionTasks[taskIterator][1], sessionTasks[taskIterator][2]);
$("#taskCounter").text(taskIterator + 1 + " of " + totalSessionTasks + " tasks");
} else {
mainMenu();
taskTimer.stop();
globalTimer.stop();
note("Thanks for playing!");
}
}
//timer object function
function Timer(element, callback) {
var ac, minutes, seconds, finalTimeInSeconds, displayMinutes, displaySeconds, interval = 1000,
self = this,
timeLeftToNextSecond = 1000;
this.running = false;
this.set = function(inputMinutes, inputSeconds) {
finalTimeInSeconds = inputMinutes * 60 + inputSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;
this.print();
}
this.add = function(inputMinutes, inputSeconds) {
finalTimeInSeconds += inputMinutes * 60 + inputSeconds;
finalTimeInSeconds = (finalTimeInSeconds < 0) ? 0 : finalTimeInSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;
this.print();
}
this.subtract = function(inputMinutes, inputSeconds) {
finalTimeInSeconds -= inputMinutes * 60 + inputSeconds;
if (finalTimeInSeconds <= 0) {
callback()
}
finalTimeInSeconds = (finalTimeInSeconds < 0) ? 0 : finalTimeInSeconds;
minutes = (Math.floor(finalTimeInSeconds / 60));
seconds = finalTimeInSeconds % 60;
this.print();
}
this.reset = function() {
this.set(0, 0);
}
this.print = function() {
displayMinutes = (minutes.toString().length == 1) ? "0" + minutes : minutes; //ternary operator: adds a zero to the beggining
displaySeconds = (seconds.toString().length == 1) ? "0" + seconds : seconds; //of the number if it has only one caracter.
$(element).text(displayMinutes + ":" + displaySeconds);
}
this.run = function() {
if (this.running == false) {
this.running = true;
var _f = function() {
secondStarted = new Date;
self.subtract(0, 1);
//interval = 1000; REMOVE THIS LINE
}
interval = 1000; //ADD IT HERE
ac = setInterval(_f, interval);
}
}
this.stop = function() {
if (this.running == true) {
this.running = false;
console.log(this + "(" + element + ") was stopped");
stopped = new Date;
interval = 1000 - (stopped - secondStarted);
clearInterval(ac);
}
}
this.getTotalTimeInSeconds = function() {
return finalTimeInSeconds;
}
this.reset();
}
function note(string) {
alert(string);
}
function mainMenu() {
//EMPTY BODY
$("body").empty();
$("body").append(
//BUTTONS
"<div id='playButton' class='mainButton'><div class='buttonText mainButtonText'>PLAY</div></div>"
);
//BINDS
$("#playButton").bind("click", function(){
playMain();
setUpSession();
});
}
function playMain() {
//EMPTY BODY
$("body").empty();
$("body").append(
//TASK TEXT
"<p class='text' id='taskText'>Lorem ipsum dolor sit amet.</p>",
//TIMERS
"<div id='taskTimerWrap'><p class='text timer' id='taskTimer'>00:00</p><p class='text' id='taskTimerText'>Task Time</p></div>",
"<div id='globalTimerWrap'><p class='text timer' id='globalTimer'>00:00</p><p class='text' id='globalTimerText'>Global Time</p></div>",
//TASK COUNTER
"<div class='text' id='taskCounter'>0/0 tasks completed</div>"
);
//BINDS
$("#taskText").bind("click", nextTask);
}
#taskText {
text-align: center;
display: table;
vertical-align: middle;
height: auto;
width: 100%;
top: 50px;
bottom: 0;
left: 0;
right: 0;
position: absolute;
margin: auto;
font-size: 65px;
cursor: pointer;
}
#taskTimerWrap {
text-align: center;
top: 0;
right: 0;
left: 170px;
margin: 5px;
position: absolute;
-webkit-transition: all 0.5s ease;
}
.timer {
font-size: 64px;
margin: 0;
line-height: 0.88;
}
#taskTimerText {
font-size: 34.4px;
margin: 0;
line-height: 0.65;
}
#globalTimerWrap {
text-align: center;
top: 0;
left: 0;
right: 170px;
margin: 5px;
position: absolute;
}
#globalTimerText {
font-size: 28.5px;
margin: 0;
line-height: 0.78;
transform: scale(1, 1.2);
}
#taskCounter {
text-align: center;
bottom: 0;
right: 0;
left: 0;
width: auto;
position: absolute;
font-size: 30px;
color: #98D8D9;
-webkit-transition: all 0.5s ease;
}
#taskCounter:hover {
color: #F1F2F0
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>