对象分配的Lua

问题描述:

我有类似于此的一个问题:LUA and Corona error: Attempt To Call Method ' ' (A Nil Value) - Driving Me Crazy 我有一个T-细胞类:对象分配的Lua

local TCell={}; 
local cell_mt = { __index=TCell }; 
function TCell.new(_contents_name,_x,_y) 
    ... 
    local ncell= 
    { 
     ... 
    }; 
    function ncell:setup() 
     ... 
    end 
    ncell:setup(); 
    return setmetatable(ncell,cell_mt); 
end 
return TCell; 

我有T细胞的引用被称为小区的2D阵列。 当我分配

cells[ind1][ind2]=cells[ind3][ind4] 

细胞[IND1] [IND2]开始失去某些属性。如果我正确地理解了上面的链接,那是因为失去了metatable关联。我需要再次使用setmetatable吗?如果作业没有在TCell主体中完成,我该怎么做?

upd。

reset_metatable=function(target) 
    return setmetatable(target,cell_mt); 
end; 
cells[ind1][ind2]=cells[ind3][ind4]; 
cells[ind1][ind2]=cells[ind1][ind2]:reset_metatable(); 

不是很有帮助。 upd2:删除所有未连接相机的代码。相机和TCell没有框架。问题似乎在metatables。输出给出6 1宽度i 50并且在它现在开始之后6 1宽度为零

----------------------------------------------------------------------------------------- 
-- 
-- Main Cycle 
-- 
----------------------------------------------------------------------------------------- 

local storyboard = require("storyboard") 
local scene = storyboard.newScene() 
-- include Corona's "physics" library 
local physics = require "physics" 
--control_circle=display.newImageRect(C.INTERFACE_DIR..C.INTERFACE_CONTROL_CIRCLE or C.EMPTY_IMAGE,C.CARS_W,C.CARS_W,true); 
local events_added=false; 

stage_frames=0; 
physics.start(); physics.pause() 
physics.setGravity(0,0); 

local PCar=require("TCar") 
local PBiped=require("TBiped"); 
local PCell=require("TCell"); 

local control_circle_len; 

local cells={}; 
local cells_w,cells_h; 
local wshift,hshift=-(C.SCREEN_THEORETICAL_W-C.SCREEN_W)/2,-(C.SCREEN_THEORETICAL_H-C.SCREEN_H)/2; 


-------------------------------------------- 

-- forward declarations and other locals 


----------------------------------------------------------------------------------------- 
-- BEGINNING OF YOUR IMPLEMENTATION 
-- 
-- NOTE: Code outside of listener functions (below) will only be executed once, 
--  unless storyboard.removeScene() is called. 
-- 
----------------------------------------------------------------------------------------- 
local wsells,hcells=(C.SCREEN_W-C.SCREEN_W%C.LANDSCAPE_CELL_W)/C.LANDSCAPE_CELL_W+1,(C.SCREEN_H-C.SCREEN_H%C.LANDSCAPE_CELL_H)/C.LANDSCAPE_CELL_H+1; 

local dfd=false; 
local function manage_cells(cmx,cmy) 
    --print("#",cmx,cmy); 
    if((cmx==0 and cmy==0) or dfd) 
    then 
     return; 
    end 
    local cells_shift_w,cells_shift_h=0,0; 
    if(cmx>=0) 
    then 
     for i=cells_w,1,-1 
     do 
      if(cells[i][1]:out_of_borders_w()==true) 
      then 
       cells_shift_w=cells_shift_w+1; 
      else 
       break; 
      end 
     end 
    else 
     for i=1,cells_w,1 
     do 
      if(cells[i][1]:out_of_borders_w()==true) 
      then 
       cells_shift_w=cells_shift_w-1; 
      else 
       break; 
      end 
     end 
    end 
    if(cmy>=0) 
    then 
     for i=cells_h,1,-1 
     do 
      if(cells[1][i]:out_of_borders_h()==true) 
      then 
       --[[cells[1][i].contents.rotation=45; 
       dfd=true;]] 
       cells_shift_h=cells_shift_h+1; 
      else 
       break; 
      end 
     end 
     --return; 
    else 
     for i=1,cells_h,1 
     do 
      if(cells[1][i]:out_of_borders_h()==true) 
      then 
       cells_shift_h=cells_shift_h-1; 
      else 
       break; 
      end 
     end 
    end 
    --print("~",cells_shift_w,cells_shift_h); 
    local stx,finx,sty,finy=1,cells_shift_w,1,cells_shift_h; 
    if(cmx<0) 
    then 
     stx=cells_w+cells_shift_w; 
     finx=cells_w; 
    end 
    if(cmy<0) 
    then 
     sty=cells_h+cells_shift_h; 
     finy=cells_h; 
    end 
    for i=stx,finx,1 
    do 
     for j=1,cells_h,1 
     do 
      if(cells[i][j]) 
      then 
       cells[i][j]:destroy(); 
       cells[i][j]=nil; 
      end 
     end 
    end 
    for i=1,cells_w,1 
    do 
     for j=sty,finy,1 
     do 
      if(cells[i][j]) 
      then 
       cells[i][j]:destroy(); 
       cells[i][j]=nil; 
      end 
     end 
    end 
    stx,finx,sty,finy=cells_w-cells_shift_w-1,1,cells_h-cells_shift_h-1,1; 
    local itx,ity=-1,-1; 
    if(cmx>=0) 
    then 
     stx=cells_shift_w+1; 
     finx=cells_w; 
     itx=1; 
     print(stx,finx); 
    end 
    if(cmy>=0) 
    then 
     sty=cells_shift_h+1; 
     finy=cells_h; 
     ity=1; 
    end 


    for i=stx,finx,itx 
    do 
     for j=1,cells_h,1 
     do 
      if(cells_shift_w~=0) 
      then 

       if(j==1) 
       then 
        print(i,1,"to",i-cells_shift_w,1); 
       end 
       cells[i-cells_shift_w][j]=cells[i][j]; 
       cells[i-cells_shift_w][j]=cells[i-cells_shift_w][j].reset_metatable(cells[i][j]); 
       print("++",cells[i-cells_shift_w][j].contents.width); 
       cells[i][j]:destroy(); 
       cells[i][j]=nil; 
       if(j==1) 
       then 
        print(i-cells_shift_w,1,"width is",cells[i-cells_shift_w][1].contents.width); 
        if(i==7) 
        then 
         cells[6][1].debug=true; 
         print("debug is set"); 
        end 
       end 
      end 
     end 
    end 
    for i=1,cells_w,1 
    do 
     for j=sty,finy,ity 
     do 
      if(cells_shift_h~=0) 
      then 
       print("?this?",i,j); 
       cells[i][j-cells_shift_h]=cells[i][j]; 
       cells[i][j]:destroy(); 
       cells[i][j]=nil; 
      end 
     end 
    end 
    for i=1,cells_w,1 
    do 
     for j=1,cells_h,1 
     do 
      if(cells[i][j]==nil) 
      then 
       print("*new",i,j); 
       cells[i][j]=PCell.new(C.LANDSCAPE_DICTIONARY(nil,1),(i-1)*C.LANDSCAPE_CELL_W+C.LANDSCAPE_CELL_W/2-wshift-camera:getX(),(j-1)*C.LANDSCAPE_CELL_H+C.LANDSCAPE_CELL_H/2-hshift-camera:getY()); 
      end 
     end 
    end 

end 
local function stage_main_frame() 
    print("START NOW",6,1,"width is",cells[6][1].contents.width); 
    local old_camera_x,old_camera_y=camera._view.x,camera._view.y; 
    if(dfd==false) 
    then 
     --print("&"); 
     camera._view.x=camera._view.x-stage_frames; 
    end 
    local cmx,cmy=-(camera:getX()-old_camera_x),-(camera:getY()-old_camera_y); 
    manage_cells(cmx,cmy); 


    stage_frames=stage_frames+1; 
    print("NOW",6,1,"width is",cells[6][1].contents.width); 
    return function(event) 
    end 

