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.