Do you like my tutorials?

Then consider supporting me on Ko-fi

Talking about Farm Heroes Saga game, Game development and Javascript.

Are you ready for the next step of the creation of a game like Farm Heroes Saga? In first step I showed you the basic concepts of the game, now it’s time to start coding something real.

CREATION OF THE GAME FIELD

I told you we have a constant called FIELDSIZE which determines the side of the game field. We also know we are going to use a one-dimensional array because it’s easier to code in any language/prototype, and finally we have another constant called TILETYPES which stores the amount of different tile types we have in the game.

So the basic algorithm would say: “create a FIELDSIZE*FIELDSIZE array and fill it with random integer values between 1 and TILETYPES” and guess what… it would work! Too bad in most cases you will get a starting array already filled with some matches already done: it’s very likely to have three or more items with the same tile type.

Do you want an example?

Let’s take this very very basic script, made with JavaScript:

var FIELDSIZE = 8;
var TILETYPES = 8;
var gameArray = new Array(FIELDSIZE*FIELDSIZE);

for(i=0;i<FIELDSIZE*FIELDSIZE;i++){
     gameArray[i]=Math.ceil(Math.random()*TILETYPES);
}

console.log(gameArray);

If you execute it with Google Chrome you will have a console output like this one:

[2, 6, 3, 2, 6, 4, 2, 6, 5, 2, 2, 2, 5, 3, 7, 6, 6, 4, 2, 4, 5, 2, 8, 6, 5, 1, 5, 3, 8, 5, 5, 6, 4, 4, 8, 4, 2, 2, 3, 1, 7, 4, 3, 4, 2, 2, 5, 6, 6, 1, 2, 7, 2, 7, 5, 7, 4, 2, 6, 6, 1, 8, 2, 5] 

You can clearly see items at indices 9, 10 and 11 have the same value, that is they form a match and we don’t want the player to start a level with a free match.

Also, I would like you to see there aren’t constants in JavaScript, so I used variables.

CREATION OF THE PERFECT GAME FIELD

The perfect game field is a game field filled with random values which do not form any free match. So our algorithm will change from “”create a FIELDSIZE*FIELDSIZE array and fill it with random integer values between 1 and TILETYPES” to “create a FIELDSIZE*FIELDSIZE array and fill it with random integer values between 1 and TILETYPES without free matches“.

That’s where things get complicated. To prevent matches during the creation of the game field, we have to be able to detect a match. Now it’s time to create the set of functions we discussed in first step, let’s make a recap:

rowNumber(i) – given a tile with array index i, will return the number of the row
colNumber(i) – basically works in the same way, operating on columns
isHorizontalMatch(i) – will say if a tile with array index i is part of an horizontal match
isVerticalMatch(i) – will say if a tile with array index i is part of a vertical match

This set of functions can be written in JavaScript this way:

function rowNumber(i){
     return Math.floor(i/FIELDSIZE);
}

function colNumber(i){
     return i%FIELDSIZE;
}

function isHorizontalMatch(i){
     return colNumber(i)>=2 && gameArray[i]==gameArray[i-1] && gameArray[i] == gameArray[i-2] && rowNumber(i)==rowNumber(i-2);
}

function isVerticalMatch(i){
     return rowNumber(i)>=2 && gameArray[i]==gameArray[i-FIELDSIZE] && gameArray[i] == gameArray[i-2*FIELDSIZE];
}

We already discussed about the logic behind these functions in first step but I would like to have a look at isHorizontalMatch function in the final AND condition where I specify both the i-th and the (i-2)th elements must be on the same row.

If I don’t specify this condition, since we have a one-dimensional array, it could happen we have two equal items in the last two position of a row, and an equal item in the first position of the next row, because the array is wrapping. Look at this picture:

Although the three highlighted carrots are basically next to each other, it’s not a valid match because they aren’t on the same row. This cannot happen when working on columns.

This way to create the perfect game field we have, for each item, to keep generating random values until it does not form a match, here it is the JavaScript example:

var FIELDSIZE = 8;
var TILETYPES = 8;
var gameArray = new Array(FIELDSIZE*FIELDSIZE);

for(i=0;i<FIELDSIZE*FIELDSIZE;i++){
     do{
          gameArray[i]=Math.ceil(Math.random()*TILETYPES);
     }while (isHorizontalMatch(i) || isVerticalMatch(i));
} 

console.log(gameArray);

function rowNumber(i){
     return Math.floor(i/FIELDSIZE);
}

function colNumber(i){
     return i%FIELDSIZE;
}

function isHorizontalMatch(i){
     return colNumber(i)>=2 && gameArray[i] == gameArray[i-1] && gameArray[i] == gameArray[i-2] && rowNumber(i) == rowNumber(i-2);
}

function isVerticalMatch(i){
     return rowNumber(i)>=2 && gameArray[i] == gameArray[i-FIELDSIZE] && gameArray[i] == gameArray[i-2*FIELDSIZE];
}

And this time the resulting array will represent a perfect game field. That was quite easy with JavaScript, but with some frameworks will require some more work, but we’ll dive into it next time, when we will place the gems on the stage.

Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.