end 
-- Called when the scene's view does not exist: 
function scene:createScene(event) 
    local group = self.view 
end 

-- Called immediately after scene has moved onscreen: 
function control_player(event) 
    car1:get_touch(event); 
end 
function scene:enterScene(event) 
    camera:newLayer("land",1); 
    camera:newLayer("bipeds",1); 
    camera:newLayer("cars",1); 

    i=1; 
    while((i-1)*C.LANDSCAPE_CELL_W-C.LANDSCAPE_CELL_W/2-wshift<=C.SCREEN_W) 
    do 
     j=1; 
     cells[i]={}; 
     while((j-1)*C.LANDSCAPE_CELL_H-C.LANDSCAPE_CELL_H/2-hshift<=C.SCREEN_H) 
     do 
      cells[i][j]=PCell.new(C.LANDSCAPE_DICTIONARY(nil,1),(i-1)*C.LANDSCAPE_CELL_W+C.LANDSCAPE_CELL_W/2-wshift-camera:getX(),(j-1)*C.LANDSCAPE_CELL_H+C.LANDSCAPE_CELL_H/2-hshift-camera:getY()); 
      j=j+1; 
     end 
     i=i+1; 
    end 
    cells_w,cells_h=#cells,#cells[1]; 
    local group = self.view 
    physics.start(); 
    physics.setPositionIterations(1) 
    if(events_added==false) 
    then 
     events_added=true; 
     Runtime:addEventListener("touch",control_player); 
     Runtime:addEventListener("enterFrame",stage_main_frame); 
    end 
end 

-- Called when scene is about to move offscreen: 
function scene:exitScene(event) 
    local group = self.view 

    physics.stop() 

end 

-- If scene's view is removed, scene:destroyScene() will be called just prior to: 
function scene:destroyScene(event) 
    local group = self.view 

    package.loaded[physics] = nil 
    physics = nil 
end 

----------------------------------------------------------------------------------------- 
-- END OF YOUR IMPLEMENTATION 
----------------------------------------------------------------------------------------- 

-- "createScene" event is dispatched if scene's view does not exist 
scene:addEventListener("createScene", scene) 

-- "enterScene" event is dispatched whenever scene transition has finished 
scene:addEventListener("enterScene", scene) 

-- "exitScene" event is dispatched whenever before next scene's transition begins 
scene:addEventListener("exitScene", scene) 

-- "destroyScene" event is dispatched before view is unloaded, which can be 
-- automatically unloaded in low memory situations, or explicitly via a call to 
-- storyboard.purgeScene() or storyboard.removeScene(). 
scene:addEventListener("destroyScene", scene) 

----------------------------------------------------------------------------------------- 

return scene 

