2013-05-08 23 views
0

我只是好奇,以及有點困惑。在我的lua代碼中,我從一開始就設置了一個新對象。lua中的對象密鑰訪問的一些洞察

enemy = {}; 

enemy.__index = enemy; 

function enemy.new(args) 
Obj = {}; 
setmetatable(Obj,enemy); 
Obj.name = "bullet"; 
Obj.x = args.x; 
Obj.y = args.y; 
Obj.spriteTexFile= "Invader.png"; 
Obj.sprite = display.newImage(Obj.spriteTexFile); 
Obj.sprite:setReferencePoint (display.TopLeftReferencePoint); 
Obj.sprite.x = Obj.x; 
Obj.sprite.y = Obj.y; 
Obj.sprite.alpha = 0; 
Obj.health = 100; 
Obj.activeBul = false; 
Obj.bullet = Bullet.new({x=Obj.sprite.x,y=Obj.sprite.y}); 
return Obj; 
end 
... 
return enemy; 
end 

因此,當實例化一個新的Enemy obj時,我將調用上面的新函數。現在在同一個文件中,敵人對象中的函數我有以下函數,例如它允許我訪問「self.bullet」,這是創建敵人時創建的Bullet對象。它也允許我在這個Bullet瞬間調用函數trajectBullet。

function enemy:shoot() 
local Bullet = require "Bullet"; 
local DEFAULTTIME = 5;--Movement time per space 
    self.bullet:trajectBullet({x=self.sprite.x,y=display.contentHeight, time = 
           DEFAULTTIME*display.contentHeight-self.sprite.y)}); 
end 

我的問題帶有如下調用。如果我嘗試在這種情況下設置一個子彈屬性,所有者屬性,我得到一個零錯誤,並不會讓我改變它。如果有人能夠幫助我理解訪問密鑰和屬性的真正效果,這將幫助我解決很多問題。

function enemy:setBulletOwner() 
self.bullet.owner = self; 
end 

UPDATE:

bullet = {}; 

bullet.__index = bullet; 

function bullet.new(arg) 
local Obj = {}; 
setmetatable (Obj, bullet); 
Obj.sprite = display.newRect( 0, 0, 3, 7); 
Obj.sprite.x = arg.x; 
Obj.sprite.y = arg.y; 
Obj.sprite:setFillColor (255, 255, 255 ); 
Obj.sprite:setReferencePoint (display.TopLeftReferencePoint); 
Obj.owner = nil; 
return Obj; 
end 

function bullet:trajectBullet(arg) 
self.sprite.tween = transition.to(self.sprite,{ tansistion = easing.outExpo, y = arg.y,   x=arg.x,time= arg.time,onComplete = function() bullet:cancelTween(self.sprite); 
    self.owner.sprite:dispatchEvent({name = "canShootAgain"}); end}); 
end 

記住Obj.owner應該得到從下面的功能設置。

function enemy:setBulletOwner() 
print("BULLET MADE"); 
self.bullet.owner = self; 
end 
+0

也許,你正在執行'enemy.setBulletOwner()'代替'enemy:setBulletOwner()' – 2013-05-08 10:14:57

+0

沒有im正在執行敵人:setBulletOwner() – 2013-05-08 19:52:33

+0

您忘記添加**完整**錯誤消息。有各種類型的「nil」錯誤信息 – dualed 2013-05-09 12:21:26

回答

3

你應該把你的班級設置了這樣

子彈

Bullet = {} 
Bullet_mt = { __index = Bullet } 

function Bullet:new(co_ordinates) 
    local obj = {x=co_ordinates[1],y=co_ordinates[2]} 
    obj.owner = "You" --etc... 
    return setmetatable(obj,Bullet_mt) 
end 

敵人

Enemy = {slogan="Gettm!'"} 
Enemy_mt = {__index = Enemy;} 

function Enemy:new(args) 
    local obj = {} 
    --etc.. 
    obj.bullet = Bullet:new({0,0}) 
    return setmetatable(obj,Enemy_mt) 
    --alert return setmetatable(obj,getmetatable(self)) 
end 

function Enemy:getBulletOwner() 
    return self.bullet.owner; 
end 

你不應該要求 「子彈」 每時間敵人射中enemy:shoot。如果你想爲敵人創造一顆子彈,如果你只想讓敵人有一顆子彈,你應該創建一個新的'實例'的子彈類,並將它與bullet關聯,就像你一直在做的那樣obj.bullet= Bullet.new(...)但是還將這個功能引入到Enemy的方法中(所以你可以在老的超出範圍之後添加一個新的子彈......)。


如果指數沒有在表中存在,它會去尋找與__index在有關分配表的元表相關聯的表中的索引。例如a = Enemy:new(),我們想通過a.slogan找出敵人的口號,我們會在a尋找索引slogan,但沒有找到它。所以我們再去檢查a的metatable中__index是什麼,在這種情況下是Enemy。所以我們尋找sloganEnemy,它存在,所以我們結束了'「Gettm!'」。

添加以下代碼下面的類定義

en = Enemy:new() 
print(en:getBulletOwner()) 
print(en.slogan) 

可生產

You 
Gettm!' 

另外睏倦a:b(arg1,arg2)a.b(arg1,arg2)之間的差的。 a:b(arg1,arg2)實質上等同於a.b(a,arg1,arg2),其中a被綁定到self的函數內。這方面的一個例子是:

print(en.getBulletOwner()) 

產生

lua: l.lua:22: attempt to index local 'self' (a nil value) 

print(en:getBulletOwner()) 

產生

You 
+0

謝謝您首先發布的所有信息。我正在閱讀你的文章,對我來說,它看起來像我在第一部分做同樣的事情。在敵人的功能,我嘗試做「self.bullet.owner」,就像你在你的getBulletOwner做的,我得到「試圖索引字段'子彈'(一個零值)」我知道原因是因爲self.bullet是本身=無,當它實際上它SHOULDNT!所以它試圖從零訪問信息,所以它崩潰。我只是很困惑什麼即時通訊做錯了。我更新了我原來的帖子,以包含新項目 – 2013-05-08 19:59:55

+0

@WilliamMcCarty嘗試更改'bullet .__ index = bullet;'爲'bullet .__ index = function(_,key)return bullet [key] end' – HennyH 2013-05-09 06:26:01