Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

What is Return True really for?
Started by lp.peralta1 May 27 2013 11:59 AM

- - - - -
2 replies to this topic

Best Answer Rob Miracle , 27 May 2013 - 01:08 PM

Let me try to explain this.

 

1.  When you need to.

2.  When dealing with events, in particular touch and tap events.

 

Number 1 might seem kind of odd, but we cannot predict how you might write a function and what you might do with it.  Returning True or False from a function is a way to identify if that function was successful or not.

 

local function  isNumberPositive(someNumber)
      if someNumber < 0 then
           return false
      end
      return true
end
 
if isNumberPositive(105) then
      print("Positive")
else
      print("Negative")
end
 

 

We cannot predict how you will write functions and when you need to return what.

 

However... For things that generate touch and tap events, returning true prevents other objects from receiving an event.   Imagine if you will a racing game, your display is a series of layers with your background being the bottom most layer,  the track could be a layer on top of your background and your car a layer on top of the track.

 

If you add a touch listener to the car, the track and the background and you touch the car, if you're function to handle the touch does not return true, then your track will also get the touch event.  If your touch handler for your track doesn't return true, the touch will make it to the background.  Lets illustrate with some code:

 

local background = display.newImageRect("background.png", 480, 320)
 
local function bgTouch(event)
      if event.phase == "began" then
            print("background was touched")
      end
end
background:addEventListener("touch", bgTouch)
 
local track = display.newImageRect("racetrack.png", 300, 200)
 
local function trackTouch(event)
    if event.phase == "began" then
         print("track was touched")
    end
end
track:addEventListener("touch", trackTouch)
 
local car = display.newImageRect("car.png", 64, 64)
 
local function carTouch(event)
    if event.phase == "began" then
        print("car was touched")
    end
end

 

So our track sits on top of our background (and lets assume both are centered).  The car is positioned to be on the track somewhere.   As the code is written now, if you touch the background, you will get "background was touched" printed on the console log.  There is nothing under the background so the touch has no where else to go so it stops.   However, if you touch the track, you will get "track was touched" and "background was touched" because that touch event gets processed by the track handler, but the code lets it go on through the layers to the background as well.  Likewise if you touched the car, you would get "car was touched", "track was touched" and "background was touched".   This is called "Event Propagation" or "Event bubbling".

 

This can be useful at times, but most of the time it is not a desirable feature and you want to stop handling the touch with the object that was actually touched.  Look at this code:

 

local background = display.newImageRect("background.png", 480, 320)
 
local function bgTouch(event)
      if event.phase == "began" then
            print("background was touched")
      end
      return true
end
background:addEventListener("touch", bgTouch)
 
local track = display.newImageRect("racetrack.png", 300, 200)
 
local function trackTouch(event)
    if event.phase == "began" then
         print("track was touched")
    end
    return true
end
track:addEventListener("touch", trackTouch)
 
local car = display.newImageRect("car.png", 64, 64)
 
local function carTouch(event)
    if event.phase == "began" then
        print("car was touched")
    end
    return true
end

 

