How to pan a display group with all inserted objects?

First, I have a new container. Then I added a display group within it and inserted my objects to the display group. I did this because I want to pan the display group and move all objects. But I can’t grab the display group. I then added a large graphic image in the display group and set the alpha to 0 but that did not work too well.

Does anyone know how I can do this? I’m trying to move a game board with objects all together within a container. I need them inside a container so some parts goes away when panning past the container borders. If I know how I can touch within the container to pan it then that would be great. 

Thanks,

Warren

** Note: I made some typos and fixed them. Only major fix was display.newImageRect()  (I had newImage) **

@WarrenW,

There are a number of ways to do this, so this may not be what you want, but it might lead to the answer that suits you:

  1. Create these groups:

    local layers = display.newGroup() layers.content = display.newGroup() layers.overlay = display.newGroup() layers:insert(layers.content) layers:insert(layers.overlay) – Now, the whole set can be removed by destroying ‘layers’: display.remove(layers)

  2. Add content to layers.content

    display.newCircle( layers.content, … ) display.newRect( layers.content, … ) display.newImageRect( layers.content, … ) … etc.

  3. Now add a touch object and listener to the overlay ( may be typos )

    local function onTouch( self, event ) local phase = event.phase if(phase == began) then layers.content.x1 = layers.content.x layers.content.y1 = layers.content.y – Note: You could create x0,y0 on creation so you always know the ‘home’ position – so my example uses x1,y1 to avoid future naming conflict self.dragging = false elseif( phase == “moved”) then self.dragging = true local dx = event.x - event.xStart local dy = event.y - event.yStart layers.content.x = layers.content.x1 + dx layers.content.y = layers.content.y1 + dy elseif( phase == “ended” ) then self.dragging = false end return self.dragging end – Use a transparent image file( fillT.png) (I keep a 16 x 16 one in all projects for this purpose) – local touchObj = display.newImageRect( layers.overlay, “fillT.png”, display.actualContentWidth, display.actualContentHeight ) touchObj.x = display.contentCenterX touchObj.y = display.contentCenterY touchObj.x0 = touchObj.x touchObj.y0 = touchObj.y touchObj.touch = onTouch touchObj:addEventListner( “touch” )

Done!

Thanks! My first issue is newRect does not accept an image as a parameter. I changed that to a newImage and then I get the error that it said attempt to call method “addEventListener” a nil value.

I then commented those 2 lines out and added this instead:

touchObj:addEventListener( “touch”, onTouch )

It ran and as soon as I toughed the screen it says attempt to index local ‘event’ a nil value.

Not sure what to do…

Is there any way the groups can be added in a container? I guess I need the group to be very large all the way around cause I need to pan it to the right and then drag an object on the left side to add. 

I have used this code for dragging. Any time I had the self included as a parameter to the touch event it never worked. Not sure what I am missing.

local function onTouch1( event ) local t = event.target local phase = event.phase if "began" == phase then -- Make target the top-most object local parent = t.parent parent:insert( t ) display.getCurrentStage():setFocus( t ) -- Spurious events can be sent to the target, e.g. the user presses -- elsewhere on the screen and then moves the finger over the target. -- To prevent this, we add this flag. Only when it's true will "move" -- events be sent to the target. t.isFocus = true -- Store initial position t.x0 = event.x - t.x t.y0 = event.y - t.y elseif t.isFocus then if "moved" == phase then -- Make object move (we subtract t.x0,t.y0 so that moves are -- relative to initial grab point, rather than object "snapping"). t.x = event.x - t.x0 t.y = event.y - t.y0 elseif "ended" == phase or "cancelled" == phase then t.isFocus = false display.getCurrentStage():setFocus( nil ) end end -- Important to return true. This tells the system that the event -- should not be propagated to listeners of any objects underneath. return true end
  1. You must have gotten the code from your e-mail?  I posted a correction above minutes after I originally posted and corrected the newRect() vs newImageRect() typo.

  2. You’re trying to use my listener like a function listener and missing the usage.  Compare these two pieces of code:

    – -- This is a function listener – local function onTouch( event ) print( event.target, event.phase ) end local tmp = display.newCircle( 100, 100, 100 ) tmp:addEventListener( “touch”, onTouch )

    – -- This is a table listener – local function onTouch( self, event ) print( self, event.phase ) end local tmp = display.newCircle( 100, 100, 100 ) tmp.touch = onTouch – You must do this. tmp:addEventListener( “touch” ) – No function passed. It is implied to be in the field ‘touch’

Alternately you can do this:

-- -- This is a table listener variant -- local function onTouch( self, event ) print( self, event.phase ) end local tmp = display.newCircle( 100, 100, 100 ) tmp:addEventListener( "touch", tmp ) -- No function passed. It is implied to be in the field 'touch'

Yes I did copy it from the email. I tried again and had another error still but found cause addEventListener was spelled wrong and I missed it. I fixed it and got it to run and showing the content I needed. As soon as I try to move anything by touching the screen I get an arithmetic error saying field x1 is nil on this line:

      layers.content.x = layers.content.x1 + dx

I’m not sure why cause you defined x1 in the began phase.

I got it working!

Let me play with this more tonight. Appreciate it!  I want to see if I can do any of the following:

Add more objects to the left side after dragging display to the right.

Put the display inside a container display so it is cut off parts of the screen.

Warren

You can put the ‘content’ group in a container, but leave the ‘dragObj’ (used for catching touches) out of the container so it doesn’t get clipped.

local layers = display.newGroup() layers.container = display.newContainer( layers, 100, 100 ) layers.content = display.newGroup() layers.overlay = display.newGroup() layers:insert(layers.container) layers:insert(layers.overlay) layers.container:insert(layers.content) --[[Order (top to bottom) overlay content container layers --]]

