0

我只是有点好奇,也有点困惑。在我的 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 瞬间调用函数 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

我的问题带有如下调用。如果我在这种情况下尝试设置 Bullet 的属性,即 owner 属性,我会得到一个 nil 错误并且不会让我更改它。如果有人可以帮助我了解访问密钥和属性的真正工作原理,那将对我有很大帮助。

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

更新:

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
4

1 回答 1

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我们会在里面寻找索引slogana但没有找到。因此,在这种情况下,我们将检查__index与 的元表相关联的内容。所以我们寻找in ,它存在所以我们最终得到 `"Gettm!'"。aEnemysloganEnemy

在类定义下添加以下代码

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)where ais bound 。self这方面的一个例子是:

print(en.getBulletOwner())

生产

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

尽管

print(en:getBulletOwner())

生产

You
于 2013-05-08T10:17:43.937 回答