Level complete detection

It's all well and good having three levels, but without a mechanism to move between them they are useless. We are going to add a check to see if the player has finished a level, if they have then increment the level counter and load the next level in the array. We only need to do the check at the end of every move; to do so every frame would be redundant.

We'll write the following method first and then explain it:

// If this method returns true then we have finished the level
boolhaveFinishedLevel () {
  // Initialise the counter for how many crates are on goal 
  // tiles
  int cratesOnGoalTiles = 0;
  // Loop through all the rows in the current level
  for (int i = 0; i< levels[currentLevel].Length; i++) {
    // Get the tile ID for the column and pass it the switch 
    // statement
    for (int j = 0; j < levels[currentLevel][i].Length; j++) {
      switch (levels[currentLevel][i][j]) {
        case 5:
        // Do we have a match for a crate on goal 
        // tile ID? If so increment the counter
        cratesOnGoalTiles++;
        break;
        default:
        break;
      }
    }
  }
  
  // Check if the cratesOnGoalTiles variable is the same as the
  // amountOfCrates we set when building the level
  if (amountOfCrates == cratesOnGoalTiles) {
    return true;
  } else {
    return false;
  }
}

In the BuildLevel method, whenever we instantiate crate, we increment the amountOfCrates variable. We can use this variable to check if the amount of crates on goal tiles is the same as the amountOfCrates variable, if it is then we know we have finished the current level. The for loops iterate through the current level's rows and columns, and we know that 5 in the array is a crate on a goal tile. The method returns a Boolean based on whether we have finished the level or not. Now let's add the call to the method. The logical place would be inside the MovePlayer method, so go ahead and add a call to the method just after the pCol += tCol; statement.

As the method returns true or false, we're going to use it in an if statement, as shown in the following code:

// Check if we have finished the level
if (haveFinishedLevel()) {
  Debug.Log("Finished");
}

The Debug.Log method will do for now, let's check if it's working. The solution for level one is on YouTube at http://www.youtube.com/watch?v=K5SMwAJrQM8&hd=1. Click on the play icon at the top-middle of the Unity screen and copy the sequence of moves in the video (or solve it yourself), when all the crates are on the goal tiles you'll see Finished in the Console panel.

Moving to the next level

Assuming everything went correctly, you should have seen the Finished text appear. Next is to load a new level which is probably going to be easier than you think. We already have all the code to build a level and add the character in our current scene. Rather than elaborately tear it down and unload the current assets, we can simply increment the currentLevel counter and then reload the scene; our existing code will take care of the rest. Replace the Debug.Log method with the following code:

// Check if we have finished the level
if (haveFinishedLevel()) {
  
  currentLevel++;
  if (currentLevel == levels.Length) {
    currentLevel = 0;
  }
  PlayerPrefs.SetInt("currentLevel", currentLevel);
  
  Invoke("LoadNextLevel", 1.0f);
} 

Here, we are checking if we have finished the level with the haveFinishedlevel method, and then incrementing the currentLevel counter. The next check makes sure that it doesn't go over the amount of levels we actually have by comparing it to the Length of the levels array, if it does go over, we set it back to 0 to loop the level order. We then store the level in the PlayerPrefs object, so you can resume from that point after quitting the game. The last line is the Invoke method, as we don't want to load the new level at the exact moment, we finish placing the last crate. We can invoke a method after a delay. Here, the method to Invoke is named LoadNextLevel and the delay is 1.0f, which means one second. Let's create the LoadLevel method:

Void LoadNextlevel () {
  Application.LoadLevel("GameScreen");
}

As you've seen previously, Application.LoadLevel just loads a new scene, and because we have set out method to use the currentLevel variable, we can simply reload our scene to render the next level.

Restarting our level

Sometimes things just don't go your way. In Sokoban, you can get yourself into a situation where it is impossible to complete the level. As this is the case, then we need the ability to restart the game. Let's map it to the Y button on the Ouya controller. Add the following code to the bottom of your Update method:

// Should we restart the current level?
if (OuyaInput.GetButtonDown(OuyaButton.Y, playerNumber)) {
  Application.LoadLevel("GameScreen");
}

Give your game a test on the Ouya, and when in the main game, click on the Y button. You should reset back to the start position.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.83.96