I'm trying to learn som OOP - Need some help

So I have setup two files. Card.lua and Main.lua

What my question is, 1. Is this a good design? 2. How can I pass instance variables to the event listeners I have setup. As shown, I’m trying to read variables setup in Card.new hello, card_is_showing, clickListener and myImage. I want to read them as instance variables in the event_listeners. It did work for onObjectTouch, why i don’t know. For onObjectTap, it doesn’t find the variable, i tried to put both card_is_showing, event.card_is_showing and event.target.card_is_showing, but it doesn’t work. Any help is appreciated.

Card = {} function Card.new(sprite, x, y, dragListener) hello = false card\_is\_showing = true clickListener = true myImage = display.newImage( sprite ) myImage.x = x myImage.y = y -- Add the mouse event listener. if dragListener == true then myImage.touch = onObjectTouch myImage:addEventListener( "touch", myImage ) end if clickListener == true then myImage.tap = onObjectTap myImage:addEventListener( "tap", myImage ) end return myImage end function onObjectTouch( self, event ) print( "onObjectTouch" ) if event.phase == "ended" then event.target.hello = false elseif event.phase == "began" then event.target.hello = true elseif event.phase == "moved" then if event.target.hello == true then event.target.x = event.x event.target.y = event.y end end end function onObjectTap( self, event ) if event.card\_is\_showing == true then event.target.isVisible = false event.card\_is\_showing = false end end

And the main file is

local card = require "Card" local deck = card.new("sprites/cardBack\_red5.png", -350, 409, false) ...

You have quite a few issues.

Firstly, you should generally use locals over globals. They are faster and are less prone to scope related bugs and leaks.

hello = false card\_is\_showing = true clickListener = true

These lines of code just set the same values to three globals every time you call the function. The “clickListener = true” line also means that, in your function, the “if clickListener == true then” check on line 18 will always be true, in which case it does nothing.

Now, to fix this, you’d add these three variables into the display object table, i.e.

local myImage = display.newImage( sprite ) myImage.x = x myImage.y = y myImage.hello = false myImage.card\_is\_showing = true myImage.clickListener = true

Now the entries will be accessible from your touch and tap functions via “event.target.hello”, for instance. I also made “myImage” a local. This way, once you return it from the function, there will only be one instance of it (unlike with the global).

Finally, the reason why your “onObjectTap” function doesn’t work is because you are looking for “event.card_is_showing”, but in your current code card_is_showing is a global variable that isn’t even attached to the event target. With my suggested fix, you’d access it via “event.target.card_is_showing”.

The reason why your “onObjectTouch” function works is because it creates the necessary values to the display object.

Oh, and also, if I’d be writing that card module/library, I’d structure it the following way:

local card = {} local function onObjectTouch( self, event ) ... end local function onObjectTap( self, event ) ... end function card.new( sprite, x, y, dragListener ) ... end return card

If you have some reasons why they need to be globals, then of course do so. I hope this helps!

Thanks, it works!

You have quite a few issues.

Firstly, you should generally use locals over globals. They are faster and are less prone to scope related bugs and leaks.

hello = false card\_is\_showing = true clickListener = true

These lines of code just set the same values to three globals every time you call the function. The “clickListener = true” line also means that, in your function, the “if clickListener == true then” check on line 18 will always be true, in which case it does nothing.

Now, to fix this, you’d add these three variables into the display object table, i.e.

local myImage = display.newImage( sprite ) myImage.x = x myImage.y = y myImage.hello = false myImage.card\_is\_showing = true myImage.clickListener = true

Now the entries will be accessible from your touch and tap functions via “event.target.hello”, for instance. I also made “myImage” a local. This way, once you return it from the function, there will only be one instance of it (unlike with the global).

Finally, the reason why your “onObjectTap” function doesn’t work is because you are looking for “event.card_is_showing”, but in your current code card_is_showing is a global variable that isn’t even attached to the event target. With my suggested fix, you’d access it via “event.target.card_is_showing”.

The reason why your “onObjectTouch” function works is because it creates the necessary values to the display object.

Oh, and also, if I’d be writing that card module/library, I’d structure it the following way:

local card = {} local function onObjectTouch( self, event ) ... end local function onObjectTap( self, event ) ... end function card.new( sprite, x, y, dragListener ) ... end return card

If you have some reasons why they need to be globals, then of course do so. I hope this helps!

Thanks, it works!