Clickers are HTML elements that have been associated with a click event through the Game object! Only the Game() object comes with an addClicker(...) method.
Let's see, if we wanted to make our 'Earn Points' button clickable and actually earn us points, we can just do:
//add clickers
game.addClicker("#earn",function() {
game.attributes.Points+=2;
});
3b. How to use a clicker [Refer to the documentation for additional parameter]
Essentially, you provide the identifier/class/name of the element you want to make clickable, and give it a function to execute on click. We provided an
anonymous function function with our code that will henceforth always be executed whenever #earn is clicked.
Great, click-event handling taken care of. What about the other button?
The syntax for
addClicker stays the same, but the code inside our anonymous function will, obviously, be a bit more complex.
game.addClicker("#getSome", function() {
//this function also shows another way to access attributes
var p=game.getAttribute("Points");
var cost=10;
var increase=2;
if (p>=cost)
{
//we can buy
p-=cost;
game.setAttribute("Points",p);
var pps=game.getAttribute("PointsPerSecond");
pps+=increase;
game.setAttribute("PointsPerSecond",pps);
}
});
3b. Code to actually buy stuff - this also shows a different way to access attributes
Great, so we have our clickers in place! Let's put it all together!
<script>
//the init() function initializes or sets up our game
function init()
{
//create Game() instance
game=new Game();
//add attributes
game.addAttribute("Points",0).track("Points","#points", function(value) { return value.toFixed(0); });
game.addAttribute("PointsPerSecond",0,"#points_per_second");
//add clickers
game.addClicker("#earn",function() {
game.attributes.Points+=2;
});
game.addClicker("#getSome", function() {
//this function also shows another way to access attributes
var p=game.getAttribute("Points");
var cost=10;
var increase=2;
if (p>=cost)
{
//we can buy
p-=cost;
game.setAttribute("Points",p);
var pps=game.getAttribute("PointsPerSecond");
pps+=increase;
game.setAttribute("PointsPerSecond",pps);
}
});
//play
game.play(play);
}
</script>
3c. Our Init function
You'll notice I added an anonymous function to the track() method for the first attribute, Points. If you recall from the sub-section on trackers (
2c), this is an optional function that takes in one parameter, the value of the attribute being tracked, and returns the way it should be displayed. I have simply set it to return no decimals, only the integer itself, in case I decide to change cost from 2 to some other decimal value.
If you refresh your game and try playing it, you'll notice you can
earn points and
buy more 'Points Per Second'. However, nothing actually happens 'per second'. This is where our
play() function comes in handy.
//the play() function contains essential game code
function play()
{
//here we see another way to get/update attributes more quickly
var g=game.attributes;
g["Points"]+=g["PointsPerSecond"]/game.getFPS();
//divide by FPS because we have to take into account the Frames Per Second when adding anything per Second,
}
3c. the play() function - also demonstrating yet another way to access attributes
Fairly straightforward, right?
We're accessing the
Points attribute
directly and adding to it the
PointsPerSecond attribute, since it does make sense.
But wait, why are we dividing the points added per second by the game's FPS - the game's FPS is 1 by default, so it doesn't matter right?
Yes, in its current state - the FPS of the game is 1 and so the division is unnecessary. But what if you decide to set the FPS to 10, or 15, or 30?
Let's do the math to see what happens if we exclude the divided-by-game.getFPS() and the FPS is 10
Suppose the
PPS (points per second) is
2. The
play() loops runs
10 times (frames) per second.
Expected Behaviour: In
1 second, the
Points attribute should increase by 2.
Actual Behaviour: In
1 second, the
Points attribute increases by 20 per second, because 2 was added 10 times per second.
Hence, in such operations, make sure you factor in the FPS, whether it is 30 or 1 (to be safe). By dividing the FPS here, we are basically adding up 10 parts of 2 in the span of 1 second. 1/10th of 2 is 1/5. So by adding 1/5
ten times to the Points attribute, we get 2 in one second!
10-15 FPS is a good choice because it also updates the tracked variables quicker. Currently, clicking on either button doesn't update the
displayed corresponding attribute immediately - the trackers waits until the next loop iteration to update, so we would have to manually throw in a Javascript/HTML text manipulation in our click functions.
Increasing the FPS would alleviate this problem at this scale.