2013-05-08 52 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