Home > Back-end >  Farm Clicker game - Gold's value is increasing more than necessary
Farm Clicker game - Gold's value is increasing more than necessary

Time:04-24

I'm trying to make a Farm Clicker game myself with Javascript. (In other words, as you click the Add Gold button, the user earns 1 gold and can obtain passive gold by buying some animals according to the number of gold he has.) But there is a problem with the program: If I save 50 gold and buy a goat, the gold suddenly increases more than necessary. The problem is most likely in the section that says setInterval, but I still couldn't find the exact solution.

HTML

<head>
  <title>Farm clicker</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div id="content"></div>
  <script src="script.js"></script>
</body>

JS

// global variables
const myContent = document.getElementById("content");
var gold=0;
let animals = {};
var goldToAdd = 0;
// global functions

function addGoldButton() {
  let myButton = document.createElement("button");
  myButton.id = "addButton";
  myButton.addEventListener("click", ()=>addGold(1)); // add one
  myButton.innerHTML = "Add Gold!";
  myContent.appendChild(myButton);
}



addGoldButton();
function addGold(goldToAdd) {
  console.trace();
  if (gold == 0) {
    gold = goldToAdd;
    let goldCounter = document.createElement("h2");
    goldCounter.id = "goldCounter";
    goldCounter.innerHTML = "Gold: "   gold;
    myContent.appendChild(goldCounter);
  } else
  {
    gold  = goldToAdd;
    document.getElementById("goldCounter").innerHTML = "Gold: "   gold;
  }
  // check for events on current gold level
  checkGold();
  goldToAdd=0;
}

function checkGold(){
  if (gold >= 50 && document.getElementById("goatBuyButton") == null) {
    let buttonBar = document.createElement("div");
    buttonBar.id = "buttonBar";
    let buyButton = document.createElement("button");
    buyButton.id = "goatBuyButton";
    buyButton.innerHTML = "Buy Goat (50g)";
    buyButton.addEventListener("click", ()=>buyAnimal("goat"));
    myContent.appendChild(buttonBar);
    buttonBar.appendChild(buyButton);
  }

  if (gold >= 90 && document.getElementById("pigBuyButton") == null) {
    let buttonBar = document.getElementById("buttonBar");
    let buyButton = document.createElement("button");
    buyButton.id = "pigBuyButton";
    buyButton.innerHTML = "Buy Pig (90g)";
    buyButton.addEventListener("click", ()=>buyAnimal("pig"));
    buttonBar.appendChild(buyButton);
  }

  if (gold >= 120 && document.getElementById("cowBuyButton") == null){
    buttonBar = document.getElementById("buttonBar");
    let buyButton = document.createElement("button");
    buyButton.id = "cowBuyButton";
    buyButton.innerHTML = "Buy Cow (120g)";
    buyButton.addEventListener("click", ()=>buyAnimal("cow"));

    buttonBar.appendChild(buyButton);
}

function buyAnimal(animal) {
  let itemBar = document.getElementById('itemBar');
  if (itemBar == null) {
    itemBar = document.createElement("div");
    itemBar.id = "itemBar";
    myContent.appendChild(itemBar);
  }

  switch (animal) {
    case "":
      //do something, don't and forget the break;
    case "goat":
      if (gold >= 50) {
        addGold(-50);
        if (animals.goats == null) {
          animals.goats = 1;
          let myElement = document.createElement("div");
          myElement.id = "goats";
          myElement.innerHTML = "Goat Quantity: "   animals.goats;
          itemBar.appendChild(myElement);
        } else {
          animals.goats  = 1;
          document.getElementById("goats").innerHTML = "Goat Quantity: "   animals.goats;
        }
      }
      break;
    case "pig":
      if (gold >= 90) {
        addGold(-90);
        if (animals.pigs == null) {
          animals.pigs = 1;
          let myElement = document.createElement("div");
          myElement.id = "pigs";
          myElement.innerHTML = "Pig Quantity: "   animals.pigs;
          itemBar.appendChild(myElement);
        } else {
          animals.pigs  = 1;
          document.getElementById("pigs").innerHTML = "Pig Quantity: "   animals.pigs;
        }
      }
      break;
    case "cow":
      if (gold >= 120) {
        addGold(-120);
        if (animals.cows == null) {
          animals.cows = 1;
          let myElement = document.createElement("div");
          myElement.id = "cows";
          myElement.innerHTML = "Cow Quantity: "   animals.cows;
          itemBar.appendChild(myElement);
        } else {
          animals.cows  = 1;
          document.getElementById("cows").innerHTML = "Cow Quantity: "   animals.cows;
        }
      }
      break;
    default:
      console.log("no animal found");
  }
}
function passiveGold() {

  if (animals.goats > 0) {
    goldToAdd  = animals.goats*5; //50=>5 10=>1
  }
  if (animals.pigs > 0) {
    goldToAdd  = animals.pigs*10; //90=>10  9=>1
  }
  if (animals.cows > 0) {
    goldToAdd  = animals.cows*15; //120=>15 8=>1
  }
  addGold(goldToAdd);
}
setInterval(passiveGold, 10000);
}