With the addition of the "return true" (and it's position outside of the if statement is important), then tapping the car will only result in "car was touched" being printed as the event stops there and goes no further.  If you put the "return true" inside the if statement, it would only trigger during the began phase and the other phases like "moved" and "ended" would continue to bubble through the display layers.   You may want/need for the events to bubble through,  but most of the time you do not.

 

It usually does not hurt to return true on any event handler and helps you get in a habit of doing it.

[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

lp.peralta1

[GLOBAL: userInfoPane.html]
lp.peralta1
  • Observer

  • 11 posts
  • Corona SDK

Hello everyone.

I do not have advanced knowledge in programming, so my question is: when should I use "return true" on my code.

I have seen many tutorials with it, but I don't want to just follow without knowing the reason things are there for.

Thank you very much in advance.

Best Regards,

Lucas Peralta [Chile]  :)



[TOPIC: post.html]
#2

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 26,394 posts
  • Enterprise

  Best Answer

Let me try to explain this.

 

1.  When you need to.

2.  When dealing with events, in particular touch and tap events.

 

Number 1 might seem kind of odd, but we cannot predict how you might write a function and what you might do with it.  Returning True or False from a function is a way to identify if that function was successful or not.

 

local function  isNumberPositive(someNumber)
      if someNumber < 0 then
           return false
      end
      return true
end
 
if isNumberPositive(105) then
      print("Positive")
else
      print("Negative")
end
 

 

We cannot predict how you will write functions and when you need to return what.

 

However... For things that generate touch and tap events, returning true prevents other objects from receiving an event.   Imagine if you will a racing game, your display is a series of layers with your background being the bottom most layer,  the track could be a layer on top of your background and your car a layer on top of the track.

 

If you add a touch listener to the car, the track and the background and you touch the car, if you're function to handle the touch does not return true, then your track will also get the touch event.  If your touch handler for your track doesn't return true, the touch will make it to the background.  Lets illustrate with some code:

 

local background = display.newImageRect("background.png", 480, 320)
 
local function bgTouch(event)
      if event.phase == "began" then
            print("background was touched")
      end
end
background:addEventListener("touch", bgTouch)
 
local track = display.newImageRect("racetrack.png", 300, 200)
 
local function trackTouch(event)
    if event.phase == "began" then
         print("track was touched")
    end
end
track:addEventListener("touch", trackTouch)
 
local car = display.newImageRect("car.png", 64, 64)
 
local function carTouch(event)
    if event.phase == "began" then
        print("car was touched")
    end
end

 

So our track sits on top of our background (and lets assume both are centered).  The car is positioned to be on the track somewhere.   As the code is written now, if you touch the background, you will get "background was touched" printed on the console log.  There is nothing under the background so the touch has no where else to go so it stops.   However, if you touch the track, you will get "track was touched" and "background was touched" because that touch event gets processed by the track handler, but the code lets it go on through the layers to the background as well.  Likewise if you touched the car, you would get "car was touched", "track was touched" and "background was touched".   This is called "Event Propagation" or "Event bubbling".

 

This can be useful at times, but most of the time it is not a desirable feature and you want to stop handling the touch with the object that was actually touched.  Look at this code:

 

local background = display.newImageRect("background.png", 480, 320)
 
local function bgTouch(event)
      if event.phase == "began" then
            print("background was touched")
      end
      return true
end
background:addEventListener("touch", bgTouch)
 
local track = display.newImageRect("racetrack.png", 300, 200)
 
local function trackTouch(event)
    if event.phase == "began" then
         print("track was touched")
    end
    return true
end
track:addEventListener("touch", trackTouch)
 
local car = display.newImageRect("car.png", 64, 64)
 
local function carTouch(event)
    if event.phase == "began" then
        print("car was touched")
    end
    return true
end

 

With the addition of the "return true" (and it's position outside of the if statement is important), then tapping the car will only result in "car was touched" being printed as the event stops there and goes no further.  If you put the "return true" inside the if statement, it would only trigger during the began phase and the other phases like "moved" and "ended" would continue to bubble through the display layers.   You may want/need for the events to bubble through,  but most of the time you do not.

 

It usually does not hurt to return true on any event handler and helps you get in a habit of doing it.



[TOPIC: post.html]
#3

lp.peralta1

[GLOBAL: userInfoPane.html]
lp.peralta1
  • Observer

  • 11 posts
  • Corona SDK

Dear Rob,

I really want to thank you, whenever I have asked something, you have replied me, you are really supportive.
Many topics are replied by you so I can tell that you are a great help for this community.

Now the "return true" statement is very clear for me so thank you, and I hope this thread will help more people with the same question I had 1 day ago.

 

Greetings and best regards,

Lucas Peralta [Chile]
 




[topic_controls]
[/topic_controls]