Help with MASKS -- Please

I am creating a 4 square style puzzle app and I am in a bit of a bind.

so I have a image that has 4 mask files that work against it top left, top right, bottom left, bottom right.

i load the image 4 times and the mask item each time as well

for i=1,4,1 do  
 pzObject[i] = display.newImageRect( puzzleFile, puzzleWidth, puzzleHeight )  
 local maskFile = "mask" .. i .. ".png"  
 pzMask[i] = graphics.newMask( maskFile )  
end  

all of the above works fine and I get my four puzzle pieces…

the problem is that when dragging the object around on the screen they pieces seem to jump of the screen when I touch them…

In the moved phase i do the following code.
I have tested this agains 1 object and it worked fine.

if(event.phase == "moved" and target.isSelected == true) then   
 target.x = x; target.y = y   
end  

any help would make me a very happy boy.

thanks

Larry
[import]uid: 11860 topic_id: 35345 reply_id: 335345[/import]

Not entirely sure what could be causing the problem, but if you can post the full code (only relevant parts, but demonstrating the problem) it would help.

I do notice that, if you’re using the masks to make the main image into smaller pieces, then you probably don’t need four masks, but without knowing how you’re applying them its hard to tell. [import]uid: 8271 topic_id: 35345 reply_id: 140468[/import]

The entire code is below in the code block.
The source code and images / masks are in the zip file.

http://www.doubleslashdesign.com/downloads/mask4test.zip
thanks in advance Larry

[code]
–***********************************************************************************************–
–***********************************************************************************************–

local screenGroup = display.newGroup()

local halfW = display.contentCenterX
local halfH = display.contentCenterY
local puzzleLeft =300 ; puzzleTop=300
local bgRect;
local isSelected = false; – Global and object levels to prevent multiple object collisions

local function main()

local i
local puzzleGroup = display.newGroup()
local puzzleFile=“pic.png”;

local pzObject = {} --Holds each puzzle piece
local pzMask = {}

local puzzleWidth=500; puzzleHeight=500;

bgRect = display.newRect( puzzleGroup, 0, 0, display.contentWidth, display.contentHeight )
bgRect:setFillColor( 0, 0, 0, 255 )
bgRect.alpha = 0
bgRect.isVisible = false

for i=1,4,1 do
pzObject[i] = display.newImageRect( puzzleFile, puzzleWidth, puzzleHeight )

pzObject[i].id=i; pzObject[i].isSelected=false;

puzzleGroup:insert( pzObject[i] )

pzObject[i].x = puzzleLeft; pzObject[i].y = puzzleTop;

– SET MASK
local maskFile = “masks/mask” … i … “.png”
pzMask[i] = graphics.newMask( maskFile )
pzObject[i]:setMask( pzMask[i] )

pzObject[i].isHitTestMasked = true --prevent transparent pixel touch

pzObject[i]:setReferencePoint( display.CenterReferencePoint )

–***********************************************************************************************
– TOUCH / MOVE
–***********************************************************************************************
local touchPz = function( event )

– Tip: For all but the simplest cases, it is best to extract the values you need from ‘event’ into local variables.
local phase = event.phase
local target = event.target
local x = event.x
local y = event.y

print(“phase–>” …phase)
print(“target.id–>” …target.id)

if not isSelected and event.phase == “began” then
target.isSelected = true; isSelected = true;
target:toFront()

elseif(event.phase == “moved” and target.isSelected == true) then
target.x = x; target.y = y

elseif event.phase == “ended” then
target.isSelected = false; isSelected = false;
end
end

pzObject[i]:addEventListener( “touch”, touchPz )
end

end

main()
[/code] [import]uid: 11860 topic_id: 35345 reply_id: 140474[/import]

So the x,y coordinate is the center of the dragged image, right?

If the original image is being used as 4 quadrants (the subimages are at top left, top right, bottom left and bottom right), then when you touch your finger in the bottom right, and then you use a masked copy of the larger image and display it at that point, you are referring to the center point of the new image… So it will appear at the bottom right of your finger (possibly offscreen even).

So a tap on the piece on the top left will cause that piece to shoot off to the top and left, a tap on the top right will cause that image to appear off the top right, etc… (because your finger is pointing at the center of the entire image, not the part you are masking…)

