I am working on a sort of clicker game where the user is able to buy upgrades. One such upgrade involves the user earning a certain amount of in-game currency per second, in this case 0.1. Unfortunately if the user decides to buy more than one of this upgrade it appears to rise exponentially. I feel like this might be because the setInterval() function is stacking each time, so that the first time it is 0.1 then the next its 0.1 + 0.2 so 0.3, then 0.3 + 0.2 + 0.1 so 0.6 and so on.
upgradePerSec1.onclick = function() {
if (presents >= cost1) {
presents -= cost1;
upgrade1Amount += 1;
totalPresentsSpent += cost1;
cost1 = Math.ceil(cost1Base *= 1.03 ** upgrade1Amount);
perSec += 0.1;
displayScore.innerHTML = format(presents) + " Presents delivered.";
cost1Disp.innerHTML = "<hr>Cost: " + format(cost1);
title.innerHTML = format(presents) + " Presents";
perSecDisp.innerHTML = formatPerSec(perSec) + " presents /s";
totalPresentsSpentDisp.innerHTML = format(totalPresentsSpent) + " Total presents spent";
setInterval(increment1, 1000);
} else {
alert("You don't have enough presents! Still need: " + format(cost1 - presents));
}
}
function increment1() {
presents += perSec;
totalPresents += perSec;
displayScore.innerHTML = format(presents) + " Presents delivered.";
totalPresentsDisp.innerHTML = format(totalPresents) + " Total presents delivered";
title.innerHTML = format(presents) + " Presents";
}
Here is some clarification for this code:
upgradePerSec1
= HTML button elementcost1
= the cost of this upgradeperSec
= variable to store the amount of "presents" per seconddisplayScore
= an HTML label elementcost1Disp
= an HTML label elementtitle
= the browser tab titleformat()
= a function to format large numbers by adding in commastotalPresents
= the total presents without taking away costs (used for a statistics section)
I have tried replacing the perSec
variable with just the number(obviously did not work) I have tried making the timing also rise but could not get the correct timing. Ive also searched many places on the web and could not find any helpful results. I saw one on stack overlfow but it did not apply to me.
>Solution :
You’re right, the setInterval
calls are stacking. To fix the issue, you should make sure you only call setInterval()
once (e.g. by adding an if statement before that line checking if perSec === 0
).
e.g.
upgradePerSec1.onclick = function() {
if (presents >= cost1) {
presents -= cost1;
upgrade1Amount += 1;
totalPresentsSpent += cost1;
cost1 = Math.ceil(cost1Base *= 1.03 ** upgrade1Amount);
perSec += 0.1;
displayScore.innerHTML = format(presents) + " Presents delivered.";
cost1Disp.innerHTML = "<hr>Cost: " + format(cost1);
title.innerHTML = format(presents) + " Presents";
perSecDisp.innerHTML = formatPerSec(perSec) + " presents /s";
totalPresentsSpentDisp.innerHTML = format(totalPresentsSpent) + " Total presents spent";
if (perSec === 0) {
setInterval(increment1, 1000);
}
} else {
alert("You don't have enough presents! Still need: " + format(cost1 - presents));
}
}
function increment1() {
presents += perSec;
totalPresents += perSec;
displayScore.innerHTML = format(presents) + " Presents delivered.";
totalPresentsDisp.innerHTML = format(totalPresents) + " Total presents delivered";
title.innerHTML = format(presents) + " Presents";
}