Home / Uncategorized / ジグソーパズル

ジグソーパズル

Kwik Cat Puzzle のサンプルプロジェクトは以下からダウンロードできます。

Bojan Živković 氏のパズルピースの作成のフォトショップのツールを使って、ジグゾーパズルをつくることができます。無料で利用できる良くできたツールです。

Kwikでジグゾーパズルのアプリを作りましょう。また オンラインの印刷サービスで本物のジグゾーパズルを作ってくれるところもあります。

puzzle pieces ATN

パズルピース作成ツールは、フォトショップのアクションファイル(ATN)に形式のツールです。選択したレイヤーをジグソーパズルのピースとして バラバラのレイヤーにします。

サンプルプロジェクトの車に乗った猫の PSDファイルのサイズは 1920 x 1280です。これは Kwik4のデフォルトである Ultimate Config(UC @4x)のサイズです。

free-puzzle piecesのATNを開きます。そして 3:2 Aspect Ratio > 24 pieces(6x4), を選択します。これで 4行 x 6列のピースが作成されます。

作成された各ピースのレイヤーは A1 から D6 までの24個のレイヤーです。

このPSDファイルを保存して、Kwikのページに登録します。

  • page4_puzzle.psd として保存しました。

Kwikでの仕組み

page4_puzzle.psd が最初のジグゾーパズルのページです。次のpage4_anim.psdは 車に乗った猫のアニメーションのページです。

  • 001 - page4_puzzle

    • 用意されたカスタムコードを使用して、ジグソーパズルのドラッグの操作とヒットテストを実現します。
      • 各ピースのコピーを作成してエンボス
      • ピースをランダムに配置
      • ドラッグ&ドロップ
      • ヒットテスト
      • 完成時に onComplete のアクションをコール
    • onComplateのアクションは次のページ(002-page4_anim)に遷移
  • 002 - page4_anim

    • 戻るボタン 001-page4_puzzle ページに遷移
    • 車のアニメーション

準備

002-page_animの車のアニメーションページを事前に完成させておきます。

  • アニメーション 車
  • ボタン page4_puzzleに戻る

手順

001-page4_puzzleをKwikで開きます。

  1. アクションを作成。 次のページ(page4_anim )に遷移する Go To Page
  2. ドラッグを作成。カスタムコードを埋め込むLuaファイルを作成するためですので、任意のピース一つだけにドラッグのインタラクションを設定してください。

    カスタムコードは 24個のピース全てをドラッグにするコードです。

  3. Publishしてください。

  4. 先ほどドラッグを設定した Luaファイルを custom フォルダにコピーします。

    copy build4/components/page001/xxx_drag.lua buld4/custom/components/page001/xxx_drag.lua
    
  5. custom にコピーしたファイルを編集します。ファイルの内容全てを下記のコードと入れ替えます。

  6. Publish を再度行います。

drag_795を A1 レイヤーに設定

onComplete アクションを作成

  • go to page4_anim
    • flip
    • 待ち 2 秒
    • 時間 1 秒

ドラッグとアクションの2つのコンポネントを作成して、パプリッシュします。


custom code の設定

  1. build4/components/page001/xxx_drag.lua をコピーして buld4/custom/components/page001/xxx_drag.lua として配置します。

  2. xxx_drag.lua が custom/components/page01 ファルダ内に配置されました。

    この xxx_drag.lua を編集します。テキストエディターを使用して、下記のコードに入れ替えます。コード全てを入れ替えてください。保存します。

再度 KwikのPublish を行ってください。パブリッシュを行うことで カスタムコードが組み込まれます。

以上です。


-- 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

Leave a Reply

メールアドレスが公開されることはありません。 が付いている欄は必須項目です