You need to do some coordinate translating to make your configuration work properly… Something like subtracting the users INITIAL tap x,y coord from the original image centerpoint, and then use that value to offset the current users finger position so the masked image lines up properly…

Without a whiteboard, I’m never gonna be able to 'splain this… Oh well… [import]uid: 79933 topic_id: 35345 reply_id: 140481[/import]

I kind of understand what your talking about, just not 100% sure exactly

your saying to do something like this.

[code]
elseif(event.phase == “moved” and target.isSelected == true) then
–target.x = x; target.y = y

local moveX = pzObject[target.id].x - x;
local moveY = pzObject[target.id].y - y;
target.x = moveX
target.y = moveY
[/code] [import]uid: 11860 topic_id: 35345 reply_id: 140485[/import]

Uhh, kind of… The key is that your finger is pointing not at the puzzle piece, but the center of the image being dragged… So you need to offset for that…

So maybe something like…

[code]
– At the top of your code, add these two globals which remember the original touch offsets…
local tapXOffset = 0
local tapYOffset = 0

– In your touch handler, try something like:

if not isSelected and event.phase == “began” then
target.isSelected = true; isSelected = true;
target:toFront()
tapXOffset = x - target.x
tapYOffset = y - target.y
print(" – x,y offset == ", tapXOffset, tapYOffset)

elseif(event.phase == “moved” and target.isSelected == true) then
target.x = x - tapXOffset; target.y = y - tapYOffset
[/code] [import]uid: 79933 topic_id: 35345 reply_id: 140486[/import]

I guess I’ll have to keep messing with it.

masked item still jumps a good bit off the screen.

I get what you’re saying and I agree, but not sure this it the exactly solution to fix the issue.

I know it has something to do the Mas and the offset, but not sure what.

Larry [import]uid: 11860 topic_id: 35345 reply_id: 140493[/import]

I just tried it, using your code, and it seemed to work fine for me… When I touch a piece, it doesn’t even jump a pixel, and drags around pretty well. Drop it anywhere, it drops properly (doesn’t jump). Pick it back up from there, and it doesn’t jump a pixel, moves nicely.

[code]
–***********************************************************************************************–
–***********************************************************************************************–

local screenGroup = display.newGroup()

local halfW = display.contentCenterX
local halfH = display.contentCenterY
local puzzleLeft =300 ; puzzleTop=300
local bgRect;
local isSelected = false; – Global and object levels to prevent multiple object collisions
local tapXOffset = 0
local tapYOffset = 0

local function main()

local i
local puzzleGroup = display.newGroup()
local puzzleFile=“pic.png”;

local pzObject = {} --Holds each puzzle piece
local pzMask = {}

local puzzleWidth=500; puzzleHeight=500;

bgRect = display.newRect( puzzleGroup, 0, 0, display.contentWidth, display.contentHeight )
bgRect:setFillColor( 0, 0, 0, 255 )
bgRect.alpha = 0
bgRect.isVisible = false

for i=1,4,1 do
pzObject[i] = display.newImageRect( puzzleFile, puzzleWidth, puzzleHeight )

pzObject[i].id=i; pzObject[i].isSelected=false;

puzzleGroup:insert( pzObject[i] )

pzObject[i].x = puzzleLeft; pzObject[i].y = puzzleTop;

– SET MASK
local maskFile = “masks/mask” … i … “.png”
pzMask[i] = graphics.newMask( maskFile )
pzObject[i]:setMask( pzMask[i] )

pzObject[i].isHitTestMasked = true --prevent transparent pixel touch

pzObject[i]:setReferencePoint( display.CenterReferencePoint )

–***********************************************************************************************
– TOUCH / MOVE
–***********************************************************************************************
local touchPz = function( event )

– Tip: For all but the simplest cases, it is best to extract the values you need from ‘event’ into local variables.
local phase = event.phase
local target = event.target
local x = event.x
local y = event.y

print(“phase–>” …phase)
print(“target.id–>” …target.id)

if not isSelected and event.phase == “began” then
target.isSelected = true; isSelected = true;
target:toFront()
tapXOffset = x - target.x
tapYOffset = y - target.y
print(" – x,y offset == ", tapXOffset, tapYOffset)

elseif(event.phase == “moved” and target.isSelected == true) then
target.x = x - tapXOffset; target.y = y - tapYOffset

elseif event.phase == “ended” then
target.isSelected = false; isSelected = false;
end
end

