Seeing many flash developers praising Lua-based SDKs like Corona and Gideros that allow us to create mobile games quickly, I couldn’t help trying them myself.
First thing I did was read up some Lua tutorials. The language seems pretty easy to grasp — everything is a table which looks like associative array or a Dictionary in AS3. Good. Until I got to the point where I want to apply/emulate OOP or write code in modular fashion. This is where things become confusing because code examples from Corona and Gideros show you how to shove everything in one big main.lua
file. To add even more confusion, different Lua OOP examples show you how to emulate OOP in different ways. And there are things called metatable and metamethods.
After an hour reading the docs and wiki and doing some experiments. I found that it’s really not that hard. Here’s an example of inheritance in one big file.
------------------- -- Car table/class ------------------- Car = {} Car.__index = Car --constructor function Car.new(brand,price) local instance = { _brand = brand, _price = price } -- set Car as prototype for the new instance setmetatable(instance, Car) return instance end -- method definitions function Car:getBrand() return self._brand; end function Car:getPrice() return self._price; end function Car:getInfo() print("Brand",self:getBrand(),"price:",self:getPrice()) end ------------------- -- SUV ------------------- SUV = {}; -- constructor SUV.__index = SUV function SUV.new(brand,price,is4WD) local instance = { _is4WD = is4WD, _price = price, _brand = brand, } -- set SUV as prototype for instance setmetatable(instance,SUV) return instance end -- set up inheritance by making Car as prototype for SUV. Now SUV can access & override Car's methods setmetatable(SUV,{__index = Car}) -- instance method function SUV:get4WD() return self._is4WD; end -- override function SUV:getInfo() print("SUV Brand",self:getBrand(),", price:",self:getPrice(),", 4WD",self:get4WD()) end ------------------- -- main program ------------------- local c = Car.new("Honda",100) c:getInfo(); local suv = SUV.new("Suzuki",150,true) -- call inherited method print(suv:getBrand()) -- call the overridden method print(suv:getInfo())
If you compile and run the program, you should see this in the console:
Brand Honda price: 100 Suzuki SUV Brand Suzuki, price: 150, 4WD true
BTW, if you’re on Mac, you should try a cool app called Code Runner. You can do quick experiments without complicated project setup. Just type your code and click run.
So, how do you separate SUV
and Car
from main.lua
and put them in different .lua files in a package? Easy.
- Create a directory for your package just like what you always do in AS3, mine is
car
. - Then move
Car
andSUV
definitions frommain.lua
and put them inSUV.lua
andCar.lua
respectively. - Add
return Car
at the end ofCar.lua
&return SUV
at the end ofSUV.lua
. - Declare
require "car.Car"
inSUV.lua
to “import” theCar
table - Import
Car
andSUV
into the main lua
Here’s my directory (package) setup and the code:
------------------- -- Car table/class ------------------- Car = {} Car.__index = Car --constructor function Car.new(brand,price) local instance = { _brand = brand, _price = price } -- set Car as prototype for the new instance setmetatable(instance, Car) return instance end -- instance method definitions function Car:getBrand() return self._brand; end function Car:getPrice() return self._price; end function Car:getInfo() print("Brand",self:getBrand(),"price:",self:getPrice()) end -- so that the Car can be imported by other classes via 'require "car.Car"' return Car
------------------- -- SUV ------------------- require "car.Car" SUV = {}; SUV.__index = SUV -- constructor function SUV.new(brand,price,is4WD) local instance = { _is4WD = is4WD, _price = price, _brand = brand, } -- set SUV as prototype for instance setmetatable(instance,SUV) return instance end -- set up inheritance. Now SUV can access & override Car's methods setmetatable(SUV,{__index = Car}) -- instance methods function SUV:get4WD() return self._is4WD; end -- override function SUV:getInfo() print("SUV Brand",self:getBrand(),", price:",self:getPrice(),", 4WD",self:get4WD()) end -- so that the SUV can be imported by other classes via 'require "car.SUV"' return SUV;
-- import Car and SUV classes require "car.Car" require "car.SUV" local car = Car.new("Honda",200); print(car:getInfo()) local suv = SUV.new("Suzuki", 250, true) -- call inherited method print(suv:getBrand()) -- call the overridden method print(suv:getInfo())
Download
Here’s the zip containing the example [download id=”18″ format=”2″]
Also in this category ...
- » Compound Component
- » Membuat Public API di Komponen React dengan useImperativeHandle
- » useContext untuk Global State
- » 8 Perintah Git Esensial
- » Python 101: Dictionary