Kwik Cat Puzzle

Kwik Cat Puzzle. Please down;oad a sample project in the zip

Bojan Živković made a nice Photoshop tool to create puzzle pieces. It is free and simple to use. Very good!

Let’s make a puzzle game with Kwik along with a printed jig-saw puzzle you may order from an on-demand print service.

puzzle pieces ATN

Using the puzzle pieces ATN, a layer or a layer group of .psd is divided into pieces of layers.

For the psd file of a cat driving car, a layer group is created. the canvas size is 1920 x 1280, it is the default width and hight of Ultimate Config project of Kwik4

Select 3:2 Aspect Ratio > 24 pieces(6x4), it makes 4 rows x 6 columns

a copy of the psd with A1 to D6 layers

save it and use it for the puzzle page of Kwik.


Kwik

page4_puzzle.psd is for jig-saw puzzle and page4_anim.psd shows a car animating for a reference for a user to make up the puzzle complete

preparation

please finish 002-page_anim firstly.

001-page4_puzzle

  1. create Action to go to page4_anim
  2. create Drag to make a layer of the pieces draggable. Just make it one piece draggable only.

    later we customize the lua file of drag to a layer to make the rest of 24 pieces draggable.

  3. Publish

  4. copy build4/components/page001/xxx_drag.lua to buld4/custom/components/page001/xxx_drag.lua

  5. Edit xxx_drag.lua in custom folder for making 24 pieces draggable

  6. Publish again

drag_795 is created on A1 layer

onComplete action is created

You need the two components only then publish


custom code to program the 24 pieces of a jig-saw puzzle

  1. copy build4/components/page001/xxx_drag.lua to buld4/custom/components/page001/xxx_drag.lua

  2. xxx_drag.lua is pasted in custom folder

Now we can edit xxx_drag.lua in custom folder like this. Please use a text editor app and replace the whole lines for the codes below.

you can find it in the sample zip. it is in build4/custom/components/page01 folder

Publish again. Kwik loads the modified xxx_drag.lua in custom folder.

That’s all. Enjoy!


-- Code created by Kwik - Copyright: kwiksher.com 2019
-- Version: 4.1.0
-- Project: KwikCatPuzzle
--
local _M = {}
--
local _K = require "Application"
--
local tiles    = {"A",  "B", "C", "D"}
local colNum   = 6
local rowNum   = 4
local hitCount = colNum * rowNum
local magneticMargin = 50
--
local function dragBeginEffect(obj)
  transition.to(obj, {time=500, rotation = 360*3})
end
--
local pieces = {}

-- Drag objects
function _M:didShow(UI)
  local sceneGroup = UI.scene.view
  local layer      = UI.layer
  local scene       = UI.scene

  for k, v in pairs(tiles) do
    for i=1,colNum do
      local dragLayer = layer[v..i]
      if dragLayer == nil then return end
      dragLayer.targetLayer = display.newImageRect(_K.imgDir..dragLayer.imagePath:lower(), _K.systemDir, dragLayer.width, dragLayer.height)
      dragLayer.targetLayer.x = dragLayer.x
      dragLayer.targetLayer.y = dragLayer.y
      dragLayer.targetLayer.fill.effect = "filter.emboss"
      dragLayer.targetLayer.fill.effect.intensity = 0.1
      scene.view:insert(dragLayer.targetLayer)
      table.insert(pieces, dragLayer)

      local randX = math.random(10,20)
      if randX % 2 == 0 then
        dragLayer.x = display.contentWidth -randX
      else
        dragLayer.x = randX
      end
      dragLayer.y = math.random(display.contentHeight)
      dragLayer:toFront()

      local randR = math.random(0, 360);
      dragLayer.rotation = randR
      dragLayer.oriRotation = randR

      local A1_lock = 0
      local A1_posX = 0
      local A1_posY = 0

      _K.MultiTouch.activate( dragLayer, "move", "single", {} )
        _K[v..i.."Drag"] = function (event )
          local t = event.target
          if event.phase == "began" then
            local parent = t.parent; parent:insert(t); display.getCurrentStage():setFocus(t); t.isFocus = true
            t.oriBodyType = t.bodyType
            t.bodyType ="kinematic"
            dragBeginEffect(t)
          elseif event.phase == "moved" then
            function hitTest(dropLayer)
              A1_posX = dragLayer.x - dropLayer.x
              A1_posY = dragLayer.y - dropLayer.y
              if (A1_posX < 0) then
                A1_posX = A1_posX * -1
              end
              if (A1_posY < 0) then
                A1_posY = A1_posY * -1
              end
              if (A1_posX <= magneticMargin) and (A1_posY <= magneticMargin) then  --in position\r\n'
                    dragLayer.x = dropLayer.x
                    dragLayer.y = dropLayer.y
                A1_lock = 1
              else
                A1_lock = 0
              end
            end
            hitTest(t.targetLayer)
          elseif event.phase == "ended" or event.phase == "cancelled" then
              t.bodyType = t.oriBodyType
              display.getCurrentStage():setFocus(nil); t.isFocus = false
              if (A1_lock == 1 and A1_posX <= magneticMargin) and (A1_posY <= magneticMargin) then
                t.x = t.targetLayer.x
                t.y = t.targetLayer.y
                _K.MultiTouch.deactivate(t)
                hitCount = hitCount -1
                t.hit = true
                if hitCount == 0 then
                    --native.showAlert("Kwik Puzzle", "Completed!")
                    Runtime:dispatchEvent({name=UI.page..".action_onComplete", event=event, UI=UI})
                end
              end
              for j, piece in pairs(pieces) do
                if not piece.hit  then
                  piece:toFront()
                end
              end
          end
          return true
        end
        dragLayer:addEventListener( _K.MultiTouch.MULTITOUCH_EVENT, _K[v..i.."Drag"] )

    end
  end
end
--
function _M:toDispose(UI)
  local sceneGroup = UI.scene.view
  local layer      = UI.layer
  local scene       = UI.scene
  for k, v in pairs(tiles) do
    for i=1,colNum do
      local dragLayer = layer[v..i]
        if (nil ~= dragLayer ) then
           dragLayer:removeEventListener ( _K.MultiTouch.MULTITOUCH_EVENT,  _K[v..i.."Drag"] );
        end
    end
  end
end
--
function _M:destroy()
    _K.A1Drag = nil
end
--
return _M