pzObject[i]:addEventListener( “touch”, touchPz )
end

end

main()

[/code] [import]uid: 79933 topic_id: 35345 reply_id: 140495[/import]

I just copied and pasted your version above into mine and - PERFECT… your a life saver…

But sure what I did wron before but i’m good to go now.

thanks so much for th help.

I owe you a cold one - or maybe two :slight_smile:

Larry [import]uid: 11860 topic_id: 35345 reply_id: 140496[/import]

Not entirely sure what could be causing the problem, but if you can post the full code (only relevant parts, but demonstrating the problem) it would help.

I do notice that, if you’re using the masks to make the main image into smaller pieces, then you probably don’t need four masks, but without knowing how you’re applying them its hard to tell. [import]uid: 8271 topic_id: 35345 reply_id: 140468[/import]

The entire code is below in the code block.
The source code and images / masks are in the zip file.

http://www.doubleslashdesign.com/downloads/mask4test.zip
thanks in advance Larry

[code]
–***********************************************************************************************–
–***********************************************************************************************–

local screenGroup = display.newGroup()

local halfW = display.contentCenterX
local halfH = display.contentCenterY
local puzzleLeft =300 ; puzzleTop=300
local bgRect;
local isSelected = false; – Global and object levels to prevent multiple object collisions

local function main()

local i
local puzzleGroup = display.newGroup()
local puzzleFile=“pic.png”;

local pzObject = {} --Holds each puzzle piece
local pzMask = {}

local puzzleWidth=500; puzzleHeight=500;

bgRect = display.newRect( puzzleGroup, 0, 0, display.contentWidth, display.contentHeight )
bgRect:setFillColor( 0, 0, 0, 255 )
bgRect.alpha = 0
bgRect.isVisible = false

for i=1,4,1 do
pzObject[i] = display.newImageRect( puzzleFile, puzzleWidth, puzzleHeight )

pzObject[i].id=i; pzObject[i].isSelected=false;

puzzleGroup:insert( pzObject[i] )

pzObject[i].x = puzzleLeft; pzObject[i].y = puzzleTop;

– SET MASK
local maskFile = “masks/mask” … i … “.png”
pzMask[i] = graphics.newMask( maskFile )
pzObject[i]:setMask( pzMask[i] )

pzObject[i].isHitTestMasked = true --prevent transparent pixel touch

pzObject[i]:setReferencePoint( display.CenterReferencePoint )

–***********************************************************************************************
– TOUCH / MOVE
–***********************************************************************************************
local touchPz = function( event )

– Tip: For all but the simplest cases, it is best to extract the values you need from ‘event’ into local variables.
local phase = event.phase
local target = event.target
local x = event.x
local y = event.y

print(“phase–>” …phase)
print(“target.id–>” …target.id)

if not isSelected and event.phase == “began” then
target.isSelected = true; isSelected = true;
target:toFront()

elseif(event.phase == “moved” and target.isSelected == true) then
target.x = x; target.y = y

elseif event.phase == “ended” then
target.isSelected = false; isSelected = false;
end
end

pzObject[i]:addEventListener( “touch”, touchPz )
end

end

main()
[/code] [import]uid: 11860 topic_id: 35345 reply_id: 140474[/import]

So the x,y coordinate is the center of the dragged image, right?

If the original image is being used as 4 quadrants (the subimages are at top left, top right, bottom left and bottom right), then when you touch your finger in the bottom right, and then you use a masked copy of the larger image and display it at that point, you are referring to the center point of the new image… So it will appear at the bottom right of your finger (possibly offscreen even).

So a tap on the piece on the top left will cause that piece to shoot off to the top and left, a tap on the top right will cause that image to appear off the top right, etc… (because your finger is pointing at the center of the entire image, not the part you are masking…)

You need to do some coordinate translating to make your configuration work properly… Something like subtracting the users INITIAL tap x,y coord from the original image centerpoint, and then use that value to offset the current users finger position so the masked image lines up properly…

Without a whiteboard, I’m never gonna be able to 'splain this… Oh well… [import]uid: 79933 topic_id: 35345 reply_id: 140481[/import]

I kind of understand what your talking about, just not 100% sure exactly

your saying to do something like this.

[code]
elseif(event.phase == “moved” and target.isSelected == true) then
–target.x = x; target.y = y

