First I must say, “I love questions like this because answering them is so much fun!”
Corona SDK is quite powerful and easy to use and it especially shines when implementing basic visuals + mechanics like this.
In this case, there are many possible answers to your question, but I’ll go for a simple solution to demonstrate my prior statements.
Using the SSK sampler, and basic Corona SDK code (no SSK special stuff) I did the following:
-
Took an image off my drive and sliced it into 3 by 3 segments using PaintShopPro.
-
Wrote some Corona Code to:
a. Lay the puzzle out in the solved position.
b. Store pertinent data regarding the solved and last positions of the tiles.
c. Make some rectangles to act as outlines of the images
d. Add a touch function to each tile
- The touch code handles the drag-n-drop functionality I need to move puzzle piecens
e. Swizzle the board. i.e. Rearranged the board.
-
Wrote some code to handle the drop calculation. This code basically tests to see if I’m dropping the tile over another tile and if I’m ‘close enough’ to the center of the tile to swap places. If I am the tiles swap positions. If not, the tile I’m dragging moves back to its last position.
-
Wrote some code to see if the puzzle was solved. This code iterates over the table of pieces and compares each piece’s current position to the initial solved position (before the swizzle). If all of the pieces are in their original locations, this code hides the outlines and removes all of the touch listeners.
Here is a video of the final results: http://www.youtube.com/watch?v=gFDAjtjfAJY
Here is the code I wrote:
local puzzleTable
local currentDragPiece
local createPuzzle
local doDrop
local swizzlePuzzle
local testCompleted
createPuzzle = function ( )
local offsetX = centerX - 106
local offsetY = centerY - 80
puzzleTable = {}
for x = 1, 3 do
for y = 1, 3 do
-- EFM you need your own puzzle pieces if you want to try this
local piece = display.newImageRect( imagesDir .. "forumHelp/puzzle/puzzleBase\_" .. y .. "x" .. x .. ".jpg", 106, 80)
local outline = display.newRect( 0, 0, 106, 80)
piece.myOutline = outline
piece.x = (x - 1) \* 106 + offsetX
piece.y = (y - 1) \* 80 + offsetY
piece.startX = piece.x
piece.startY = piece.y
piece.lastX = piece.x
piece.lastY = piece.y
outline.x = piece.x
outline.y = piece.y
outline:setFillColor(0,0,0,0)
outline.strokeWidth = 3
outline:setStrokeColor(255,255,255)
function piece:touch( event )
local target = event.target
if( event.phase == "began" ) then
target:toFront()
target.myOutline:toFront()
currentDragPiece = target
return true
elseif( event.phase == "moved" and target == currentDragPiece ) then
currentDragPiece.x = event.x - event.xStart + currentDragPiece.lastX
currentDragPiece.y = event.y - event.yStart + currentDragPiece.lastY
currentDragPiece.myOutline.x = currentDragPiece.x
currentDragPiece.myOutline.y = currentDragPiece.y
return true
elseif( event.phase == "ended" and target == currentDragPiece ) then
doDrop( target, 20 )
testCompleted()
end
end
piece:addEventListener( "touch", piece )
puzzleTable[#puzzleTable+1] = piece
end
end
end
doDrop = function ( curPiece, snapDist )
local snapDistSquared = snapDist \* snapDist
for i = 1, #puzzleTable do
local piece = puzzleTable[i]
if(piece ~= curPiece) then
local dx = piece.x - curPiece.x
local dy = piece.y - curPiece.y
local lengthSquared = dx \* dx + dy \* dy
print(lengthSquared, snapDistSquared)
if( lengthSquared \<= snapDistSquared ) then
curPiece.x = piece.x
curPiece.y = piece.y
piece.x = curPiece.lastX
piece.y = curPiece.lastY
curPiece.lastX = curPiece.x
curPiece.lastY = curPiece.y
piece.lastX = piece.x
piece.lastY = piece.y
curPiece.myOutline.x = curPiece.x
curPiece.myOutline.y = curPiece.y
piece.myOutline.x = piece.x
piece.myOutline.y = piece.y
return true
end
end
end
curPiece.x = curPiece.lastX
curPiece.y = curPiece.lastY
curPiece.myOutline.x = curPiece.x
curPiece.myOutline.y = curPiece.y
end
swizzlePuzzle = function ( )
for i = 1, 100 do
local pieceA = puzzleTable[math.random(1, #puzzleTable)]
local pieceB = puzzleTable[math.random(1, #puzzleTable)]
if(pieceB ~= pieceA) then
pieceA.x = pieceB.x
pieceA.y = pieceB.y
pieceB.x = pieceA.lastX
pieceB.y = pieceA.lastY
pieceA.lastX = pieceA.x
pieceA.lastY = pieceA.y
pieceB.lastX = pieceB.x
pieceB.lastY = pieceB.y
pieceA.myOutline.x = pieceA.x
pieceA.myOutline.y = pieceA.y
pieceB.myOutline.x = pieceB.x
pieceB.myOutline.y = pieceB.y
end
end
end
testCompleted = function ()
for i = 1, #puzzleTable do
local piece = puzzleTable[i]
if( piece.x ~= piece.startX or piece.y ~= piece.startY ) then
return false
end
end
for i = 1, #puzzleTable do
local piece = puzzleTable[i]
piece.myOutline.isVisible = false
piece:removeEventListener( "touch", piece.touch )
end
return true
end
createPuzzle()
swizzlePuzzle()
Note: This code probably won’t work right ‘out-of-the-box’, but it will be close. Regardless, I hope this helps get you started!
Note2: The entire demo has been uploaded to SSK so you can download it and look at the sampler if you want. I warning however, SSK and the sampler are still very messy. I’m reorganizing, adding features, and working on docs now.
Cheers,
Ed
Roaming Gamer, LLC.
SSK for Corona SDK (github) (videos)
[import]uid: 110228 topic_id: 32243 reply_id: 128328[/import]