CodePudding user response:

There are two main issues with the gold incrementation here. There's a brace out of place leading to (I think) the setInterval be created several times (each time checkGold is called, in fact). Secondly, the goldToAdd amount is not zero at the start of passiveGold. I've also edited addGold so that two gold counters don't turn up when you hit 0 gold. Snippet below:

const myContent = document.getElementById("content");
var gold=0;
let animals = {};
var goldToAdd = 0;
// global functions

function addGoldButton() {
  let myButton = document.createElement("button");
  myButton.id = "addButton";
  myButton.addEventListener("click", ()=>addGold(1)); // add one
  myButton.innerHTML = "Add Gold!";
  myContent.appendChild(myButton);
}


addGoldButton();

function addGold(goldToAdd) {
  if(document.getElementById("goldCounter") == null) {
    let goldCounter = document.createElement("h2");
    goldCounter.id = "goldCounter";
    myContent.appendChild(goldCounter);
  }
  
  gold  = goldToAdd;
  document.getElementById("goldCounter").innerHTML = "Gold: "   gold;
  
  checkGold();
}

function checkGold(){
  if (gold >= 50 && document.getElementById("goatBuyButton") == null) {
    let buttonBar = document.createElement("div");
    buttonBar.id = "buttonBar";
    let buyButton = document.createElement("button");
    buyButton.id = "goatBuyButton";
    buyButton.innerHTML = "Buy Goat (50g)";
    buyButton.addEventListener("click", ()=>buyAnimal("goat"));
    myContent.appendChild(buttonBar);
    buttonBar.appendChild(buyButton);
  }

  if (gold >= 90 && document.getElementById("pigBuyButton") == null) {
    let buttonBar = document.getElementById("buttonBar");
    let buyButton = document.createElement("button");
    buyButton.id = "pigBuyButton";
    buyButton.innerHTML = "Buy Pig (90g)";
    buyButton.addEventListener("click", ()=>buyAnimal("pig"));
    buttonBar.appendChild(buyButton);
  }

  if (gold >= 120 && document.getElementById("cowBuyButton") == null){
    buttonBar = document.getElementById("buttonBar");
    let buyButton = document.createElement("button");
    buyButton.id = "cowBuyButton";
    buyButton.innerHTML = "Buy Cow (120g)";
    buyButton.addEventListener("click", ()=>buyAnimal("cow"));

    buttonBar.appendChild(buyButton);
  }
}