local moveX = pzObject[target.id].x - x;
local moveY = pzObject[target.id].y - y;
target.x = moveX
target.y = moveY
[/code] [import]uid: 11860 topic_id: 35345 reply_id: 140485[/import]

Uhh, kind of… The key is that your finger is pointing not at the puzzle piece, but the center of the image being dragged… So you need to offset for that…

So maybe something like…

[code]
– At the top of your code, add these two globals which remember the original touch offsets…
local tapXOffset = 0
local tapYOffset = 0

– In your touch handler, try something like:

if not isSelected and event.phase == “began” then
target.isSelected = true; isSelected = true;
target:toFront()
tapXOffset = x - target.x
tapYOffset = y - target.y
print(" – x,y offset == ", tapXOffset, tapYOffset)

elseif(event.phase == “moved” and target.isSelected == true) then
target.x = x - tapXOffset; target.y = y - tapYOffset
[/code] [import]uid: 79933 topic_id: 35345 reply_id: 140486[/import]

I guess I’ll have to keep messing with it.

masked item still jumps a good bit off the screen.

I get what you’re saying and I agree, but not sure this it the exactly solution to fix the issue.

I know it has something to do the Mas and the offset, but not sure what.

Larry [import]uid: 11860 topic_id: 35345 reply_id: 140493[/import]

I just tried it, using your code, and it seemed to work fine for me… When I touch a piece, it doesn’t even jump a pixel, and drags around pretty well. Drop it anywhere, it drops properly (doesn’t jump). Pick it back up from there, and it doesn’t jump a pixel, moves nicely.

[code]
–***********************************************************************************************–
–***********************************************************************************************–

local screenGroup = display.newGroup()

local halfW = display.contentCenterX
local halfH = display.contentCenterY
local puzzleLeft =300 ; puzzleTop=300
local bgRect;
local isSelected = false; – Global and object levels to prevent multiple object collisions
local tapXOffset = 0
local tapYOffset = 0

local function main()

local i
local puzzleGroup = display.newGroup()
local puzzleFile=“pic.png”;

local pzObject = {} --Holds each puzzle piece
local pzMask = {}

local puzzleWidth=500; puzzleHeight=500;

bgRect = display.newRect( puzzleGroup, 0, 0, display.contentWidth, display.contentHeight )
bgRect:setFillColor( 0, 0, 0, 255 )
bgRect.alpha = 0
bgRect.isVisible = false

for i=1,4,1 do
pzObject[i] = display.newImageRect( puzzleFile, puzzleWidth, puzzleHeight )

pzObject[i].id=i; pzObject[i].isSelected=false;

puzzleGroup:insert( pzObject[i] )

pzObject[i].x = puzzleLeft; pzObject[i].y = puzzleTop;

– SET MASK
local maskFile = “masks/mask” … i … “.png”
pzMask[i] = graphics.newMask( maskFile )
pzObject[i]:setMask( pzMask[i] )

pzObject[i].isHitTestMasked = true --prevent transparent pixel touch

pzObject[i]:setReferencePoint( display.CenterReferencePoint )

–***********************************************************************************************
– TOUCH / MOVE
–***********************************************************************************************
local touchPz = function( event )

– Tip: For all but the simplest cases, it is best to extract the values you need from ‘event’ into local variables.
local phase = event.phase
local target = event.target
local x = event.x
local y = event.y

print(“phase–>” …phase)
print(“target.id–>” …target.id)

if not isSelected and event.phase == “began” then
target.isSelected = true; isSelected = true;
target:toFront()
tapXOffset = x - target.x
tapYOffset = y - target.y
print(" – x,y offset == ", tapXOffset, tapYOffset)

elseif(event.phase == “moved” and target.isSelected == true) then
target.x = x - tapXOffset; target.y = y - tapYOffset

elseif event.phase == “ended” then
target.isSelected = false; isSelected = false;
end
end

pzObject[i]:addEventListener( “touch”, touchPz )
end

end

main()

[/code] [import]uid: 79933 topic_id: 35345 reply_id: 140495[/import]

I just copied and pasted your version above into mine and - PERFECT… your a life saver…

But sure what I did wron before but i’m good to go now.

thanks so much for th help.

I owe you a cold one - or maybe two :slight_smile:

Larry [import]uid: 11860 topic_id: 35345 reply_id: 140496[/import]