JSFiddle - React, Tailwind, and code Playground
HTML
<h1>Widgets: <span id="widget-count">0</span> (<span id="cps">0</span> / s)</h1>
<button id="produce-widget">Produce Widget</button>
<h2>Store:</h2>
<div id="store-container"></div>
<h2>Coding exercises:</h2>
<ul>
<li>Change the starting costs and see how it affects the game</li>
<li>Add two more levels of widgeteers</li>
<li>Add stats near the top showing widgets per second and the number of widgeteers of each type</li>
<li>Add an upgrades section</li>
<li>Add save/load buttons that use localStorage.setItem() and localStorage.getItem()</li>
<li>Check the Bootstrap 3 checkbox in the upper left and change the <button> elements to use <div class="btn btn-primary"> instead</li>
</ul>
JavaScript
// Game is a global object. It is unique and can be called from wherever in the code.
var Game = {
interval: 10, // time between each tick (in ms)
decimals: 2, // Number of decimals displayed, 0 for just integers
currency: 0, // currency owned
// DOM elements
button: undefined,
count: undefined,
store: undefined,
cpsDisplay: undefined,
// This is the handle for the setInterval.
// It is good practice to keep it stored somewhere, if only to be able
// to stop it with window.clearInterval(Game.handle)
handle: undefined,
// The possible buildings will be stored in this array
buildings: [],
init: function(_buildings) {
var self = this;
// -- Cache DOM elements
// (traversing the DOM with jQuery is costly on large pages, so it is recommended
// to call static elements just once and store them for future use. Also makes for some
// more readable code)
this.button = $('#produce-widget');
this.count = $('#widget-count');
this.store = $('#store-container');
this.cpsDisplay = $('#cps');
// bind the click event
this.button.click(function() {
self._click(); // Note about 'self' : inside a jQuery click() function, 'this' will contain the element that has been clicked, in this
// case the "Produce widget" button. We use 'self' to still have access to our Game object inside the function.
});
// -- Initialize all buildings and store them in the buildings array
$.each(_buildings, function(i, _building) {
var newBuilding = Building(_building).init();
self.buildings.push(newBuilding);
});
// Launch the ticker
this.handle = window.setInterval(function() {
self._tick();
}, this.interval);
},
// called each time you click
_click: function() {
this.currency++;
},
// called at each tick
_tick: function() {
// Each building produces his currency, and then we check
// if we have enough to buy another (ie...