简体   繁体   中英

Getting a 'nil' value when attaching an addEventListener method to a created Object

I just started getting my feet wet with Corona and trying to work with OOP. This is just a simple Match Making Game to help me along with thinking like OOP. I have 2 classes, one class will be creating an instances of a Card (i will be making multiple objects of this type of Card Class) and the other is the MatchCardsManager Class - this creates the cards and applies the properties

The error I am getting is, after i have created the object "MatchCard" i tried to apply an "addEventListener" to the object. but when i do i receive an error of the following

     Support/Outlaw/Sandbox/5/MatchCardsManager.lua:53: 
attempt to call method 'addEventListener' (a nil value)
        stack traceback:

If i comment out the info on addEventListener, all objects are displayed accordingly to the constructor i created in MatchCard Class.

Below are my files - the error i am getting is in the MatchCardsManager class

mCard[i] = MatchCardsManager:displayPlacementCard(i, temp, x, y)
mCard[i]:addEventListener("touch", myTouch)

Any help or suggestions about fixing this or better approach would be greatly appreciated. Thank you.

The MatchCard Class will be just a simple constructor for now as this is not my issue

-- MatchCard Class
-- Meta Data
local sceneGroup = sceneGroup

local MatchCard = { }
local MatchCard_mt = { __index = MatchCard } -- metatable

------------------------------------------------
-- PRIVATE FUNCTION 
------------------------------------------------

------------------------------------------------
-- PUBLIC FUNCTION
------------------------------------------------
-- constructor
function MatchCard.new (id, animal, state, imageId, x, y)

    local newMCard = display.newRoundedRect( x, y, 59, 47, 5)
    newMCard.strokeWidth = 3
    newMCard:setFillColor( 0.5 )
    newMCard:setStrokeColor( 1, 0, 0 )
    newMCard.properties = {
        id = id or nil,
        animal = animal or nil,
        state = state or 0, 
        imageId = imageId,
    }

    return setmetatable ( newMCard, MatchCard_mt )

end

MatchCardsManager Class is there I plan to create an many instances of cards

-- require files
local MatchCard = require('MatchCard') --MatchCard

local sceneGroup = sceneGroup
local MatchCardsManager = {} -- originally we should use a displayGroup

-- TODO: insert group into scene

local animalPicsReference = { "dog", "dog", "cat", "cat", "pig", "pig" , "fish", "fish"} 

-- manager class properties
MatchCardsManager.totalCards = 8
MatchCardsManager.totalPairs = 4
MatchCardsManager.pairsFound = 0
MatchCardsManager.firstCardSelected = 0
MatchCardsManager.secondCardSelected = 0

-- lets create 6 MatchCardFiles
function MatchCardsManager:create()

    local animalPics = animalPicsReference
    local x = 108 - 85
    local y = 125
    print("do we go here never works")

    local mCard = {}

    for i=1, 4  
        do 
           x = x + 85 
           num = math.random(1, #animalPics)
           temp = animalPics[num]
           table.remove(animalPics, num) 
           mCard[i] = MatchCardsManager:displayPlacementCard(i, temp, x, y)
           mCard[i]:addEventListener("touch", myTouch)

    end

    x = 108 - 85
    y = 195 
    for j = 5, 8 do 
            x = x + 85          
           num = math.random(1, #animalPics)
           temp = animalPics[num]
           table.remove(animalPics, num) 
           mCard[j] = MatchCardsManager:displayPlacementCard(j, temp, x, y)
           print(type(mCard[j]))
           mCard[j]:addEventListener("touch", myTouch)
    end
    --mCards:addEventListener("touch", myTouch)
    return mCard
end

local function  myTouch( event )
    if event.phase == "began" then
            print( "You touched the object! "..event.target.imageId)
    end
end

function MatchCardsManager:displayPlacementCard(idx, animal, x, y)
    -- randomly place the cards in the object id

    local card = MatchCard.new(idx, animal, 0, animal, x, y)
    --card:show(x,y) -- displays card and that is it
    print("animal added is "..card.properties.imageId)
    return card
end

return MatchCardsManager

The problem is in the constructor. local newMCard = display.newRoundedRect(...) creates a display object , but the line: return setmetatable(newMCard, MatchCard_mt) overwrites the metatable that the display object had and so it no longer has access to display's __index metamethod that is used to find addEventListener .

To fix this, you need to look into how inheritance is added in Lua. See Inheritance Tutorial so you can inherit addEventListener . The solution will be something like: setmetatable(MatchCard, {__index=ShapeObject}) or =display.ShapeObject} ---I can't be sure how Corona implements its classes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM