Game project: Money!

I did a small update on the game-thing: the player is now able to col­lect money (or dia­monds, or burg­ers, or any­thing). These will be used in the in-game shops to, well, buy stuff.

One issue I had was that I wanted to make the coins col­lected per­sis­tent: for exam­ple, if you grab all the coins to get in stage 1, visit a cou­ple of other stages, then go back to stage 1, you won’t find any coin any­more – because you already picked all of them when you first vis­ited. If you need 500 coins (dia­monds, burger, etc.) to buy some­thing, going to the same level again and again won’t help.

At first, I was not too sure about how to imple­ment this fea­ture.
After a cou­ple of dis­cus­sions with a friend should I say, a patient one?), I set­tled for the fol­low­ing approach (which is not exactly what he rec­om­mended, but which kinda works for me):

I start with the BasicGame object, which allows to keep things stored between dif­fer­ent states. In the boot state, I cre­ated some­thing look­ing like this:

BasicGame = {  
  vis­it­edLevels: []
};

Every time I load a new level, I check if the vis­it­edLevels key is either empty, or matches some­thing exist­ing.
If it is empty of there is not match, I set a value alreadyVis­ited to false, and cre­ate a new key:

BasicGame.visitedLevels.push({
  lev­el­Name: ‘theLevel­Name’,
  coins: []
})

Now every time the player grabs a coin, I add its coor­di­nates in the coins array:

for (var i=0; i<BasicGame.visitedLevels.length; i++){
  if (BasicGame.visitedLevels[i].levelName == this.currentLevel) {
    BasicGame.visitedLevels[i].coins.push(
      {x: coin.cameraOffset.x, y:coin.cameraOffset.y}
    );
  }
}

(not sure if using cam­eraOff­set is the proper way, but that’s the only value that matched the one I grabbed from the tilemap).

After a cou­ple of coins col­lected, the BasicGame object starts to look like:

BasicGame = {
  vis­it­edLevels: [
    {
      lev­el­Name: ‘theLevel­Name’,
      coins: [
        {x: 2, y: 6},
        {x: 100, y: 82}
      ]
    }
  ]
};

Then when I cre­ate my level and add the coins, I check first if alreadyVis­ited is false.
If it is true, I com­pare each coin coor­di­nates with what I have stored in the BasicGame object for the cur­rent level. I only add the coin if there is no match.

cre­ate­Coins: func­tion() {
  this.coins = this.add.group();
  var coinArr = this.findObjectsByType(‘coin’, this.map, ‘object­sLayer’);
  var coin;
  coinArr.forEach(function(element) {
    if (this.alreadyVisited){
      var coin­WasTaken = false;
      for (var i=0; i<BasicGame.visitedLevels.length; i++) {
        if (BasicGame.visitedLevels[i].levelName == this.currentLevel) {
          for (var j=0; j<BasicGame.visitedLevels[i].coins.length; j++) {
            console.log(BasicGame.visitedLevels[i].coins[j]);
            if(BasicGame.visitedLevels[i].coins[j].x == element.x && BasicGame.visitedLevels[i].coins[j].y == element.y) {
              coin­WasTaken = true;
            }
          }
        }
      }
      if (!coin­WasTaken) {
        coin = new Coin(this.game, element.x, element.y, this.map);
        this.coins.add(coin);
      }
    } else {
      coin = new Coin(this.game, element.x, element.y, this.map);
      this.coins.add(coin);
    }
    //console.log(element);
  }, this);
}

It works, but I would be curi­ous to know if there are other solu­tions, or maybe a more “stan­dard” way to achieve the same thing. Com­ments & crit­ics welcome!

2 Comments

  1. Pied
    Posted August 19, 2015 at 6:15 am | Permalink

    I think a com­mon way would be to have a map from level to coins. When­ever a coin is con­sumed, you just remove it from the map. There­fore, you’ll never even try to dis­play it any­more. This map is then stored in your game state.
    If you can per­sist this map, it’s even bet­ter: you don’t need to have every­thing in mem­ory! (but peo­ple may cheat)

    P!

  2. Jérôme
    Posted August 19, 2015 at 4:45 pm | Permalink

    Yeah that’s basi­cally the oppo­site approach: instead of stor­ing only the dif­fer­ences, you store the orig­i­nal state. Might make the code for read­able, I won­der from a per­for­mance per­spec­tive?
    Didn’t think about the cheat­ing aspect – but that’s not some­thing I am too wor­ried about, at least for now :)

Post a Comment

Your email is never shared. Required fields are marked *

*
*