function buyAnimal(animal) {
  let itemBar = document.getElementById('itemBar');
  if (itemBar == null) {
    itemBar = document.createElement("div");
    itemBar.id = "itemBar";
    myContent.appendChild(itemBar);
  }

  switch (animal) {
    case "":
      //do something, don't and forget the break;
    case "goat":
      if (gold >= 50) {
        addGold(-50);
        if (animals.goats == null) {
          animals.goats = 1;
          let myElement = document.createElement("div");
          myElement.id = "goats";
          myElement.innerHTML = "Goat Quantity: "   animals.goats;
          itemBar.appendChild(myElement);
        } else {
          animals.goats  = 1;
          document.getElementById("goats").innerHTML = "Goat Quantity: "   animals.goats;
        }
      }
      break;
    case "pig":
      if (gold >= 90) {
        addGold(-90);
        if (animals.pigs == null) {
          animals.pigs = 1;
          let myElement = document.createElement("div");
          myElement.id = "pigs";
          myElement.innerHTML = "Pig Quantity: "   animals.pigs;
          itemBar.appendChild(myElement);
        } else {
          animals.pigs  = 1;
          document.getElementById("pigs").innerHTML = "Pig Quantity: "   animals.pigs;
        }
      }
      break;
    case "cow":
      if (gold >= 120) {
        addGold(-120);
        if (animals.cows == null) {
          animals.cows = 1;
          let myElement = document.createElement("div");
          myElement.id = "cows";
          myElement.innerHTML = "Cow Quantity: "   animals.cows;
          itemBar.appendChild(myElement);
        } else {
          animals.cows  = 1;
          document.getElementById("cows").innerHTML = "Cow Quantity: "   animals.cows;
        }
      }
      break;
    default:
      console.log("no animal found");
  }
}
function passiveGold() {
  goldToAdd = 0;
  if (animals.goats > 0) {
    goldToAdd  = animals.goats*5; //50=>5 10=>1
  }
  if (animals.pigs > 0) {
    goldToAdd  = animals.pigs*10; //90=>10  9=>1
  }
  if (animals.cows > 0) {
    goldToAdd  = animals.cows*15; //120=>15 8=>1
  }
  addGold(goldToAdd);
}
setInterval(passiveGold, 10000);
<div id="content"></div>

CodePudding user response:

So here the problem is in the passiveGold Function.It runs in to a infinite loop because after you are buying an animal the animal count is obviously greater than 0.So the if condition will be evaluated to true always inside the passiveGold function and as a result of that it runs into a infinite loop.

function passiveGold() {

  if (animals.goats > 0) {
    goldToAdd  = animals.goats*5; //50=>5 10=>1
    return;
  }
  if (animals.pigs > 0) {
    goldToAdd  = animals.pigs*10; //90=>10  9=>1
    return;
  }
  if (animals.cows > 0) {
    goldToAdd  = animals.cows*15; //120=>15 8=>1
    return;
  }
  addGold(goldToAdd);
  
}

So here i just did a small modification by adding return statements into every if condition code blocks.So that after executing once it will return to the main function.

// global variables
const myContent = document.getElementById("content");
var gold=0;
let animals = {};
var goldToAdd = 0;
// global functions

function addGoldButton() {
  let myButton = document.createElement("button");
  myButton.id = "addButton";
  myButton.addEventListener("click", ()=>addGold(1)); // add one
  myButton.innerHTML = "Add Gold!";
  myContent.appendChild(myButton);
}



addGoldButton();
function addGold(goldToAdd) {
  console.trace();
  if (gold == 0) {
    gold = goldToAdd;
    let goldCounter = document.createElement("h2");
    goldCounter.id = "goldCounter";
    goldCounter.innerHTML = "Gold: "   gold;
    myContent.appendChild(goldCounter);
  } else
  {
    gold  = goldToAdd;
    document.getElementById("goldCounter").innerHTML = "Gold: "   gold;
  }
  // check for events on current gold level
  checkGold();
  goldToAdd=0;
}

