How to detect number of touch points?

This code is from the forum, I’ve been doing this on/off and it’s been quite a while since last time I coded…

What I wanted to know is how to detect how many fingers touch the screen?

[lua]

system.activate(“multitouch”)

local group = display.newGroup()

local background = display.newRect(group, 0, 0, display.contentWidth, display.contentHeight)

      background:setFillColor(123, 223, 156, 255)

local touchText = display.newText(group, “”, display.contentWidth*0.5, 50, 0, 0, “Helvetica”, 24)      

local function onObjectTouch(self, event )

    if event.phase == “began” then

        print(“Touch began”)

        – specify the global touch focus

        display.getCurrentStage():setFocus( self )

        self.isFocus = true

    elseif self.isFocus then

            – do something here; or not

        if event.phase == “moved” then

            print(“Touch moved”)

        elseif event.phase == “ended” or event.phase == “cancelled” then

            print(“Touch ended or cancelled”)

            – reset global touch focus

            display.getCurrentStage():setFocus( nil )

            self.isFocus = nil

        end

    end

    return true

end

background.touch = onObjectTouch

background:addEventListener(“touch”, background)

[/lua]

If you look in the sample code at the Multi-touch example, it should have comments and examples how to determine that information.

If you look in the sample code at the Multi-touch example, it should have comments and examples how to determine that information.

Thanks Rob,

Getting the number of points was dead easy thanks to great sample code!

But I noticed that if I have three( or any number but at least 2  ) fingers touching screen then lift one off the code set touches to 0 points. If I then press a finger again the fingers left on screen does not get detected. Should I have some sort of listener in the moved phase for keeping track if there are still fingers touching?

[lua]

system.activate(“multitouch”)

local group = display.newGroup()

local background = display.newRect(group, 0, 0, display.contentWidth, display.contentHeight)

      background:setFillColor(223, 223, 156, 255)

local touchText = display.newText(group, “0”, 0, 0, 0, 0, “Helvetica”, 80)    

      touchText:setReferencePoint(display.CenterReferencePoint)

      touchText.x = display.contentWidth - 50

      touchText.y = 60

      touchText:setTextColor(0)

local function calculateDelta( previousTouches, event )

    local id,touch = next( previousTouches )

    if event.id == id then

        id,touch = next( previousTouches, id )

        assert( id ~= event.id )

    end

    local dx = touch.x - event.x

    local dy = touch.y - event.y

    return dx, dy

end

