Arduboy Course - Part V: Level

date
Jun 16, 2024
type
KnowledgeBase
year
slug
arduboy-5
status
Published
tags
Arduino
C++
Microcontroller
summary
Let’s take what we have and make a whole level!

Making a whole Level

Just do the same thing many times?

We could do the same thing multiple times to get an entire level, but then we’d have many individual obstacles and would need to check for collisions with each and every one of them.
We could do the same thing multiple times to get an entire level, but then we’d have many individual obstacles and would need to check for collisions with each and every one of them.
Instead of making individual variables for all obstacles, we’ll use an array - essentially a list of obstacles.
Notice how the index of our array starts with 0, not 1. In programming all indices are usually zero-based!
Notice how the index of our array starts with 0, not 1. In programming all indices are usually zero-based!
 
Now what this allows us to do is loop through the array - for example when drawing the obstacles!
Simple Example:
notion imagenotion image
✅ Draws obstacles from an array
❎ It’s all happening in the main class

Level Class

✌️
Let’s create a new CLASS that will hold all our level-related data (most importantly all our obstacles)! And we’ll do this in a new file in our project…
  • In the Arduino IDE click onto the 3 dots () at the top right of the source code, then choose New Tab
  • This will create a new file, call it level.h
    • notion imagenotion image
notion imagenotion image
Let’s make a new class that will hold all the data for our level!
  • We’ll move our Obstacle struct into the new file level.h
  • Create the class Level
    • Create a public array for our obstacles
    • Create a public int to hold the number of obstacles that have been added: obstacleCount
    • Create a method to add an obstacle to the Level object: addObstacle - we’ll use this to set up our level
Note how obstacles[obstacleCount++] accesses the Obstacle at position obstacleCount and then immediately increases obstacleCount by 1! All in one! Like 🪄 magic…
Note how obstacles[obstacleCount++] accesses the Obstacle at position obstacleCount and then immediately increases obstacleCount by 1! All in one! Like 🪄 magic…
Back in the main file we can now include our new file via #include "level.h" - that will pull in our Obstacle struct and our Level class!
Why do we need a Level class again? 
It keeps our main file clean since a lot of level-related functionality can live in the levels.h file instead of our main file. Also note how it makes it really easy for us to have multiple levels - We can simply swap out the contents of our level variable!
Why do we need a Level class again? It keeps our main file clean since a lot of level-related functionality can live in the levels.h file instead of our main file. Also note how it makes it really easy for us to have multiple levels - We can simply swap out the contents of our level variable!

Move collision detection out of the main file

If all our obstacle-related stuff lives in level.h, then it makes a lot of sense to move the collision-checking in there as well!
  • Move checkCollision into Obstacle - that way we could also use an Obstacle just by itself without the need for a Level object
    • One version of checkCollision checks against values
    • Another version of checkCollision checks against an Entity
  • Make a checkCollision method in Level that takes an Entity as its argument and automatically checks for collision against all Obstacles in the Level
Now we can simplify the main file down to this:
Nice! Notice how it’s now super-easy to add multiple coins and multiple platforms! And most interactions basically handle themselves. All we need to do is set everything up, then call player.process and level.checkCollision in loop() and then draw all the things!
Nice! Notice how it’s now super-easy to add multiple coins and multiple platforms! And most interactions basically handle themselves. All we need to do is set everything up, then call player.process and level.checkCollision in loop() and then draw all the things!
notion imagenotion image

Level Design - Level Editor

It’s cumbersome to construct a level in source code, so I made a little ➡️ LEVEL EDITOR where you can lay out a level, then simply click the Export C++ button and generate the corresponding source code!
It’s cumbersome to construct a level in source code, so I made a little ➡️ LEVEL EDITOR where you can lay out a level, then simply click the Export C++ button and generate the corresponding source code!
Shortcut Keys
B - Add a box
DEL - Delete selected object
Other Features
  • It also saves the level in your browser’s localStorage, so you can work on it across sessions.
  • If you want to save the level or continue on a different PC you can export it as a JSON file for later re-import.
notion imagenotion image
 
✨ Now go, make a level! ✨
 

Leave a comment