Posted on by

Maintaining the same code across multiple modules/screens might not seem so bad with just one or two levels, but what about when your game grows to twenty levels and you need to change a simple option on the pause screen? My guess is that you’d rather modify one file, rather than all twenty.

There are several different ways you can modularize functions that are common to many modules/screens, but I’m going to walk you through what I believe is the easiest method to implement as well as understand.

But before you continue with this tutorial, I highly recommend that you take a moment to gain an understanding of how to use external modules in Corona first.

Scenario

I’ll elaborate on the simple game scenario I described a moment ago. Let’s say we are creating a game with several levels, and the things common to each level are:

The main character (as well as the character’s associated functions).
Number that represent the game’s score.
Pause button and menu.

We’re not going to construct a complete game here, we’ll instead create a few sample functions to illustrate how you might apply the same logic to your actual project.

Game Functions

The first thing we’ll do is create a separate module called gamefunctions.lua, which we’ll use for functions that are common to all (or most) levels. Here’s what your gamefunctions.lua might look like:

As you can see from the code sample above, we have three separate functions for creating a character (and a jump method for the player), a score display (plus a method to change the score), and a pause button.

How, you can leverage the code above in as many levels as you want! Here’s the beginnings of an example level module:

You see, returning the player, score, and pause button from the respective functions stores an instance of the objects into the specified variables in level1.lua. You can also see how the methods and properties are accessed (lines 26 and 27).

Of course, these are very simplistic examples and don’t actually reflect a real game, but the point wasn’t to make an actual game right now, but to show you how you can write functions once, and leverage them across several different screens/modules.

Now, let’s say you want to add a “shoot” method to the player. Using this technique, you’ll only need to modify gamefunctions.lua and add code to the newPlayer function code block, and instantly any functions that call newPlayer() will have access to the new method! Simple as that.

Not Just for Games…

Although the example I provided had to do with creating game functions common to multiple levels, this concept can be applied to just about any app. Your “gamefunctions.lua” could be anything really, and serve to hold all the page creation/turning functions for your eBook app, or the functions for pulling data from a remote server in your business app—the possibilities are endless.

Just about every app can take advantage of this technique to not only access common functions across multiple screens/modules, but will also serve to help keep your code clean, organized, and easily maintained.


Posted by . Thanks for reading...

16 Responses to “Tutorial: Simple Modular Coding Technique”

  1. Daniel W

    When you pauseButton:removeSelf() in level1.lua, does this also remove the event listener attached to pauseButton?

    Reply
  2. Noah Atchison

    I don’t get how to “pause”. What would be the API code for suspending the hardware, like we can do in the simulator, to make a pause utility for our game?

    Reply
    • Jonathan Beebe

      The ‘pause’ method was really just an example, the point was to demonstrate how to separate common functions into external modules to help make your projects easier to maintain, and extend.

      Reply
  3. Jonathan Beebe

    @Daniel W: Yes, any event listeners that are NOT attached to Runtime will be removed upon calling removeSelf().

    Once again, listeners attached to the Runtime (e.g. via Runtime:addEventListener…) must be removed manually.

    Reply
  4. Steven K

    modules are awesome especially when you work with several people on one project but I’m always afraid of using it because you have to use global functions and variables when you use modules :(

    Reply
  5. Chang Kian Boon

    Always remember check on memory leaks when dealing with modules and global functions, as I found that after I have removed a Runtime enterFrame listener, the sub functions attached inside that Runtime function is not deleted. Have to nil out all the functions attached to Runtime listener after removing the listener. *I was using director class.

    Reply
  6. Jonathan Beebe

    @StevenK: You don’t really need to worry about how the functions are global in external modules, because whenever you use them, you normally localize the function in the module you are using before ever calling the function anyway. As long as the variables within the functions are local, you’ll be ok.

    Reply
  7. Tyler

    Being one of the few that comes from a Lua background instead of Actionscript, I tend to use a lot of libraries for Lua, such as the MiddleClass & MindState libraries – https://github.com/kikito/middleclass/wiki
    These were made to work with the LOVE engine (www.love2d.org), but they have served me equally as well while working in Corona.

    Reply
  8. don@loqheart.com

    @Tyler I do have an Actionscript background, and I’ve found MiddleClass to be the easiest implementation for classes around. I’m using it for my HSM framework.

    From my experience, all modules create globals even if you try to specify local. For instance the physics module.

    local physics = require(‘physics’) — is not local

    In another module physics will be accessible.

    I use a variation of this to unload modules: http://snippets.luacode.org/snippets/unrequire_121

    You can see the difference in application memory if you do the unrequire.

    Reply
  9. Claudemirton

    Could you clarify me about the variable scoreCount and how updating it change the text value of scoreDisplay object?

    Thanks in advance.

    Reply
  10. Jonathan Beebe

    @Claudemirton: The change() method was defined in gamefunctions.lua, and scoreDisplay is an instance of the display object that was created using the newScoreDisplay() function (also in gamefunctions.lua).

    Reply
  11. DavisD

    I am really almost giving up with corono for the issue of not being able to run any sample application in my android 2.3 honey comb cellphone. I tried to build a sample app but the problem is when i copy it to my cellphone it gives me an error which doesn’t allow the app from running. I would really like to be given assurance that everything will go smoothly on my cellphone before I will purchase corona.

    I am a PHP and VB programmer but a noob in corona. Please help.

    Reply
  12. Nicholas G

    A friend of mine builds fine for 2.2 and 2.3 android.

    You say “Before I will purchase corona” well, if you don’t have a license

    You can’t build for android or iphone, meaning you can’t “test” on your device.

    So until you buy a license, you won’t be able to do what you are saying.

    Hope that helps :)

    ng

    Reply
  13. carlos m. icaza

    @davisd – please move your question to the forum. More eyes will look at it and will try to get to the bottom of it.

    You should be able to install on Android devices even when running trial mode of Corona.

    .c

    Reply
  14. ES

    module(…, package.seeall) is missing above — gamefunctions.lua

    I’m looking at posts out of order and this sample confused me as it wasn’t using module

    Reply

Leave a Reply

  • (Will Not Be Published)