CakeEater 6: Multiple Levels

Planning
Step 1
You may have noticed by now that it is impossible to complete this level and eat all the cake...
Temp1539300492 Temp1539300641 Temp1539300579
Planning
Step 2
The first thing we will add in this lesson is to let the player choose their starting location

Starting here makes the level possible:

Temp1539300715
Step 3
In the setup() function of your index.js, start with cakeEater equal to null
Temp1539300918
Check Your Work
Step 4
If we run it right now we'll get an error
Temp1539301171

If you look at the console the error looks like this:

Temp1539301193
Planning
Step 5
The error is happening here, where we call update on "null"
Temp1539301303
Step 6
We can use this if-statement to make sure we HAVE a cakeEater before we call its update method
Temp1539301420
Planning
Step 7
If there IS NOT a cakeEater on the screen, we should have the program allow the user to place one on a Tile

Let's make a function named placeEater() and start by making it highlight potential Tiles

Step 8
We'll add an ELSE statement to say if there is not a cakeEater call "placeEater"
Temp1539306180

The placeEater does not exist yet so let's make one in the next step

Step 9
We'll do this function in two parts

The First Part will calculate the x and y position of the selection window

Temp1539306627

The Second Part will draw a white selection box

Check Your Work
Step 10
Now we have a selection window but it doesn't snap to Tiles like we need it to
Step 11
We can round the mouseX and mouseY to the nearest multiple of tilesize using modulo
Temp1539308155

Here is a quick explanation if you are curious where this comes from:

mouseX % tilesize returns the remainder of mouseX / tilesize.

So for example if mouseX is at 54, we would want to set x to 50.

mouseX % tilesize is equal to 4 because:
54 % 50 = 4

So then is

mouseX - mouseX % tilesize
= 54 - (54 % 4) 
= 54 - 4 
= 50
Check Your Work
Step 12
You should now see the selector snapping to each Tile
Planning
Step 13
Ideally, if the payer mouses over a Wall tile or any place that is not "free", our cursor will not display a selector
Temp1539382977

We can use Tile.placeFree() to check if a given Tile is free to occupy.

But we need a column and row number to use it...

Step 14
Add variables for the column and row number
Temp1539383284

We can calculate these numbers by taking the x and y coordinates of the selector and dividing them by tilesize.

Example:
if x = 500
then x / tilesize == 10
so x is the 10th column

Challenge
Step 15
Use Tile.placeFree in the condition of an if-statement so that we only draw the selector if the selected Tile is free
Temp1539383700
  • A free Tile is one that is not a Wall, a Crumb, or out of bounds.

  • Tile.placeFree() takes a column number and a row number and returns true or false if the Tile is free or not

  • You just obtained the column and row numbers in the last step...

Check Your Work
Step 16
Make sure the selector only appears on free Tiles
Planning
Step 17
Lastly we'd like to place a 'new CakeEater' at the selector's location when the mouse is pressed

For this we're going to need to edit our Input.js file so that we can detect mouse input

Step 18
Just like we have a keyPressed and keyReleased, add a mousePressed and mouseReleased function to Input.js
Temp1539384233
Step 19
We can use mouseButton instead of keyCode
Temp1539384490

mouseButton returns "left", "right", or "middle"

I like to change these to "mouseleft" and "mouseright" by adding 'mouse' to them

Temp1539384538
Step 20
If the selector is being drawn, add that if the user clicks we create a new CakeEater
Temp1539385014

We add this new CakeEater to the cakeEater variable

Check Your Work
Step 21
Because of this code in our draw loop, we should be able to place and then move our CakeEater
Temp1539385268
Planning
Step 22
Next we'll add the ability to reset the game upon pressing the 'R' button

These three lines of code are the pieces we need to set up the game

Temp1539386236

We need:

  • an empty tiles array
  • to call Tile.createGrid()
  • to set the cakeEater variable to null
Challenge
Step 23
Make the game reset if the player presses the 'R' key

You should call a function named reset if the cakeEater exists and the player presses 'r'

Hints:

  • Use register to check if 'r' is pressed
  • the keyCode for 'r' is 82 which you could get with 'r'.charCodeAt(0)

Make a reset function which:

  • set tiles to an empty array
  • set cakeEater to null
  • uses Tile.createGrid to restart the level
Planning
Step 24
Next we will make the player advance to the next level after eating all of the cake

Each level will be stored in an array named levels

Temp1539397594
Step 25
Make a new file named "Levels.js"
Temp1539387876

Remember to include this script in index.html

Step 26
Move this level variable from index.js to Levels.js
Temp1539387936
Step 27
Edit this variable so that it becomes and array of objects

Change the name to levels

Temp1539388290

Right now we only have one level object

Check Your Work
Step 28
This will break your game for a couple steps by the way
Temp1539388591

Renaming level to levels means we cannot call createGrid(level)

Step 29
Add a second level object into the levels array
Temp1539388468

You may design your own level or you can copy and paste mine for now:

  {
      size: [5, 5],
      tiles: [
        0, 0, 0, 0, 0,
        0, 1, 0, 0, 0,
        0, 1, 1, 1, 0,
        0, 0, 0, 1, 0,
        0, 0, 0, 0, 0
      ]
  },
Step 30
Now in index.js try passing createGrid levels[0]
Temp1539388711

This should be displaying the first level once again:

Temp1539388742
Check Your Work
Step 31
If you change the array index to "1" you should see the second level
Temp1539389294
Step 32
Add a variable at the top of index.js named "levelNum" and start it at 0
var levelNum = 0;
Step 33
Now, whenever you call Tile.createGrid you'll want to pass it levels[levelNum]
Tile.createGrid(levels[levelNum]);

If levelNum is 0, this will create level 0
If levelNum is 1, this will create level 1

Planning
Step 34
So if the player eats all of the cake, we'll need to increase levelNum by 1 and then call "reset"
Temp1539397728
Step 35
Create a function named "checkComplete" which will constantly check to see if all of the cake has been eaten
function checkComplete() {


}

Call this function only if a cakeEater exists

Temp1539395229
Planning
Step 36
The plan for this will be as follows

We'll start with a list of all of the Tiles in our game: tiles

Temp1539394956

Then we'll filter this list with .filter to remove any Tiles that are not Cake Tiles

Temp1539395066

If there are no Tiles left in the list, then we know that there is no more cake to eat and thus the level has been completed!

Temp1539395140
Step 37
Make a variable for the "uneaten" tiles
Temp1539395351
Step 38
Add a filtered version of the Tiles array that only allows for Tiles whose location is considered "free"
Temp1539397278

If a tile is a Wall or a Crumb its column and row will not be "free" and thus it will not pass the filter

If a tile is free, we know it is an uneaten cake tile, so it will pass through the filter

Step 39
If the list of uneaten tiles is empty we know there are no cake Tiles
Temp1539396492

In here we can increase the level number and call reset()

Step 40
Increase levelNum by 1 using the "++" operator, then call reset()
Temp1539396865
Check Your Work
Step 41
Eating all of the cake should now take the player to the next level!
Planning
Step 42
Keep adding levels and challenge your friends to play them. Can you make a level that stumps your friends?
Temp1539397882
CakeEater 6: Multiple Levels Info

Account

MVCode Clubs

Created By

Newprofile jamie

Course:

CakeEater

Access Level

premium

For Teachers and Schools

Teach coding to your students with MVCode Teach

MVCode offers an integrated product designed to teach coding to students.

Learn more about MVCode Teach