That did it! I used the additional code above and created the container where I wanted, set the anchorX/Y to 0 and works exactly like I need.

Thank you!!!

** Note: I made some typos and fixed them. Only major fix was display.newImageRect()  (I had newImage) **

@WarrenW,

There are a number of ways to do this, so this may not be what you want, but it might lead to the answer that suits you:

  1. Create these groups:

    local layers = display.newGroup() layers.content = display.newGroup() layers.overlay = display.newGroup() layers:insert(layers.content) layers:insert(layers.overlay) – Now, the whole set can be removed by destroying ‘layers’: display.remove(layers)

  2. Add content to layers.content

    display.newCircle( layers.content, … ) display.newRect( layers.content, … ) display.newImageRect( layers.content, … ) … etc.

  3. Now add a touch object and listener to the overlay ( may be typos )

    local function onTouch( self, event ) local phase = event.phase if(phase == began) then layers.content.x1 = layers.content.x layers.content.y1 = layers.content.y – Note: You could create x0,y0 on creation so you always know the ‘home’ position – so my example uses x1,y1 to avoid future naming conflict self.dragging = false elseif( phase == “moved”) then self.dragging = true local dx = event.x - event.xStart local dy = event.y - event.yStart layers.content.x = layers.content.x1 + dx layers.content.y = layers.content.y1 + dy elseif( phase == “ended” ) then self.dragging = false end return self.dragging end – Use a transparent image file( fillT.png) (I keep a 16 x 16 one in all projects for this purpose) – local touchObj = display.newImageRect( layers.overlay, “fillT.png”, display.actualContentWidth, display.actualContentHeight ) touchObj.x = display.contentCenterX touchObj.y = display.contentCenterY touchObj.x0 = touchObj.x touchObj.y0 = touchObj.y touchObj.touch = onTouch touchObj:addEventListner( “touch” )

Done!

Thanks! My first issue is newRect does not accept an image as a parameter. I changed that to a newImage and then I get the error that it said attempt to call method “addEventListener” a nil value.

I then commented those 2 lines out and added this instead:

touchObj:addEventListener( “touch”, onTouch )

It ran and as soon as I toughed the screen it says attempt to index local ‘event’ a nil value.

Not sure what to do…

Is there any way the groups can be added in a container? I guess I need the group to be very large all the way around cause I need to pan it to the right and then drag an object on the left side to add. 

I have used this code for dragging. Any time I had the self included as a parameter to the touch event it never worked. Not sure what I am missing.

local function onTouch1( event ) local t = event.target local phase = event.phase if "began" == phase then -- Make target the top-most object local parent = t.parent parent:insert( t ) display.getCurrentStage():setFocus( t ) -- Spurious events can be sent to the target, e.g. the user presses -- elsewhere on the screen and then moves the finger over the target. -- To prevent this, we add this flag. Only when it's true will "move" -- events be sent to the target. t.isFocus = true -- Store initial position t.x0 = event.x - t.x t.y0 = event.y - t.y elseif t.isFocus then if "moved" == phase then -- Make object move (we subtract t.x0,t.y0 so that moves are -- relative to initial grab point, rather than object "snapping"). t.x = event.x - t.x0 t.y = event.y - t.y0 elseif "ended" == phase or "cancelled" == phase then t.isFocus = false display.getCurrentStage():setFocus( nil ) end end -- Important to return true. This tells the system that the event -- should not be propagated to listeners of any objects underneath. return true end
  1. You must have gotten the code from your e-mail?  I posted a correction above minutes after I originally posted and corrected the newRect() vs newImageRect() typo.

  2. You’re trying to use my listener like a function listener and missing the usage.  Compare these two pieces of code:

    – -- This is a function listener – local function onTouch( event ) print( event.target, event.phase ) end local tmp = display.newCircle( 100, 100, 100 ) tmp:addEventListener( “touch”, onTouch )

    – -- This is a table listener – local function onTouch( self, event ) print( self, event.phase ) end local tmp = display.newCircle( 100, 100, 100 ) tmp.touch = onTouch – You must do this. tmp:addEventListener( “touch” ) – No function passed. It is implied to be in the field ‘touch’

Alternately you can do this:

-- -- This is a table listener variant -- local function onTouch( self, event ) print( self, event.phase ) end local tmp = display.newCircle( 100, 100, 100 ) tmp:addEventListener( "touch", tmp ) -- No function passed. It is implied to be in the field 'touch'

Yes I did copy it from the email. I tried again and had another error still but found cause addEventListener was spelled wrong and I missed it. I fixed it and got it to run and showing the content I needed. As soon as I try to move anything by touching the screen I get an arithmetic error saying field x1 is nil on this line:

      layers.content.x = layers.content.x1 + dx

I’m not sure why cause you defined x1 in the began phase.

I got it working!

Let me play with this more tonight. Appreciate it!  I want to see if I can do any of the following:

Add more objects to the left side after dragging display to the right.

Put the display inside a container display so it is cut off parts of the screen.

Warren

You can put the ‘content’ group in a container, but leave the ‘dragObj’ (used for catching touches) out of the container so it doesn’t get clipped.

local layers = display.newGroup() layers.container = display.newContainer( layers, 100, 100 ) layers.content = display.newGroup() layers.overlay = display.newGroup() layers:insert(layers.container) layers:insert(layers.overlay) layers.container:insert(layers.content) --[[Order (top to bottom) overlay content container layers --]]

That did it! I used the additional code above and created the container where I wanted, set the anchorX/Y to 0 and works exactly like I need.

Thank you!!!