[Updated August 3, 2020]
While the info below is good, I do have a Lock/Unlock Level library available for people who don’t want the hassle of coding it themselves.
Reading the forums I see the same questions come up again and again – which is fine, because everybody’s new at the beginning. But there are some questions that frustrate me because while the question is valid, the thinking behind the question is based on assumptions that make me think the person asking is heading down the wrong path.
For example, “How do I lock a Composer level so someone can’t play it ahead of the previous level?”
That’s a valid question, except that you don’t lock a Composer level, a Storyboard level, or any other kind of level.
Instead, you “set a flag” that determines whether a player can access that level or not.
If you walk into an office and want to talk to Tom you might look at an In-Out board to see if you can talk to him. If the peg is set to Out, you can’t talk to him. If the peg next to Mark is set to In, you can talk to him.
In a game it works the same way. You have an In-Out board, or maybe a Lock-Unlock board, and depending on where the peg is set, the player can access that level or not.
The lock isn’t a part of the Composer scene any more than an In-Out board is a part of Tom or Mark.
While you might wonder what the difference is, it’s one of simplicity. By attempting to make the lock a part of Composer, you’re complicating things more than you need to. And there are enough details with Composer handling that it doesn’t need any more complexities. 🙂
Like most everything else involving 2D game dev, Solar2D makes it easy to set this up, so let’s look at an example of how to separate the two, the level from the lock.
1 2 |
levelAccess = { [1]=true, [2]=false, [3]=false } currentLevel = 1 |
That code creates a table with three elements representing three levels. The first is set to true, meaning we can play that level. It also sets a variable showing which level we’re playing right now. To show the Select Level screen we’d do something like this (not complete code):
1 2 3 4 5 6 7 |
for x = 1, #levelAccess do if levelAccess[x] == true then print("Play Level " .. tostring(x) ) else print("Level " .. tostring(x) .. " Locked" ) end end |
Obviously, instead of putting in those print lines you’d either show a level button or a lock picture. And when the user chooses a level to play you’ll set the currentLevel variable to that level number.
As you can see, you don’t lock or unlock a level — you don’t even give the player access to a level if it’s locked, so you don’t need to “lock the level.”
After the player completes level one and you want to unlock level two, you’d do this (as part of the “cleanup” on level one):
1 |
levelAccess[currentLevel+1] = true |
Now when the player goes to the Select Level screen they’ll see two levels they can play (although in a real game you’d probably just send them on to that level).
What About Later Sessions
At this point if the user quits the app and comes back later, the levelAccess table will be reset to the default, with only level 1 unlocked. That means you’ll need to save the current table when you exit the program and load the table when you launch the program.
Since there are many ways to handle that (saving and loading a table) I’m not going to reinvent the wheel — I just wanted to bring that up since I know a lot of people wonder about that.
In general, when you launch the app you’ll load the table, or, if the table doesn’t exist, use the default. During gameplay you set the levels in the table that are playable to true, and when the app exits you save that table.
I subscribe to the philosophy that the most important thing is the player experience, so making it work is more important than making it work a certain way. However, the more simplicity you have in your code the faster you can write it, the easier you can make modifications later, and the better for reusing the same chunks of code in later projects.
Originally written for Corona SDK, now called Solar2D, but still just as awesome.
I was just playing around with this and found this to be much easier than most of the information from other sources. However, I cannot unlock the next level in the level selector for some reason. I created a level selector lua file and included levelAccess = { [1]=true, [2]=false, [3]=false }. I also included:
for x = 1, #levelAccess do
if levelAccess[x] == true then
print(“Play Level ” .. tostring(x) )
else
print(“Level ” .. tostring(x) .. ” Locked” )
end
end
So now, if I want to do the same for level 2, do I just repeat what I put above and change the x=1 to x=2?
Also, I put levelAccess[currentLevel+1] = true on my exit scene in the level1 lua file but when I beat level 2 and go back to the level selector menu, level 2 is still locked. I did put currentLevel = 1 in the enter scene in level 1 and currentLevel = 2 in the enter scene in level 2. Am I doing something wrong?