Updates from Kwik4 to Kwik5

What are udated from Kwik4 to Kwik5?

Kwik Project File

  • location

    the images and lua files of a psd are published under App folder

    kwik4kwik5
    ~/Documents/Kwik/{{Project Name}}{{anonymous}}
    ~/Documents/Kwik/{{Project Name}}/*.psd{{anonymous}}/Photoshop/{{Book Name}}//*.psd
    ~/Documents/Kwik/{{Project Name}}/build4{{anonymous}}/Solar2D
    ~/Documents/Kwik/{{Project Name}}/build4/assets/images{{anonymous}}/Solar2D/App/{{Book Name}}/assets/images
    ~/Documents/Kwik/{{Project Name}}/build4/components/{{Page}}{{anonymous}}/Solar2D/App/{{Book Name}}/components/{{Page}}

Exporter in Photoshop

  • Photsohop Files > Open button

    kwik4kwik5
    the psd files are under ~/Documents/Kwik/{{Project Name}} folder. Automatically they are listedPlease choose a folder that has the psf files with Open button
  • Solar2D Project > Select Book

    kwik4kwik5
    under build4 folder and no choice was availablePlease choose a folder with Select Book button where to publish images of a PSD in Solar2D project
    • Publish

      it pareses .psd and generates images/lua files of Solar2D project into App/book folder

    • Load Simulator (only mac)

      due to UXP specification, Solar2D simulator is not automatically loaded in Windows.

      For Windows users, please use Show Folder button which opens Solar2D project folder in File Explorer,then click “startSoar2D.bat” file to open Solar2D simulator.

    • Active Document > Export Code or Export Images

      it publishes the images/lua files from the active document only.

    • Validate Names: layer names in Japanese Kana

      • symbols are converted to ‘_’
      • ‘レイヤー 1’ is converted to ‘reiya_1’
    • Layer Groups: publish images of a nested layer group.


Project structure in Detail

  • Book > page( a psd) > layer

    names of psd files are used to create releated lua files.

    It was fixed like page01, page02 .. in kwik4


    kwik4kwik5
    pageOne.psd is refered to “page01”
    - assets/images/p1
    - components/page01
    - commands/page01
    - views/page01Scene.lua.
    pageOne.psd is “pageOne”
    - assets/images/pageOne
    - components/pageOne
    - commands/pageOne
    - components/pageOne/index.lua
  • dist folder

    kwik4kwik5
    build4
    - assets/images/p1
    - components/page01
    - commands/page01
    - views/page01Scene.lua.
    App/{bookName}
    - assets/images/pageOne
    - components/pageOne
    - commands/pageOne
    - components/pageOne/index.lua

    commands/common
    components/common
    components/bookstore

    bookshelf is renamed to bookstore that is an enhancement of the kwik4’s bookshefl imlementation (it was provided with kwikshelf.plugin)


Editor in Solar2D

kwik editor enables a no-code/low-code editing. It would be better to underestand what codes are generated by kwik editor, sometimes it is quicker just edting or adding snipets of codes into .lua files.

main.lua

  • main.lua

    you can load a book project with the following code.

    require("controller.index").bootstrap{
      name="book",
      editing = true,
      goPage = "page1",
      position = {x=0, y=0},
      common = common}
    • editing

      it should be false for your production release or building app for device

App/book/index.lua

the pages are defined in App/{{Book Name}}/index.lua

Kwik4 had .kwk xml to hold a properties/values of a Kwik project. Kwik5 uses .lua

  • App/{bookName}/index.lua

    local scenes = {
      "page1",
      "page2",
      "yourPageName"
    }
    return scenes
    • you can change the order of pages in scenes table
    • A developer may add your own(custom) page to the index.lua

Page Index - components/page/index.lua

  • App/{bookName}/components/{pageName}/index.lua

    These are the two main tables

    • components
    • commands

components > layers

the layers form photoshop(images) and other resouces are indexed

page sceneName = ...
--
local scene = require('controller.scene'page(sceneName, {
    name = "page1",
    components = {
      layers = {
          {  bg={} },
          {  gotoBtn={} },
          {  title={} },
          {  customLayerName={} },

       },
      audios = {  },
      groups = {  },
      timers = {  },
      variables = {  },
      page = { }
    },
    commnands = {  },
    onInit = function(scene) print("onInit") end
})
--
return scene
  • you can add your own(custom) layers to the layers table too

    nested layres are supported

    layers = {
      ...
      { title = {}},
      {
        customLayeTop = {
          {panelOne ={ }},
          {panelTwo = { {buttonOne={} }, {buttonTwo={} }} }
      }
    }

layer class

animation, button, layer replacements(spritesheet,video, particles,,) have defined with class names in kwik5

For instance, kwik4 you created a unique name to animation. kwik5 identifies a animation with layer with class name. You don’t need to assign a name to animation or buttons etc in kwik5.

for instance, “wich” > “en” layer with linear animation has “linear” class attached in index.lua.

components = {
  layers = {
    ...
     witch = {     {
       en = {
         class={ "linear", }  }
     },
  }

{{layer}}_{{class}}.lua should be present in layers/page/ folder

Mutliple classes are supported. If you define your own class, you may add your own custom class to a layer

components = {
  layers = {
    ...
    { title = {}, class={"animation", "button", "yourClass"}},
  }

components > audios, groups, timers variables, page

components = {
  ...
  audios = {
    long  = {"longOne", "longTwo" },
    short ={"shortOne","shortTwo"} ,
    sync  = {"syncOne", "syncTtwo"}}
  }
  groups = {"groupOne","groupTwo"},
  timers = {"timerOne", "timerTwo"},
  variables = {"varOne", "varTwo"},
},

Commands

events from buttons or animation’s complete etc are deftined in commands table.

For example, panelOne.OK event that comes from a button in panelOne. It fires OK event, and actions code in panelOne.OK.lua in App/{bookName}/commnads/{pageName} will be exectued.

page sceneName = ...
--
local scene = require('controller.scene'page(sceneName, {
    name = "page1",
    layers = {
          {  bg={} },
    ...
    },
    components = {
    ...
    },
    commnands = {
      "panelOne.OK",
      "panelOne.Cancel",
      "timerOne",
      "actionOne",
      },
    onInit = function(scene) print("onInit") end
})
--
return scene

Components Properties

the properties of animation, button, layer repleacements(spritesheet,video, particles) are editied, and saved with Kwik Editor.

The values of components properties are added/attached as a component class to a layer visually for designers to do a no-code editing

Kwik5 is aimed to be a low code tool faster to work with .lua code easily and directly. See the next Lua section

kwik4kwik5
1. In Photoshop, edit with kwik’s component panel, it saves props to .kwk(XML)
2. Publish .lua from .kwk

then preview in Solar2D simulator
In Photoshop, kwik exporter publishes .lua with layer properties

1. In Solar2D simulator, kwik editor reads the properties in .lua directly
2. User creates/modifies animation, button etc with the editor

For developers, you can use a text editor to edit .lua directly
  • App/{{Book Name}}/components/{{Page}}/layers/{{Layer}}.lua

    kwik4kwik5
    UI.layer = {}UI.sceneGroup = display.newGroup()
    local bg = UI.layer.bglocal bg = UI.sceneGroup.bg

    kwik4’s UI.layer is obsolete.

App/lingualSample/components/page1/layers/Candice_linear.lua

local parent,root = newModule(...)

local M = {
  name = "Candice",
  class = "linear", -- "Dissolve" "Path" "Linear" "Pulse" "Rotation" "Tremble" "Bounce" "Blink"
}

M.obj = require(parent.."en").obj

M.layerOptions = {
  --
  referencePoint = "Center", -- "Center" "TopLeft" "TopCenter" "TopRight" "CenterLeft" "CenterRight" "BottomLeft" "BottomLeft" "BottomRight" for text
  deltaX         = 0,
  deltaY         = 0,
}
-- animationProps
M.properties = {
  type    = "", -- group, page, sprite
  target = "witch/en",
  autoPlay = true,
  delay    = 0,
  duration = 2000,
  loop     = 1,
  reverse  = false,
  resetAtEnd  = false,
  --
  easing   = "inCircular", -- 'Linear' 'inOutExpo' 'inOutQuad' 'outExpo' 'outQuad' 'inExpo' 'inQuad' 'inBounce' 'outBounce' 'inOutBounce' 'inElastic' 'outElastic' 'inOutElastic' 'inBack' 'outBack' 'inOutBack'
  ------------
  -- flip
  xSwipe   = nil,
  ySwipe   = nil,
}
--

M.to = {
  x     = -180,
  y     = -100,
  --
  alpha = 1,

  yScale   = 1.5,
  xScale   = 1.5,
  rotation = 30,
}
-- more option

-- action at the end of animation
M.actions = { onComplete = "" }
...
...

Command Properties

  • Appp/{bookName}/commands/{pageName}/{commandName}.lua

App/book/commands/page1/actionOne.lua

local ActionCommand = {}
local AC           = require("commands.kwik.actionCommand")
--
-----------------------------
-----------------------------
function ActionCommand:new()
	local command = {}
	--
	function command:execute(params)
		local UI         = params.UI
		local sceneGroup = UI.sceneGroup
		local layers      = UI.layers
		local obj        = params.obj

    -- local conditions = require("App." .. UI.book..".common.conditions")
    -- local expressions = require("App." .. UI.book.."common.expressions")

    --
    -- target layer :sceneGroup[layerName]
    -- target animation : layer.animations[index]
    --
    obj = UI:getAnimation("witch/en_linear")
    AC.Animation:play(obj)
	end
	return setmetatable( command, {__index=AC})
end
--
ActionCommand.model = [[
{"name":"flyAnim","actions":[{"command":".animation.play","params":{"target":"witch/en_linear"}}]}
]]
--
return ActionCommand

Variables

Edit Variable in action command dialog

  • target: LCD
  • Value: value..‘1’
  • type: function

this makes the code like this, and setVariable update LCD variable stored internally

UI.setVaraible("LCD", function(value) value..1 return end)

UI.getVariable(varName) is also available for external code you make

See Details in tutorial/keyboard/

Assets

kwik editor automatically makes App/book/assets/model.lua by reading folders/files under App/book/assets folder.

you can create an audio component, layer repleacements of video, particles, sync audio&text, spritesheets by selecting one in the asset table.

{
    audios = {
      {
        name = "click.mp3",
        path = "audios/short",
        links = {{page = "page1"}}
      }
    },
    videos = {
      {
      name = "videoA.mp4",
      path = "videos",
      links = {{page= "page01", layers = {"imageOne"}},
              }
      },
      {
        name = "videoB.mp4",
        path = "videos",
        links = {
          {page= "page01", layers = {"iamgeTwo"}}}
      }
    },
    sprites = {}
  }

click ‘_target’ in the properties panel, then you can select a layer for video replacement in layerTable.

  1. click ‘_target’ by mouse

  2. select a layer for video replacement

  3. you see the star is set in _target property

See Details in get_started/component_with_asset/


Bookstore

Bookstore module in kwik handles mutliple books in App folder. Each book’s asset can be downloaded from your server on Internet

Details in Bookstore

  • portrait view for library
  • book table view
    • each book status: isFree, isPurchased, isDownloadable, isDownloaded

      • online icon

      See the section of bookstore/components/#Photoshop files table.psd

    • restore & download all

App/bookstore.lua

bookignored hides the given names in bookTable in kwik editor.

local M = {
  bookignored = {"book1", "mybook", "kwikTheCat"}
}
--
local pageCommand = require("components.bookstore.controller.pageCommand")
local model = require("components.bookstore.model.base")
--
model.debug = true
model.URL = "http://localhost:8080/bookshop/"
-- model.URL = nil means simple IAP store without network download
-- downloadBtn, savingTxt won'T be used. You don't need to create them.
----------
model.TOC = "bookTOC"
model.LIBRARY_PAGES = {en = "scenes.library"}
model.DIALOG_PAGES = {en = "scenes.dialog"}
--
model.name = "catalog01"
--
--
model.books = {
  bookFree = {
    name = "bookFree",
    versions = {},
    titles = {en = "bookOne"},
    descriptions = {en = "desc"},
    isFree = true,
    isOnlineImg = true,
    isDownloadable = true,
    image = "App/bookFree/assets/thumnails/page1.png",
    productNames = {apple = "bookFree", google = "bookFree", amazon = "bookFree"}
  },
  bookOne = {
    name = "bookOne",
    versions = {},
    titles = {en = "bookOne"},
    descriptions = {en = "desc"},
    isFree = false,
    isOnlineImg = true, -- true
    isDownloadable = true, -- true
    image = "App/bookOne/assets/thumnails/page1.png",
    productNames = {apple = "bookOne", google = "bookOne", amazon = "bookOne"}
  }
}
...