local function onObjectTouch(self, event )

    local previousTouches = self.previousTouches

    local numTotalTouches = 1

    if ( previousTouches ) then

        – add in total from previousTouches, subtract one if event is already in the array

        numTotalTouches = numTotalTouches + self.numPreviousTouches

        if previousTouches[event.id] then

            numTotalTouches = numTotalTouches - 1

        end

    end

    if event.phase == “began” then

        if ( not self.isFocus ) then

            – Subsequent touch events will target button even if they are outside the contentBounds of button

            display.getCurrentStage():setFocus( self )

            self.isFocus = true

            previousTouches = {}

            self.previousTouches = previousTouches

            self.numPreviousTouches = 0

        elseif ( not self.distance ) then

            local dx,dy

            if previousTouches and ( numTotalTouches ) >= 2 then

                dx,dy = calculateDelta( previousTouches, event )

            end

            – initialize to distance between two touches

            if ( dx and dy ) then

                local d = math.sqrt( dx*dx + dy*dy )

                if ( d > 0 ) then

                    self.distance = d

                    --self.xScaleOriginal = self.xScale

                    --self.yScaleOriginal = self.yScale

                    print( "distance = " … self.distance )

                end

            end

        end

        if not previousTouches[event.id] then

            self.numPreviousTouches = self.numPreviousTouches + 1

        end

        previousTouches[event.id] = event

        

        – touchText update

        touchText.text = self.numPreviousTouches

    elseif self.isFocus then

            – do something here; or not

        if event.phase == “moved” then

            print("—> Touch moved")

            if ( self.distance ) then

                local dx,dy

                if previousTouches and ( numTotalTouches ) >= 2 then

                    dx,dy = calculateDelta( previousTouches, event )

                end

    

                if ( dx and dy ) then

                    local newDistance = math.sqrt( dx*dx + dy*dy )

                    local scale = newDistance / self.distance

                    print( “newDistance(” …newDistance … “) / distance(” … self.distance … “) = scale(”…  scale …")" )

                    if ( scale > 0 ) then

                        --self.xScale = self.xScaleOriginal * scale

                        --self.yScale = self.yScaleOriginal * scale

                    end

                end

            end

            if not previousTouches[event.id] then

                self.numPreviousTouches = self.numPreviousTouches + 1

            end

            previousTouches[event.id] = event

            – touchText update

            touchText.text = self.numPreviousTouches

        elseif event.phase == “ended” or event.phase == “cancelled” then

            print("—> Touch ended or cancelled")

            if previousTouches[event.id] then

                self.numPreviousTouches = self.numPreviousTouches - 1

                previousTouches[event.id] = nil

            end

            if ( #previousTouches > 0 ) then

                – must be at least 2 touches remaining to pinch/zoom

                self.distance = nil

            else

                – previousTouches is empty so no more fingers are touching the screen

                – Allow touch events to be sent normally to the objects they “hit”

                display.getCurrentStage():setFocus( nil )

                self.isFocus = false

                self.distance = nil

                self.xScaleOriginal = nil

                self.yScaleOriginal = nil

               

               – Reset touchText

               touchText.text = 0

                

                – reset array

                self.previousTouches = nil

                self.numPreviousTouches = nil

            end

        end

    end

    return true

end

background.touch = onObjectTouch

background:addEventListener(“touch”, background)

[/lua]

Thanks Rob,

Getting the number of points was dead easy thanks to great sample code!

But I noticed that if I have three( or any number but at least 2  ) fingers touching screen then lift one off the code set touches to 0 points. If I then press a finger again the fingers left on screen does not get detected. Should I have some sort of listener in the moved phase for keeping track if there are still fingers touching?

[lua]

system.activate(“multitouch”)

local group = display.newGroup()

local background = display.newRect(group, 0, 0, display.contentWidth, display.contentHeight)

      background:setFillColor(223, 223, 156, 255)

local touchText = display.newText(group, “0”, 0, 0, 0, 0, “Helvetica”, 80)    

      touchText:setReferencePoint(display.CenterReferencePoint)

      touchText.x = display.contentWidth - 50

      touchText.y = 60

      touchText:setTextColor(0)

local function calculateDelta( previousTouches, event )

    local id,touch = next( previousTouches )

    if event.id == id then

        id,touch = next( previousTouches, id )

        assert( id ~= event.id )

    end

    local dx = touch.x - event.x

    local dy = touch.y - event.y

    return dx, dy

end

local function onObjectTouch(self, event )

    local previousTouches = self.previousTouches

    local numTotalTouches = 1

    if ( previousTouches ) then

        – add in total from previousTouches, subtract one if event is already in the array

        numTotalTouches = numTotalTouches + self.numPreviousTouches

        if previousTouches[event.id] then

            numTotalTouches = numTotalTouches - 1

        end

    end

    if event.phase == “began” then

        if ( not self.isFocus ) then

            – Subsequent touch events will target button even if they are outside the contentBounds of button

            display.getCurrentStage():setFocus( self )

            self.isFocus = true

            previousTouches = {}

            self.previousTouches = previousTouches

            self.numPreviousTouches = 0

        elseif ( not self.distance ) then

            local dx,dy

            if previousTouches and ( numTotalTouches ) >= 2 then

                dx,dy = calculateDelta( previousTouches, event )

            end

            – initialize to distance between two touches

            if ( dx and dy ) then

                local d = math.sqrt( dx*dx + dy*dy )

                if ( d > 0 ) then

                    self.distance = d

                    --self.xScaleOriginal = self.xScale

                    --self.yScaleOriginal = self.yScale

                    print( "distance = " … self.distance )

                end

            end

        end

        if not previousTouches[event.id] then

            self.numPreviousTouches = self.numPreviousTouches + 1

        end

        previousTouches[event.id] = event

        

        – touchText update

        touchText.text = self.numPreviousTouches

    elseif self.isFocus then

            – do something here; or not

        if event.phase == “moved” then

            print("—> Touch moved")

            if ( self.distance ) then

                local dx,dy

                if previousTouches and ( numTotalTouches ) >= 2 then

                    dx,dy = calculateDelta( previousTouches, event )

                end

    

                if ( dx and dy ) then

                    local newDistance = math.sqrt( dx*dx + dy*dy )

                    local scale = newDistance / self.distance

                    print( “newDistance(” …newDistance … “) / distance(” … self.distance … “) = scale(”…  scale …")" )

                    if ( scale > 0 ) then

                        --self.xScale = self.xScaleOriginal * scale

                        --self.yScale = self.yScaleOriginal * scale

                    end

                end

            end

            if not previousTouches[event.id] then

                self.numPreviousTouches = self.numPreviousTouches + 1

            end

            previousTouches[event.id] = event

            – touchText update

            touchText.text = self.numPreviousTouches

        elseif event.phase == “ended” or event.phase == “cancelled” then

            print("—> Touch ended or cancelled")

            if previousTouches[event.id] then

                self.numPreviousTouches = self.numPreviousTouches - 1

                previousTouches[event.id] = nil

            end

            if ( #previousTouches > 0 ) then

                – must be at least 2 touches remaining to pinch/zoom

                self.distance = nil

            else

                – previousTouches is empty so no more fingers are touching the screen

                – Allow touch events to be sent normally to the objects they “hit”

                display.getCurrentStage():setFocus( nil )

                self.isFocus = false

                self.distance = nil

                self.xScaleOriginal = nil

                self.yScaleOriginal = nil

               

               – Reset touchText

               touchText.text = 0

                

                – reset array

                self.previousTouches = nil

                self.numPreviousTouches = nil

            end

        end

    end

    return true

end

background.touch = onObjectTouch

background:addEventListener(“touch”, background)

[/lua]