简体   繁体   中英

Two seperate listeners for same object Corona

I created a display group and put some items in it and added a listener for slide function that slides the display group to reach the items outside of the screen and come back. I also want to add a touch listener for those items which calls the function which drags items. So how can I achieve that without interfering those listeners with each other?

Here is the pic:

在此处输入图片说明

在此处输入图片说明

I put all those circles and numbers on blue rectangle to a display group and I added a touch event listener for that group:

ballGroup.touch=slide
ballGroup:addEventListener("touch", ballGroup) 

I also want to be able to add another touch event listener for balls:

function createBall()

        local ball = display.newCircle(x, H/2-25, 50)
        local label = display.newText(""..count, ball.x, ball.y, nil , 35)
        label:setTextColor ( 255, 0, 0 )
        ball.no = count
        ball.touch=chooseBall
        ball:addEventListener("touch", ball)
        ballGroup:insert(ball)
        ballGroup:insert(label)
        count=count+1
        x=x+120
end

However, it's just listening the event of the function that I write first. What do you suggest me to achieve what I want? When I try to slide the balls, I just want it to listen slide event and when I try to drag the balls, I want it to listen drag event. How can I do that?

Okey, I am sharing the whole code that I came up with after Rob's suggestion but it is still not working and the Outlaw IDE gives that error:

attempt to perform arithmetic on x0(nil value) and the line is where the moved phase is in the slide function.

Here is the whole code:

W=display.contentWidth
H=display.contentHeight
local ballGroup = display.newGroup()--balls and numbers will be added
local x=50 --for ball's locating
local count=1 -- little ball's number starting from 1


local rect --background rect for balls
--big circle at the bottom
local circle = display.newCircle(W/2, H-90, 70) 
local circleTxt = display.newText("", 0, 0, nil, 50 )
circleTxt:setTextColor ( 255, 0, 0 )
circleTxt.x=circle.x; circleTxt.y = circle.y


--Dragging ball and checking if  it is inside big circle if it is so, remove ball and   show the number of ball on big circle
function dragBall(self, event)
if event.phase=="began" then
    display.getCurrentStage ( ):setFocus(self,  event.id)
    self.isFocus=true
    self.x0= self.x; self.y0=self.y
elseif event.phase=="moved" then
        local dx = math.abs( event.x - event.xStart ) -- Get the x-  transition of the touch-input
        local dy = math.abs( event.y - event.yStart ) -- Get the y-transition of the touch-input
        if dy < 5 then --I changed it to less than, because if  y is bigger,then focus should stay on the ball which will be dragged 
            display.getCurrentStage():setFocus( nil )
            event.target.isFocus = false
            return false
        end           
        self.x = self.x0+(event.x-event.xStart); self.y = self.y0+(event.y-event.yStart) --drag ball
elseif event.phase=="cancelled" or event.phase=="ended" then
        checkArea(self)
        display.getCurrentStage():setFocus(self,nil)

end             
return true
end


function createBall()
local ball = display.newCircle(x, H/2-25, 50)
local label = display.newText(""..count, ball.x, ball.y, nil , 35)
label:setTextColor ( 255, 0, 0 )
ball.no = count
ball.touch=dragBall
ball:addEventListener("touch", ball)
ballGroup:insert(ball)
ballGroup:insert(label)
count=count+1
x=x+120
end


for i=1,8 do
createBall()
end


rect = display.newRect(0,0, ballGroup.width, ballGroup.height); rect.y=H/2-25
rect:setFillColor(0,0,255)
rect:toBack()

function slide(self, event)

if event.phase=="began"  then
    self.x0=self.x 
    self.y0=self.y
    display.getCurrentStage():setFocus(self, event.id)
    self.isFocus=true
elseif event.phase=="moved" then
    local dif = event.x-event.xStart

    self.x = self.x0+dif
    if ballGroup.contentBounds.xMax < W then
        ballGroup.x = ballGroup.x+(W-ballGroup.contentBounds.xMax)
    elseif ballGroup.contentBounds.xMin > 0 then
        ballGroup.x = 0
    end
elseif event.phase=="cancelled" or event.phase=="ended" then
    display.getCurrentStage():setFocus(nil)
    self.isFocus=false 
end
return true 
end

ballGroup.touch=slide
ballGroup:addEventListener("touch", ballGroup)

local bounds = circle.contentBounds
local xMax = bounds.xMax
local xMin = bounds.xMin
local yMax = bounds.yMax
local yMin = bounds.yMin

function checkArea(self)    
    if self.x>xMin and self.x<xMax and self.y>yMin and self.y<yMax then
        circleTxt.text=""..self.no
        self:removeSelf()
        self=nil
    end 

end

My Solution is put Runtime Touch Lister:

    if event.phase == "began" then
        startx = event.x

    elseif event.phase == "ended" then

        local endx = event.x
        result_postion = endx-startx
            if result_postion >50 then
                 print("right swipe")
            elseif result_postion <50 then
                  print("left swipe")
            end
     end

After Object(ball) touch Function

local function ball(event)
if event.phase == "began" then
startpos = event.x
display.getCurrentStage():setFocus(event.target)
elseif event.phase == "moved" then
endpos = event.x
result = endpos-startpos
if result<30 and result>=-30 then
print("correct")
    end
    end
end

You can have a listener on the scroll area and a listener on the circles. The handler for the circles need to test to see if the event.phase is "moved" and if you've moved say more than 5px, then you want to release the focus on the circle and return false, letting the event propogate to the underlying object.

        elseif event.phase == "moved" then -- Check if you moved your finger while touching
            local dx = math.abs( event.x - event.xStart ) -- Get the x-transition of the touch-input
            local dy = math.abs( event.y - event.yStart ) -- Get the y-transition of the touch-input
            if dx > 5 or dy > 5 then
                display.getCurrentStage():setFocus( nil )
                event.target.isFocus = false
                return false
            end
        end

or something like that.

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