Corona LUA and OOP Design

So, I proceed from the traditional game development, which uses the principles of OOP, and from what I saw, you can imitate this using LUA when you know what you are doing. In some code posts, I found out how you can use the director class and create files with a new function (), etc.

What I'm looking for is a way to control my weapons. I have a player and an opponent, and I would prefer to have one class of weapons, say, Canon weapons. I have done the following:

-- private vars here local power local canonSprite local whatever local someFunction = function() ... end -- Private stuff here local weaponCanon = {} weaponCanon.fire = function(atX, atY) ... end weaponCanon.reset = function() ... end return weaponCanon 

Then in my level code I just do:

 local weaponCanon = require("weaponCanon") weaponCanon.fire(100, 100) 

This works great and allows me to use the "private" and "public" mentality when encoding my weapons. The problem is that if I want the player and the opponent to have a canon:

 local playerWeapon = require("weaponCanon") local opponentWeapon = require("weaponCanon") 

It just returns the same object, not a new instance of this object. Thus, I get only one Canon weapon at the enemyโ€™s location. This is obviously now what I want / need.

There are a lot of weapons in our game, and it would be nice to have only one version of each file with a setting that tells us if this is an enemy weapon or a playerโ€™s weapon. An alternative is to copy each file and create a weapon, PlayerCanon and weaponOpponentCanon, but I compress the thought of modifications to one file and must change 2+ files each time.

How can I make it return an instance and what is the structure of the LUA file for this?

Thanks or any help

-d

+7
source share
5 answers

I think you are trying to model a class with your source file. This means that you must also have a function to create a new instance of this class, if you do not want them to share all their state.

Something line by line (unchecked):

 local WeaponCannon = {} WeaponCannon.__index = WeaponCannon function WeaponCannon:new() return setmetatable({}, self) end function WeaponCannon:fire(x, y) -- Do something via the self reference and arguments (x, y) end return WeaponCannon 

And in your code code (also untested):

 require('WeaponCannon') local playerWeapon = WeaponCannon:new() local opponentWeapon = WeaponCannon:new() 
+5
source

If you later begin to need inheritance (that is, LaserCannon is a subclass of Weapon), you may have to use metadata more deeply.

There are many libraries that let you run "oop on top of Lua." Here you can see a very good list:

http://lua-users.org/wiki/ObjectOrientedProgramming

I am the author of middleclass . With my library you would have to do something like this:

 local Weapon = class('Weapon') function Weapon:initialize(a,b,c) self.x,self.y,self.z = a,b,c end function Weapon:fire(x,y) ... end 

LaserCannon will be easy to implement - you just pass the second class to the class:

 local LaserCannon = class('LaserCannon', Weapon) function LaserCannon:initialize(a,b,c,d) self.w = d Weapon.initialize(self, a,b,c) -- superclass' constructor end function LaserCannon:foo() ... end 

You can use it as follows:

 require 'middleclass' -- so you can use "class" LaserCannon = require 'laser_cannon' local playerWeapon = LaserCannon:new() -- a laser local opponentWeapon = Weapon:new() -- a regular generic weapon opponentWeapon:fire(100,200) -- typical use playerWeapon:fire(100, 200) -- LaserCannon inherits fire from Weapon playerWeapon:foo() -- LaserCannon-exclusive 

This is with the middle class, which I prefer since I did it. Other libraries on the page that I mentioned earlier offer similar features.

+7
source

Although you are creating a new table for the weapon object, you are not creating new variables. Any variables declared at the top of your module are essentially static variables (i.e., variables shared by all instances of the class.) To create variables that are unique to this object, you need to create them in a table, for example:

 weaponCannon = {} weaponCannon.power = 10 

And in any case, you only create the object once, you need the "constructor" function, which creates the tables:

 function new() local weaponCannon = {} weaponCannon.power = 10 end 


By the way, there are two other things that are not directly related to your answer, but can be very useful changes to your code. Firstly, using a colon instead of a period for calling functions in a method will allow you to use the "self" keyword inside the method, for example:

 function weaponCannon:fire() --this is only a test print(self.power) end 

then

 local playerWeapon = require("weaponCanon") playerWeapon:fire() 

Secondly, you can actually use display objects as tables, instead of creating an empty table, and then pasting the display object into this empty table:

 weaponCannon = display.newImage("cannon.png") weaponCannon.power = 10 

Please note that you cannot set up a meta table if you do. I believe that this approach looks more logical and prefers not to use meta tables on their own, but this is your challenge.

+1
source

There are no objects - you just have a bunch of global data. You really need to make instances.

 function NewWeapon(arg) return { fire = function(self, atX, atY) print(self.var) end, var = arg, } end NewWeapon(3):fire(1, 2) NewWeapon(7):fire(3, 5) 
0
source

I like ponzao. However, change it to:

 local WeaponCannon = {} function WeaponCannon:new() local instance = {} setmetatable(instance, {__index = WeaponCannon}) -- setup your new instance here return instance end function WeaponCannon:fire(x, y) -- Do something via the self reference and arguments (x, y) end return WeaponCannon 

And in your code code:

 local WeaponCanon = require('WeaponCannon') local playerWeapon = WeaponCannon:new() local opponentWeapon = WeaponCannon:new() 

What I changed:

  • Created a local instance variable to allow installation before returning it
  • A more compact way to install metatetable
  • Use a variable for the class when calling code
0
source

All Articles