2013-03-30 37 views
9

Tôi có một vấn đề tương tự như này: LUA and Corona error: Attempt To Call Method ' ' (A Nil Value) - Driving Me Crazy Tôi có một lớp TCell:Object 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ôi có mảng 2ngày tài liệu tham khảo TCell gọi là tế bào. Khi tôi chỉ định

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

ô [ind1] [ind2] bắt đầu mất một số thuộc tính. Nếu tôi hiểu liên kết ở trên chính xác thì điều đó gây ra bởi việc mất liên kết có thể so sánh được. Tôi có cần sử dụng setmetatable lần khác không? Làm thế nào tôi có thể làm điều đó nếu nhiệm vụ không được thực hiện trong cơ thể TCell?

cập nhật.

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

không thực sự hữu ích. upd2: xóa tất cả mã không được kết nối với máy ảnh. Máy ảnh và TCell không có khung nhập. Vấn đề có vẻ là trong metatables. Đầu ra cho NOW 6 1 chiều rộng i 50 và sau nó BẮT ĐẦU NGAY 6 1 chiều rộng là nil

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

Có sự không khớp '[' – hjpotter92

+0

Đã sửa. Đó là một ví dụ. Mã này trông giống như: các ô [i-cells_shift_w] [j] = các ô [i] [j]; – user2136963

+0

Bạn có chắc chắn rằng 'i-cells_shift_w',' i' và 'j' luôn trỏ đến các khóa hợp lệ không? –

Trả lời

1

Tôi tin rằng bạn có thể hiểu sai phân bổ biến ở Lua. Tất cả các biến thực sự là tham chiếu/con trỏ tới đối tượng. Khi bạn viết:

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

bạn đang ném đi (loại bỏ một tham chiếu đến) đối tượng được trỏ đến bởi các tế bào [ind1] [ind2], và bạn tạo một tài liệu tham khảo thứ hai để các đối tượng được trỏ đến bởi các tế bào [ ind3] [ind4].

Nếu bạn đặt một số nội dung (như các thuộc tính bạn nghĩ đang biến mất) trong các ô [ind1] [ind2] trước bài tập, nó sẽ không ở đó sau bài tập vì biến đó hiện trỏ vào một đối tượng khác.