local TCell={}; 
local cell_mt = { __index=TCell }; 
function TCell.new(_contents_name,_x,_y) 
    --print(camera.x); 
    if(_x==nil) 
    then 
     _x=0; 
    end 
    if(_y==nil) 
    then 
     _y=0; 
    end 
    camera:newLayer("abacaba", 1); 
    local ncell= 
    { 
     contents_name=_contents_name; 
     contents; 
     sequence_data; 
     sheet_data; 

     debug=false; 
     --[[main_frame; 
     main_frame_handler=function(self) 
      main_frame=function(event) 
       if(self.contents.x+self.contents.width/2<0 or self.contents.y+self.contents.height/2<0 or self.contents.x-self.contents.width/2>C.SCREEN_W or self.contents.y-self.contents.height/2>C.SCREEN_H) 
       then 
        --self:destroy(); 
       end 
      end 
      return main_frame; 
     end;]] 
     clear=function(self) 
      if(self.debug==true) 
      then 
       print("CLEAR!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n\n\n"); 
      end 
      --print(self.contents); 
      self.contents:removeSelf(); 
      camera:removeObject("land",self.contents); 
     end; 
     show=function(self,_contents_name,__x,__y) 
      if(self.debug==true) 
      then 
       print("SHOW!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n\n\n"); 
      end 
      self.contents_name=_contents_name; 
      if(self.contents_name~=C.EMPTY_IMAGE) 
      then 
       self:set_sequence_data(); 
      end 
      if(self.contents_name~=C.EMPTY_IMAGE) 
      then 
       self.sheet_data=graphics.newImageSheet(self.contents_name,C.LANDSCAPE_SHEET_DATA); 
       self.contents=display.newSprite(self.sheet_data,self.sequence_data); 
      else 
       self.contents=display.newImageRect(C.EMPTY_IMAGE,C.LANDSCAPE_CELL_W,C.LANDSCAPE_CELL_H,true); 
       self.sequence_data=nil; 
      end 
      self.contents.x=__x; 
      self.contents.y=__y; 
      camera:addObject("land",self.contents); 
     end; 
     out_of_borders_w=function(self) 
      --print(self.contents.width); 
      return self.contents.x+self.contents.width/2-camera:getX()<C.LANDSCAPE_CELLS_LEFT_BORDER-C.LANDSCAPE_CELL_W or 
       self.contents.x-self.contents.width/2-camera:getX()>C.LANDSCAPE_CELLS_RIGHT_BORDER+C.LANDSCAPE_CELL_W; 
     end; 
     out_of_borders_h=function(self) 
      return self.contents.y+self.contents.height/2-camera:getY()<C.LANDSCAPE_CELLS_UPPER_BORDER-C.LANDSCAPE_CELL_H or 
       self.contents.y-self.contents.height/2-camera:getY()>C.LANDSCAPE_CELLS_LOWER_BORDER+C.LANDSCAPE_CELL_H; 
     end; 
     reset_metatable=function(target) 
      return setmetatable(target,cell_mt); 
     end; 
     set_sequence_data=function(self) 
      local px=math.floor(((_x)%C.LANDSCAPE_SHEET_DATA.sheetContentWidth)/C.LANDSCAPE_SHEET_DATA.width)+1; 
      local py=math.floor(((_y)%C.LANDSCAPE_SHEET_DATA.sheetContentHeight)/C.LANDSCAPE_SHEET_DATA.height)+1; 
      self.sequence_data= 
      { 
       { name = "only", start=C.LANDSCAPE_SHEET_DATA.sheetContentWidth/C.LANDSCAPE_SHEET_DATA.width*(py-1)+px, count=1 } 
      }; 
     end; 

     destroy=function(self) 
      --Runtime:removeEventListener("enterFrame",self.main_frame); 
      --Runtime:removeEventListener("enterFrame",self.main_frame_handler); 

      self:clear(); 
      if(index~=nil) 
      then 
       --destroy_cell(index); 
      end 
     end 
    }; 
    function ncell:setup() 
     self:show(self.contents_name,_x,_y); 
    end 
    ncell:setup(); 
    return setmetatable(ncell,cell_mt); 
end 
return TCell; 
+2

有错配'[' – hjpotter92

+0

已更正。这是一个例子。代码如下所示:cells [i-cells_shift_w] [j] = cells [i] [j]; – user2136963

+0

你确定'i-cells_shift_w','i'和'j'总是指向有效的键吗? –

我相信你可能会误解Lua中的变量赋值。所有变量实际上都是对象的引用/指针。当你写:

cells[ind1][ind2]=cells[ind3][ind4] 

你扔掉(除去参考),通过细胞[IND1] [IND2]指向的对象,并创建第二个参考对象被细胞[指向IND3] [IND4]。

如果您在赋值之前在单元格[ind1] [ind2]中放置了一些东西(比如您认为正在消失的属性),它将不会在赋值之后出现,因为该变量现在指向不同的对象。