function checkGold(){
  if (gold >= 50 && document.getElementById("goatBuyButton") == null) {
    let buttonBar = document.createElement("div");
    buttonBar.id = "buttonBar";
    let buyButton = document.createElement("button");
    buyButton.id = "goatBuyButton";
    buyButton.innerHTML = "Buy Goat (50g)";
    buyButton.addEventListener("click", ()=>buyAnimal("goat"));
    myContent.appendChild(buttonBar);
    buttonBar.appendChild(buyButton);
  }

  if (gold >= 90 && document.getElementById("pigBuyButton") == null) {
    let buttonBar = document.getElementById("buttonBar");
    let buyButton = document.createElement("button");
    buyButton.id = "pigBuyButton";
    buyButton.innerHTML = "Buy Pig (90g)";
    buyButton.addEventListener("click", ()=>buyAnimal("pig"));
    buttonBar.appendChild(buyButton);
  }

  if (gold >= 120 && document.getElementById("cowBuyButton") == null){
    buttonBar = document.getElementById("buttonBar");
    let buyButton = document.createElement("button");
    buyButton.id = "cowBuyButton";
    buyButton.innerHTML = "Buy Cow (120g)";
    buyButton.addEventListener("click", ()=>buyAnimal("cow"));

    buttonBar.appendChild(buyButton);
}

function buyAnimal(animal) {
  let itemBar = document.getElementById('itemBar');
  if (itemBar == null) {
    itemBar = document.createElement("div");
    itemBar.id = "itemBar";
    myContent.appendChild(itemBar);
  }

  switch (animal) {
    case "":
      //do something, don't and forget the break;
    case "goat":
      if (gold >= 50) {
        addGold(-50);
        if (animals.goats == null) {
          animals.goats = 1;
          let myElement = document.createElement("div");
          myElement.id = "goats";
          myElement.innerHTML = "Goat Quantity: "   animals.goats;
          itemBar.appendChild(myElement);
        } else {
          animals.goats  = 1;
          document.getElementById("goats").innerHTML = "Goat Quantity: "   animals.goats;
        }
      }
      break;
    case "pig":
      if (gold >= 90) {
        addGold(-90);
        if (animals.pigs == null) {
          animals.pigs = 1;
          let myElement = document.createElement("div");
          myElement.id = "pigs";
          myElement.innerHTML = "Pig Quantity: "   animals.pigs;
          itemBar.appendChild(myElement);
        } else {
          animals.pigs  = 1;
          document.getElementById("pigs").innerHTML = "Pig Quantity: "   animals.pigs;
        }
      }
      break;
    case "cow":
      if (gold >= 120) {
        addGold(-120);
        if (animals.cows == null) {
          animals.cows = 1;
          let myElement = document.createElement("div");
          myElement.id = "cows";
          myElement.innerHTML = "Cow Quantity: "   animals.cows;
          itemBar.appendChild(myElement);
        } else {
          animals.cows  = 1;
          document.getElementById("cows").innerHTML = "Cow Quantity: "   animals.cows;
        }
      }
      break;
    default:
      console.log("no animal found");
  }
}
function passiveGold() {

  if (animals.goats > 0) {
    goldToAdd  = animals.goats*5; //50=>5 10=>1
    return;
  }
  if (animals.pigs > 0) {
    goldToAdd  = animals.pigs*10; //90=>10  9=>1
    return;
  }
  if (animals.cows > 0) {
    goldToAdd  = animals.cows*15; //120=>15 8=>1
    return;
  }
  addGold(goldToAdd);
  
}
setInterval(passiveGold, 10000);
}
<head>
  <title>Farm clicker</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div id="content"></div>
  <script src="script.js"></script>
</body>

Hope I solved your problem.And if you need anything to be clarified let me know.

CodePudding user response:

I've refactored your code and broke it down and remade it. i've made the logic simpler and more like an actual game loop demo

<head>
  <title>Farm clicker</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div id="content"></div>
</body>
// global state
let game_state = {
    gold: 50,
  animals: {
    goats: 0,
    pigs: 0,
    cows: 0
  },
}

// global variables
const content = document.getElementById("content");
let passiveGoldInterval = null;

// helper functions
function addGold(value){
    game_state.gold  = value;
  updateUI();
}

function buyAnimal(animal){
    switch(animal){
      case 'goat':
          if(game_state.gold >= 50){
                    addGold(-50);
                game_state.animals.goats  ;
          }
          break;
      case 'pig':
          if(game_state.gold >= 90){
                    addGold(-90);
                game_state.animals.pigs  ;
          }
          break;
      case 'cow':
          if(game_state.gold >= 120){
                    addGold(-120);
                game_state.animals.cows  ;
          }
          break;
        default: // do nothing
  }
  updateUI();
}

// background function
function passiveGold(){    
        addGold(game_state.animals.goats * 5); // add gold for goats
        addGold(game_state.animals.pigs * 10); // add gold for pigs
        addGold(game_state.animals.cows * 15); // add gold for cows
}

