I just put together a basic game framework to show novice programmers how to organize your code in a modular, object-oriented way. You can download the project from here (I’d like to submit it to Code Exchange but that seems to be down at the moment):
http://www.box.net/shared/uz5beg19h8
Now this is just one approach to doing OOP in Lua; most people would build classes in Lua using metatables, but that approach isn’t quite as flexible (eg. you can’t do multiple inheritance that way.) I originally got the idea for building the code in this way from this thread:
http://developer.anscamobile.com/forum/2010/12/12/finding-objects-parent
–
Anyway, here’s an explanation touching on many features being demonstrated:
First off, a novice programmer might be wondering what’s the advantage to splitting up the code into a dozen different files like this. Well, one advantage is that it enables you to write shared functions in one place and simply tell other parts to use that code. A good example is all the different levels of your game. Rather than copy-pasting the game logic in each level, you simply link them all to the same shared code. Then later when you make adjustments to the code, you can make your adjustments in one place instead of having to repeat the changes in a dozen different places.
It’s gets even better because you can build up a chain of modules linking to other modules, what’s called “inheritance.” I strongly suggest looking up that term, but for a great example observe in my code how both Menus and Levels are types of Scenes. Level1 is in turn a type of Level; because a Level is a type of Scene, level1.lua automatically gets code from both level.lua and scene.lua in a chain.
Frankly a newcomer could get nothing else from this example framework because they find it confusing, but this notion of modules inheriting from other modules is very very useful.
–
Going through the modules one by one…
Starting in main.lua we see a bunch of require() statements for other modules. Note that not every module is directly required by main, because all of these required modules also themselves require other modules. main.lua also has functions for switching scenes by calling the new() function in various modules, commented out code for checking memory, and finally at the very bottom everything is set in motion by starting up the main menu.
In menu.lua we see a bunch of buttons being placed around the screen. The buttons use functions passed to the menu from main, and those functions slide out the current scene and start a new one. The two most interesting lines to look at are lines 7 and 8:
local self = display.newGroup()
Scene.decorate(self)
That first line shows how every “scene” in Corona can simply be a diplay group that everything else is inserted into. That second line is how all of the code from the Scene module is linked to the Menu.
In scene.lua not much is going on right now. The few methods in there are simply to transition your scenes onto and off the screen. This is just a placeholder that you could fill in later with more functionality shared by all scenes, like loading screens or background music.
level1.lua shows the inheritance chain described earlier. We have the screen transitions shared by all scenes, plus we also have code shared by all levels but not by all scenes. Specifically, all levels have walls surrounding the screen and that’s what setup_walls() does. We also use the following line to attach code from yet another module to a bunch of entities in the level:
Hopper.decorate(self.entities[i])
level2.lua is pretty much the same thing as level1, except instead of making the entities into Hoppers they are made into Floaters.
level3.lua demonstrates multiple inheritance by making the entities have properties of both Hoppers and Floaters. Again, I can’t think of any way to do this with metatables, but it’s pretty simple to do this using decorators to add new functions to existing objects.
Both hopper.lua and floater.lua are similar except, well, one has code to hop up when the users taps the screen and the other has code to float around randomly. Notice the line “if self.bodyType == nil then” that’s used to make sure the physics body is only added once when both decorators are used (ie. multiple inheritance.)
–
So there you have it. Hopefully others find this educational. Again, even if everything else in this example framework confuses you, the notion of modules inheriting from other modules is very very useful. [import]uid: 12108 topic_id: 4760 reply_id: 304760[/import]
The sample above just meant to illustrate that FoobarSprite has all its stuff in a single contained place without having to know much about the outside world, this just makes it convenient for me to maintain. (“FoobarSprite” could be a bee, a bullet, a card, a maze wall with physics, a collectible diamond which explodes, a worm, etc.)