Animoでかんたんにアニメーションを作る

4/15の「CoronaSDK MeetUp 2013 #1」用のネタです。
ざっくりいうと、
Flashでアニメつくって、それを簡単に、
コード書かずにCoronaで再現する方法、というものです。

概要はもちろん当日お話しますが、
これをCoronaSDKのこと知らない人もいるところで説明するのは、時間がかかりすぎると思うので、とりあえず適当にここに書きます。
めんどくさいので、
当日聞いて、ここみると、
あ、こういうふうにやったんだーってわかる....って感じにしかかかないです。

あと、Animoやるまえに、
こちらをぜひ読んでためしてみてください。
僕が話したこと、これから書く事は全部以下のものの発展系です。
SpriteLog=Animoだとおもってもらって問題ないです。
https://sites.google.com/site/coronaopensrc2/video-1/spriteloq_layout

▼Export Layout For Corona.jsfl、編集後のdiff

```

173,176c173,177
<     output.push("\tgroups['"+ename+"'] = group");
<     output.push("\tgroup.elementName = '"+ ename +"'")
<     output.push("\tgroup.libraryName = \"" + libItemName + "\"");
<     output.push("\t"+ insertInGroup(gname, "group"));
---
>     output.push("\tgroups['"+libItemName+"'] = group");    
>     //output.push("\tgroups['"+ename+"'] = group");    
>     //output.push("\tgroup.elementName = '"+ ename +"'")
>     //output.push("\tgroup.libraryName = \"" + libItemName + "\"");
>     //output.push("\t"+ insertInGroup(gname, "group"));
183c184
<     output.push("\tdimensions['"+ ename +"'] = {width = "+ Math.floor(_element.width) +", height = "+ Math.floor(_element.height) +"}");
---
>     //output.push("\tdimensions['"+ ename +"'] = {width = "+ Math.floor(_element.width) +", height = "+ Math.floor(_element.height) +"}");
185c186
<     if (_element.scaleX != 1) {
---
>     //if (_element.scaleX != 1) {
187c188
<     }
---
>     //}
192c193
<     if (_element.scaleY != 1) {
---
>     //if (_element.scaleY != 1) {
194c195
<     }
---
>     //}
199c200,201
<     if (_element.rotation != 0 && !isNaN(_element.rotation)) { 
---
>     //if (_element.rotation != 0 && !isNaN(_element.rotation)) { 
>      if (!isNaN(_element.rotation)) {
201a204
>     //}
311,312c314
< 
< 
---
>     var stack = [];
328c330
<             outl("local function createLayout(_spriteFactory)");
---
>             outl("local function createLayout(_spriteFactory,num)");
330a333,334
>             outl("\t if "+ldx+" ~= num then return false end");
> 
335c339
<             outl("\t"+ newGroup(layoutName).nl());
---
>             //outl("\t"+ newGroup(layoutName).nl());
345,346c349,350
<                 outl("\t"+ newGroup(group.name));
<                 outl("\t"+ insertInGroup(layoutName, "groups['"+ group.name +"']").nl());
---
>                 //outl("\t"+ newGroup(group.name));
>                 //outl("\t"+ insertInGroup(layoutName, "groups['"+ group.name +"']").nl());
406,407c410,412
< 
<             return layouttxt;
---
> 	            //ozawa
> 	        stack.push(layouttxt)
>             //return layouttxt;
416a422,423
>     //ozawa
>     return stack;
445c452,454
<         FLfile.write(fileurl, layout);
---
>         for(var l in layout){
>             FLfile.write(fileurl+l+'.lua', layout[l]);
>         }
```

▼上記で生成されたレイアウトLuaを実行する

