2011-06-14 71 views
7

所以我來自傳統的遊戲開發,使用面向對象的原則,從我看到你可以模仿使用LUA一旦你知道你在做什麼。在一些代碼貼子中,我發現如何使用導演類並創建具有新()功能的文件等。電暈LUA和OOP設計

我正在尋找的是管理我的武器的方法。我有一個球員和一個對手,我寧願有一個武器類,比如weaponCanon。我所做的是:

-- 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 

然後在我的級別代碼中,我簡單地做:

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

此編碼了當的偉大工程,允許我使用「私有」和「公共」的心態我武器。問題是,如果我想要的球員,對手有一個佳能:

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

這只是返回相同的對象,而不是一個新的實例到該對象。所以我只能在對手的武器位置獲得一件武器。這顯然現在是我想要/需要的。

我們的遊戲中有很多武器,如果只有一個版本的每個文件都有一個設置,告訴我們它是對手的武器還是玩家武器,那就太好了。另一種方法是複製每個文件並創建一個weaponPlayerCanon和一個weaponOpponentCanon,但是我擔心修改一個文件並不得不每次更改2+文件。

我該如何讓它返回一個實例以及LUA文件的結構是什麼?

感謝或任何和所有幫助

-d

+0

我很清楚:http://lua-users.org/wiki/LuaModuleFunctionCritiqued,這是我得到我的設計,但它並不真正解決我的問題,除非我忽略了一些東西.. – 2011-06-14 14:54:01

+0

我想你錯過了你需要的數據和邏輯。所以你需要一個新的功能來提供「表格」來包含你的武器的設置,然後你可以提供這個設置作爲火力函數的參數,所以它減少了槍械表格的功率值。 PIL的第15章應該讓你朝着正確的方向http://www.lua.org/pil/15.html – 2011-06-14 15:11:05

+0

你在這裏所做的是告訴我一些我最終想要測試的東西,所以謝謝你救了我麻煩。 – jhocking 2011-06-15 11:42:19

回答

5

我想你想一類與源文件模型。這意味着你還應該有一個函數來創建該類的一個新實例,除非你希望他們共享他們的所有狀態。沿(未經測試)的線

東西:

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 

而且在調用代碼(也未經測試):

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

感謝所有的答覆,我覺得這些都是很棒的解決方案..這個讓我想到我想要做的。 – 2011-06-15 15:32:59

+0

嘿,在這個例子中你將如何擁有私有變量/函數?或者,除非我使用圖書館,否則不存在? – 2011-06-15 16:02:54

+0

如果它們是不帶任何狀態的實用函數,只是將它們放在源文件中,並且不返回它們。您不在表中公開的任何本地變量也是私有的。作爲一個例子'函數f()local a = 5; return {getA = function()返回結束,setA = function(new_a)a = new_a end} end'。局部變量'a'只通過'getA'和'setA'公開。 – ponzao 2011-06-15 19:03:49

0

有沒有對象這裏 - 你只是有一堆的全球數據。你真的需要製作實例。

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) 
7

如果以後你就開始需要繼承(即LaserCannon是武器的子類),你可能會需要更深刻地使用元表。

有很多圖書館可以讓你做「在Lua之上」。你可以看到一個非常好的列表在這裏:

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

我的middleclass作者。隨着我的lib中,你將不得不做這樣的事情:

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會很容易實現 - 你只是傳遞第二個參數類:

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 

你可以使用這樣的:

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 

這是middleclass,這是我喜歡的,因爲我做了它。我之前提到的頁面上的其他庫提供了類似的功能。

+0

我一直在看你的圖書館,並喜歡它很多。我可能會很快切換。我一直在做一些測試,但遇到了一個大問題。我將它用於Corona SDK,並遇到需要設置要調用的onCollision函數的情況。通常我只是做: self.canonBall.collision = onWeaponCollision self.canonBall:的addEventListener( 「碰撞」,self.canonBall) 然而,onWeaponCollision將無法正常工作。有沒有辦法仍然與你的圖書館做到這一點? 閱讀更多: http://stackoverflow.com/questions/6363671/middleclass-problems – 2011-06-15 21:35:19

+1

回答了這個問題:) – kikito 2011-06-15 21:38:25

1

雖然您爲武器對象創建了一個新表,但您不會創建新變量。任何在模塊頂部聲明的變量本質上都是靜態變量(即變量由類的所有實例共享)。要創建對於該對象唯一的變量,您需要在表中創建變量,如下所示:

weaponCannon = {} 
weaponCannon.power = 10 

而且你只有一次創建一個對象,你需要一個 「構造」 功能,創建表:

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


順便說一句,這AREN其他兩個東西不直接與您的答案相關,但可以對您的代碼進行非常有用的修改。首先,使用的不是句冒號調用函數的方法可以讓你使用的方法裏面的「自我」的關鍵詞,是這樣的:

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

然後

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

其次,可以實際使用的顯示對象爲表,而不是創建一個空表,然後貼在顯示器對象成空表:

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

注意,你不能設置元-T但是如果你這樣做的話。我發現這種方法看起來更符合邏輯,並且不希望自己使用元表,但那是你的呼叫。

0

我喜歡ponzao的回答。然而,將其更改爲:

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 

而且在調用代碼:

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

我改變什麼:返回之前

  • 創建一個本地實例變量,允許設置設置元表
  • 使用一個變量的類磨片的
  • 更緊湊的方式ñ調用代碼