Home > Enterprise >  Why is this javascript function executing more times per second than it's supposed to
Why is this javascript function executing more times per second than it's supposed to

Time:01-06

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 element
  • cost1 = the cost of this upgrade
  • perSec = variable to store the amount of "presents" per second
  • displayScore = an HTML label element
  • cost1Disp = an HTML label element
  • title = the browser tab title
  • format() = a function to format large numbers by adding in commas
  • totalPresents = 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.

CodePudding user response:

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) {
    if (perSec === 0) {
      setInterval(increment1, 1000);
    }
    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";
  } 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";
}
  • Related