```
------
--avatar.lua
------

local storyboard = require('storyboard')
local scene = storyboard.newScene()
local loqsprite = require('loq_sprite')
local sg    --シーンのView
local grp
local files = {}
local num = 0
local fnum = 1
local character
local logoAnim
local logoAnimKey


--これを変更するとアクションが切り替わる
local action = 'idle'

function scene:createScene( event )
    logoAnimKey = 0
    
    --各アクションのフレーム数を管理(ここはFlashのフレーム数をみて書いてください...)
    files.cnt = {
        idle=30,
        walk=14,
        punchS=17,
    }
    --ここはExport Layout For Corona.jsflでかき出したluaを読み込む
    files.idle = 
    {
        require('pause__idle0'),
        require('pause__idle1'),
        require('pause__idle2'),
        require('pause__idle3'),
        require('pause__idle4'),   
    }

    files.walk = {
        require('pause__walk0'),
        require('pause__walk1'),
        require('pause__walk2'),
        require('pause__walk3'),
        require('pause__walk4')
    }

    files.punchS = {
        require('pause__punchS0'),
        require('pause__punchS1'),
        require('pause__punchS2'),
        require('pause__punchS3'),
        require('pause__punchS4'),
        require('pause__punchS5'),
        require('pause__punchS6'),
        require('pause__punchS7'),
        require('pause__punchS8')
    }


    sg = self.view
    local img  = loqsprite.newFactory('face_01_01',
                                      'body_02_01',
                                      'hair_04_01',
                                      'c_shadow')    
    grp = display.newGroup()
    local createNewLoqSprite = {
        exec= function(loqSprite,group) 
        return {
            stack ={},
            unUsed ={},
            grp = group,
            ls = loqSprite,
            --loq_spriteのnewSpriteGroupをオーバーライド
            newSpriteGroup = function(self,name)
                if self.stack[name] == nil then
                    self.stack[name] = self.ls:newSpriteGroup(name)
                    self.grp:insert(self.stack[name])
                end
                if self.unUsed[name] ~= nil then
                    self.unUsed[name] = false
                end
                self.stack[name].alpha = 1
                return self.stack[name]
            end         
      }   
      end
    }
    character = createNewLoqSprite.exec(img,grp)
   
    grp.x = 100
    grp.y = 260


    
    --背景みづらいので
    local bg = display.newRect(sg,0,0,320,480)
    bg:setFillColor(100,0,0)
    

    --切り替えボタン
    local name = {'idle','walk','punchS'}
    
    local i
    for i=1,3 do
        local rect = display.newRoundedRect(sg,20+100*(i-1),400,80,60,10)
        rect.num = i
        local text = display.newText(sg,name[i],30+100*(i-1),410,nil,16)
        text:setTextColor(0,0,0)
        
        rect:addEventListener('tap',function(event)
            action = name[i]
            num = 0
            fnum = 1                
        end)
    end

    
    --ロゴアニメーション
    logoSprites = display.newGroup()
    logoSprites:scale(0.5,0.5)
    logoSprites.y = -30
    titleLogoSheet = loqsprite.newFactory('sheet_titleLogo')
    logoAnim = createNewLoqSprite.exec(titleLogoSheet,logoSprites)

    --アニメ実行ボタン
    local rect = display.newRoundedRect(sg,220,200,80,60,10)
    rect:addEventListener('tap',function(event)
       logoAnimKey = 0
       
    end)
end

local function enterFrame(event)
    
    if logoAnimKey < 17 then
        require('layout_titleLogo'..logoAnimKey).createLayout(logoAnim,logoAnimKey)
        logoAnimKey = logoAnimKey+1
    end
    
    local k,v
    for k,v in pairs(character.stack) do
         character.unUsed[k] = true    
    end
    
    local p = files[action][fnum].createLayout(character,num)
    if p ~= false then
        for k,v in pairs(character.unUsed) do
             if v==true then
                 character.stack[k].alpha = 0
             end
        end
        fnum = fnum + 1
        if fnum > #files[action] then
            fnum = 1
        end
    end
    num = num +1 
    if num > files.cnt[action] then
        num = 0        
    end
end

function scene: destroyScene(event)
    display.remove(self.view)
end

scene:addEventListener( 'destroyScene', scene )
scene:addEventListener( 'createScene', scene )
Runtime:addEventListener( 'enterFrame', enterFrame )

return scene
```

わけわからなければ質問いただければ…。