2

I am trying to make a variable increase every second. What should I include inside the function autoClicker, so that the variable clicks increase by 1 every second? Also, if there are any more problems in the code, could you point them out to me? Sorry if this question seems basic, I am still quite new to JavaScript.

// The variable we are trying to increase
var clicks = 0;
var upgrade1 = 1;

function getClicks() {
  clicks += upgrade1;
  document.getElementById("clicks").innerHTML = clicks;
};

function buyAutoClicker() {
  if (clicks >= 50) {
    clicks -= 50
    autoClicker()
  } else {
    alert = "Sorry, you don't have enough clicks to buy this";
  }
}

// The function I will use to increase clicks
function autoClicker() {}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
Temmie308
  • 21
  • 2

4 Answers4

3

You could create an AutoClicker class that has a start, pause, ad update function. It will be in charge of managing the setInterval id.

Edit: I updated it to include upgrade buttons and the target can now be manually clicked.

const upgrades = [{
  cost: 50,
  rate: 2
}, {
  cost: 100,
  rate: 4
}];
  
const main = () => {
  const target = document.querySelector('.auto-clicker');
  const span = document.querySelector('.info > span');
  const btn = document.querySelector('.btn-toggle');
  const clicker = new AutoClicker(target, 1000, (clicks) => {
    span.textContent = clicks;
  }).start();

  initializeUpgrades(clicker, upgrades);

  btn.addEventListener('click', (e) => {
    e.target.textContent = clicker.isRunning() ? 'Start' : 'Pause';
    clicker.toggle();
  });
};

const initializeUpgrades = (clicker, upgrades) => {
  const upgradeContainer = document.querySelector('.upgrades');

  upgrades.forEach(upgrade => {
    const btn = document.createElement('button');
    btn.textContent = upgrade.cost;
    btn.value = upgrade.rate;
    btn.addEventListener('click', (e) => {
      let cost = parseInt(e.target.textContent, 10);
      let value = parseInt(e.target.value, 10);
      if (clicker.clicks >= cost) {
        clicker.clicks -= cost;
        clicker.step = value
      } else {
        console.log(`Cannot afford the ${value} click upgrade, it costs ${cost} clicks`);
      }
    });
    upgradeContainer.appendChild(btn);
  });
};

class AutoClicker {
  constructor(target, rate, callback) {
    if (typeof target === 'string') {
      target = document.querySelector(target);
    }
    this.target = target;
    this.rate = rate;
    this.callback = callback;
    
    this.init();
  }
  init() {
    this.step = 1;
    this.clicks = 0;
    this._loopId = null;
    
    this.target.addEventListener('click', (e) => {
      this.update();
    });
  }
  isRunning() {
    return this._loopId != null;
  }
  toggle() {
    this.isRunning() ? this.pause() : this.start();
  }
  update() {
    this.clicks += this.step;
    if (this.callback) {
      this.callback(this.clicks);
    }
  }
  start() {
    this.update(); // Update immediately
    this._loopId = setInterval(() => this.update(), this.rate);
    return this;
  }
  pause() {
    clearInterval(this._loopId);
    this._loopId = null;
    return this;
  }
}

main();
.wrapper {
  width: 10em;
  text-align: center;
  border: thin solid grey;
  padding: 0.5em;
}

.auto-clicker {
  width: 4em;
  height: 4em;
  background: #F00;
  border: none;
  border-radius: 2em;
}

.auto-clicker:focus {
  outline: none;
}

.auto-clicker:hover {
  background: #F44;
  cursor: pointer;
}

.info {
  margin: 1em 0;
}

.upgrades {
  display: inline-block;
}

.upgrades button {
  margin-right: 0.25em;
}
<div class="wrapper">
  <button class="auto-clicker"></button>
  <div class="info">Clicks: <span class="clicks"></span></div>
  <button class="btn-toggle">Pause</button>
  <div class="upgrades"></div>
</div>
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
1

// The variable we are trying to increase
var clicks = 0;
var upgrade1 = 1;

function getClicks() {
  clicks += upgrade1;
  document.getElementById("clicks").innerHTML = clicks;
};

function buyAutoClicker() {
  if (clicks >= 50) {
    clicks -= 50
    autoClicker()
  } else {
    alert = "Sorry, you don't have enough clicks to buy this";
  }
}

// The function I will use to increase clicks
setInterval(function(){ clicks++;console.log(clicks); }, 1000);
DCR
  • 14,737
  • 12
  • 52
  • 115
1

Use setInterval to run a function at a specified interval. This will run increaseClicks every 1000 milliseconds (every second):

function increaseClicks() {
    clicks++;
}

var interval = setInterval(increaseClicks, 1000);

Use clearInterval to stop running it:

clearInterval(interval);

You can omit var interval = if you don't want to use clearInterval:

setInterval(increaseClicks, 1000);
Dull Bananas
  • 892
  • 7
  • 29
0

There might be several things to improve this code

  • the use of textContent is preferable to innerHTML, it checks if there are no html tags in the text
  • then using inline functions like ()=>{} are more useful but in this program it does'nt make a difference, where you to use it in object oriented context you could use it several ways
  • you don't need document.getElementById, you could just use id. And finaly (this is just à random tip which has nothing to do with much of anything) you may consider branchless programming because ifs are expensive. Stackoverflow Branchless Programming Benefits

But anyways you should have fun :)

var clicks = 0;
var upgrade1 = 1;

function getClicks() {
  clk.textContent = (clicks += upgrade1);
};

function buyAutoClicker() {
  if (clicks >= 50) {
    clicks -= 50
    setInterval(()=>{getClicks();},1000);
  } else {
    alert("Sorry, you don't have enough clicks to buy this");
  }
}

clk.onclick=()=>{getClicks();};
b.onclick=()=>{buyAutoClicker();};
html,body{height:100%;width:100%;margin:0;}
p{height:50px;width:50px;background:red;}
<p id="clk"></p>
<p id="b"></p>
codeanjero
  • 674
  • 1
  • 6
  • 14