TOP > プログラム関連 > Lua > LÖVE(Love2D) > LÖVE(Love2D)でシンプルなPVなどの動画を作成する > 動画アプリケーションの大枠を整える

LÖVE(Love2D)でシンプルなPVなどの動画を作成する
◆◆ 動画アプリケーションの大枠を整える ◆◆

ではここからいよいよ動画作成に向けてLuaのコードを書いていくよ!

さて、たとえば闇雲に画像を表示するだけであれば以下のようにすれば実現できるわけですが……。

ファイル名:main.lua
function love.load () image = love.graphics.newImage ("test.png") end function love.update () -- 更新処理は特になし end function love.draw () love.graphics.draw ( image, 150, 50 ) end

で、あとはLua的にゴニョゴニョすればどうとでも好きなように「動くもの」ができる……と言うと記事が終わってしまうんですが、 これだけだと漠然とし過ぎていて万能ナイフ一本でサバイバルみたいな世界ですね。 目的は「動画」ということで、ある程度の枠組みは整えていこうではありませんか。

具体的に何が欲しいか?

そもそもLuaでプログラミングができるということは「好きなように処理を書ける」ということです。 たとえば「画像を好きな位置に表示する」とか「その画像を別の位置へ移動させる」とかですね。

その自由度は残しつつ、

「お望みの処理」を
「並べて」
「時間の流れに沿って」
「順番に実行していく」

ということができるような仕組みが欲しい。

時間の流れに沿って

ではまず、話は前後しますが一番全体的なことですので「時間の流れに沿って」の部分を実装していきます。 時間と言いつつ正確に「時・分・秒」を計算するのは面倒なので、「アプリケーション開始からのフレーム数」でいいですよね? いいということにしました。閣議決定しました。

ファイル名:main.lua
frame = 0 function love.load() -- 処理なし end function love.update() frame = frame + 1 print ("現在" .. frame .. "フレーム目") end function love.draw() -- 処理なし end
実行結果

よし! これでアプリケーションの中で「時間が流れる」ようになった!

「お望みの処理」を「並べる」

では次に「お望みの処理を」の部分に取り掛かりましょう。 あくまでも「お望みの処理」です。中身は決まっていない。箱だけ用意しておいて、後で何でも処理を書き込めるようにしておきたい。

そんなときは「サブルーチン(関数)」の出番です。

ファイル名:main.lua
function oreoreTask() print ("お望みの処理") end
frame = 0 function love.load() end function love.update() frame = frame + 1
-- 100フレーム目に oreoreTask() を実行 if ( frame == 100 ) then oreoreTask() end
end function love.draw() end

こんなふうにお望みの処理を関数にしておいて、他にも大量に書き加えて frame のカウント値に応じて分岐させて実行…… というやり方でも多分デキルとは思うのですが、増えてくると少々面倒になりそうです。

というわけで「並べる」ことができるよう、関数をオブジェクトとして、配列(テーブル)に入れることにします。 このとき、添字の番号を「それを実行するタイミング(フレーム)」ということにします。

timeTable[n] の n に、実行するフレーム番号を入れて、処理を書き足していくわけです。 この段階では処理を登録するだけで、まだ実行はせず、毎フレーム繰り返す必要もありません。 したがって、love.load() の中に書いておくこととします。

ファイル名:main.lua
timeTable = {}
frame = 0 function love.load()
timeTable[100] = function() print("フレーム100のときの処理") end timeTable[200] = function() print("フレーム200のときの処理") end timeTable[300] = function() print("フレーム300のときの処理") end
end function love.update() frame = frame + 1 end function love.draw() end
「順番に実行」

では、配列に入れた処理が「順番に実行」されるようにしましょう。 毎フレームのことなので、love.update() の中に書きます。

こんなふうにしておくと、

ファイル名:main.lua
timeTable = {} frame = 0 function love.load() timeTable[100] = function() print("フレーム100のときの処理") end timeTable[200] = function() print("フレーム200のときの処理") end timeTable[300] = function() print("フレーム300のときの処理") end end function love.update() frame = frame + 1
for key, value in pairs(timeTable) do if (key == frame) then value() end end
end function love.draw() end

こうなる!

実行結果(コンソール側)

……え? 結局if文で処理を分岐させる最初のサンプルと変わらないって? 否定はしないっっ! (心意気としては動画作成ソフトの操作をイメージして、時系列に沿って任意の「処理」を「登録」していく、という感じを Lua的に表現したかったのデス)

ともかく、これでお望みのタイミングでお望みの処理を実行できるようになった! 我らの野望成就せり! あとはLua的にゴニョゴニョと好きなように何とでもなるぜヒャッハー!

と言いたいところですが、まだ love.draw() の中が空っぽですね。 このままではいくらフレーム数が経過してもLove2Dのウィンドウ上では真っ黒な画面が続くばかり。 光よあれ、キャラ画像よあれ。どうすればいいんでしたっけ? はじめにLua言語があった。

LÖVE と Lua の関係図をもう一度。

たとえばLove2Dで画像を表示するにはLua言語で「love.graphics.image*************」のように唱えて Love2Dさんに「画像を表示してね」とお願いするのでしたね。 かと言って下記のようにしたのでは、表示されません。

ファイル名:main.lua
timeTable = {} frame = 0 function love.load()
image = love.graphics.newImage ("test.png")
timeTable[100] = function()
-- 100フレーム目に表示される? love.graphics.draw ( image, 150, 50 )
end end -- 更新 function love.update() frame = frame + 1 for key, value in pairs(timeTable) do if (key == frame) then value() end end end -- 描画 function love.draw() -- まだ何も書いてない end

なぜかと言えば、この処理が実行されるのは結局 update() の内部だからです。 Love2Dのお約束として、描画系の処理は draw() の内部に書かないとイケないのでした。 それに特定のフレームで love.graphics.draw を実行するだけでは画像は実行したフレームでしか表示されず一瞬で消えてしまいます。さぁどうしよう!

というわけで次は、画像をイイカンジに取り扱う仕掛けを作り込んでいきます。