// game state management (init)
function init(){  
  passiveGoldInterval = setInterval(passiveGold, 10000); // calss this function every 10 seconds
  updateUI();
}

function updateUI(){

    if (!(document.getElementById("addButton"))) {
    let myButton = document.createElement("button");
    myButton.id = "addButton";
    myButton.addEventListener("click", ()=>addGold(1)); // add one
    myButton.innerHTML = "Add Gold!";
    content.appendChild(myButton);
  }
  
    if (!(document.getElementById("goldCounter"))) {
    let goldCounter = document.createElement("h2");
    goldCounter.id = "goldCounter";
    goldCounter.innerHTML = "Gold: "   game_state.gold;
    content.appendChild(goldCounter);
  } else
  {
    document.getElementById("goldCounter").innerHTML = "Gold: "   game_state.gold;
  }
  
  let itemBar = document.getElementById('itemBar');
  if (itemBar == null) {
    itemBar = document.createElement("div");
    itemBar.id = "itemBar";
    content.appendChild(itemBar);
  }
  
  // animals (display counts)
  if (game_state.animals.goats >= 1 && !(document.getElementById("goats"))) {
    let myElement1 = document.createElement("div");
    myElement1.id = "goats";
    myElement1.innerHTML = "Goat Quantity: "   game_state.animals.goats;
    document.getElementById('itemBar').appendChild(myElement1);
  } else if(document.getElementById("goats")) {
    document.getElementById("goats").innerHTML = "Goat Quantity: "   game_state.animals.goats;
  }
  
  if (game_state.animals.pigs >= 1 && !(document.getElementById("pigs"))) {
    let myElement2 = document.createElement("div");
    myElement2.id = "pigs";
    myElement2.innerHTML = "Pig Quantity: "   game_state.animals.pigs;
    document.getElementById('itemBar').appendChild(myElement2);
  } else if(document.getElementById("pigs")) {
    document.getElementById("pigs").innerHTML = "Pig Quantity: "   game_state.animals.pigs;
  }
  
  if (game_state.animals.cows >= 1 && !(document.getElementById("cows"))) {
    let myElement3 = document.createElement("div");
    myElement3.id = "cows";
    myElement3.innerHTML = "Cow Quantity: "   game_state.animals.cows;
    document.getElementById('itemBar').appendChild(myElement3);
  } else if(document.getElementById("cows")) {
    document.getElementById("cows").innerHTML = "Cow Quantity: "   game_state.animals.cows;
  }
  
  // display buttons if match
  // button container
    if(!(document.getElementById("buttonBar"))){
        let buttonBar = document.createElement("div");
        buttonBar.id = "buttonBar";
        content.appendChild(buttonBar);
    }


    // goats buy
    if(game_state.gold >= 50){
        if(!(document.getElementById("goatBuyButton"))){
            let buyButton = document.createElement("button");
            buyButton.id = "goatBuyButton";
            buyButton.innerHTML = "Buy Goat (50g)";
            buyButton.addEventListener("click", () => buyAnimal("goat"));
                content.appendChild(buyButton);
        }
    } else {
        if(document.getElementById("goatBuyButton")){
            document.getElementById("goatBuyButton").remove();
        }
    }
    
    // pigs buy
    if(game_state.gold >= 90){
        if(!(document.getElementById("pigBuyButton"))){
            let buyButton = document.createElement("button");
            buyButton.id = "pigBuyButton";
            buyButton.innerHTML = "Buy Pig (90g)";
            buyButton.addEventListener("click", () => buyAnimal("pig"));
                content.appendChild(buyButton);
        }
    } else {
        if(document.getElementById("pigBuyButton")){
            document.getElementById("pigBuyButton").remove();
        }
    }

    // cows buy
    if(game_state.gold >= 120){
        if(!(document.getElementById("cowBuyButton"))){
            let buyButton = document.createElement("button");
            buyButton.id = "cowBuyButton";
            buyButton.innerHTML = "Buy Pig (90g)";
            buyButton.addEventListener("click", () => buyAnimal("cow"));
                content.appendChild(buyButton);
        }
    } else {
        if(document.getElementById("cowBuyButton")){
            document.getElementById("cowBuyButton").remove();
        }
    }
}

init();
  • Related