local lamps = {} -- (table of lamps, and states)массив состояний ламп lamps[1] = { lamp = display.newCircle(160,50,35), state = 0 } lamps[2] = { lamp = display.newCircle(60,50,35), state = 0 } lamps[3] = { lamp = display.newCircle(260,50,35), state = 0 } lamps[4] = { lamp = display.newCircle(160,150,35), state = 0 } lamps[5] = { lamp = display.newCircle(60,150,35), state = 0 } lamps[6] = { lamp = display.newCircle(260,150,35); state = 0 } local function lamp\_tap (event) if event.target.state == 1 then -- if we choose correct lamp event.target.lamp:setFillColor(0,0.8,0) else -- if not event.target.lamp:setFillColor(0.8,0,0) end end for i=1,6 do lamps[i].lamp:addEventListener("tap",lamp\_tap) end
I’m using this “system” of index in other functions, and they’re working, but in lamp_tap something goes wrong,and I see an error : “attempt to index field ‘lamp’(a nil value)”. What’s wrong?
You are getting this error because you are mixing up your tables and event targets.
You attach the eventListener to lamps[#].lamp, which means that this is your event target. In your code, you are referring to event.target.lamp, which is the same as, for example, lamps[1].lamp.lamp. Your app crashes because it tries to set fill color to a display object that does not exist. Changing the code to just “event.target:setFillColor(0.8,0,0)” will fix the crash.
You, however, have another issue there as well. Your “state” value is attached to the lamps[#] table and it isn’t connected to the event.target directly.
Also, in Corona, all display objects are tables. You could simplify and fix your code by doing the following:
local lamps = {} lamps[1] = display.newCircle(160,50,35) lamps[1].state = 0
either as per xedur: use the display object as the table element then “decorate” it with the state value
OR…
if you want/need to retain your current structure (where outer table is a simple lua table that “owns” an undecorated display object in its .lamp plus whatever other values like .state), then give .lamp a reference back to its outer wrapper so that you can traverse up from the event.target to the table, then over to the state value, fe:
-- lamps[n].lamp needs a ref to lamps[n] for i = 1,6 do lamps[i].lamp.wrapper = lamps[i] end -- in event listener event.target -- is lamps[n].lamp, a display.newCircle event.target.wrapper -- is lamps[n], a table event.target.wrapper.state -- is lamps[n].state, a number
You are getting this error because you are mixing up your tables and event targets.
You attach the eventListener to lamps[#].lamp, which means that this is your event target. In your code, you are referring to event.target.lamp, which is the same as, for example, lamps[1].lamp.lamp. Your app crashes because it tries to set fill color to a display object that does not exist. Changing the code to just “event.target:setFillColor(0.8,0,0)” will fix the crash.
You, however, have another issue there as well. Your “state” value is attached to the lamps[#] table and it isn’t connected to the event.target directly.
Also, in Corona, all display objects are tables. You could simplify and fix your code by doing the following:
local lamps = {} lamps[1] = display.newCircle(160,50,35) lamps[1].state = 0
either as per xedur: use the display object as the table element then “decorate” it with the state value
OR…
if you want/need to retain your current structure (where outer table is a simple lua table that “owns” an undecorated display object in its .lamp plus whatever other values like .state), then give .lamp a reference back to its outer wrapper so that you can traverse up from the event.target to the table, then over to the state value, fe:
-- lamps[n].lamp needs a ref to lamps[n] for i = 1,6 do lamps[i].lamp.wrapper = lamps[i] end -- in event listener event.target -- is lamps[n].lamp, a display.newCircle event.target.wrapper -- is lamps[n], a table event.target.wrapper.state -- is lamps[n].state, a number