TOP > プログラム関連 > Lua > LÖVE(Love2D) > LÖVE(Love2D)でシンプルなPVなどの動画を作成する > 仕上げ:BGMを鳴らす / スペースキーを押すまで待機するようにする

LÖVE(Love2D)でシンプルなPVなどの動画を作成する
◆◆ 仕上げ:BGMを鳴らす / スペースキーを押すまで待機するようにする ◆◆
BGMを鳴らす

画像が表示できるようになった! テキストが表示できるようになった! あと足りないものは何だろう? BGMだ!
というわけでBGMを鳴らせるように機能を追加します。

と言っても、凝ったことをしなくていいのであれば、

・開始と同時にオーディオファイルを読み込んで演奏
・終了時に止める

の2つだけでいいんじゃないでしょうか。

Love2DでBGMを鳴らすのは公式Wikiによるとこういう感じらしいっすね。

bgm = love.audio.newSource ( "hogehoge.mp3", "stream" )
bgm:play()

凝ったことをしようと思えば画像やテキストと同じようにクラス化するといいのかもですが、 画像やテキストと違って、「複数のものを同時平行的に処理」する必要は多分そんなにないんじゃないでしょうか? え? 必要あるって?
いや、だから凝ったことをしたいなら、その都度ガンバルこととしてですね。 今回は冒頭で述べた2つの機能「鳴らす」「止める」だけで満足することにするのですよ。欲張らない。頑張らない。

さて、Love2Dの公式Wikiによると、上記のようにしてオーディオファイルを読み込んで……

bgm:play() で演奏
bgm:stop() で停止

とのこと。

これで充分と言えば充分ですが、PV動画的には終了時にはブツ切れではなくフェードアウトぐらいはして欲しい気はします。 Love2Dにはフェードアウトの機能はあるのでしょうか?  機能は play と stop 以外にもたくさんあるみたいで全部を理解しようとすると命がいくつあっても足りませんが、 ザッと見た感じ、ズバリ「フェードアウト」という機能はなさそうです。あるのかな? あったらごめんなさい。

その代わりと言うか、ボリューム調整はできるみたいですね。

bgm:setVolume ( 値 )

値は 0.0〜1.0 とのこと。(0.0が最小。1.0で最大)
setメソッドがあるということは、getメソッドで現在値を取得することもおできになる。

値 = bgm:getVolume ()

これを利用して、「フェードアウト開始フラグ」が立っていたらボリュームを少しずつ下げる、という処理を書いてあげれば夢が叶うに違いありません。

main.lua の update() の中のどこか
-- BGMフェードアウト判定 & 処理 if (isBgmFadeOut) then v = bgm:getVolume() v = v - 0.005 -- 減らす量は適当に書き換えて調整 if (v < 0) then v = 0 end bgm:setVolume(v) end

スペースキーで開始

今まではアプリケーションの起動と同時にイキナリおっ始まっておりました。 それで何か困ることはあるのでしょうか? ないっちゃないですね。はい。 ただ、最終的に動画とするために、画面キャプチャソフトで録画をするという運命を私たちは背負っているのでしたね。 イキナリおっぱじまるようではタイミングを合わせるのが難しい。

Love2D自体にウィンドウの表示内容を録画、みたいな小洒落たフィーチャーがあるとハッピーなのですが、 私がザッと公式Wikiをナナメ読みした限りでは、そういうものはなさそうです。あるのかな? あったらゴメンなさい。

で、録画の際、タイミング良く開始するために例えばスペースキーを押すまで待機してくれてたりすると便利かな、ということです。 もちろんスペースキーじゃなくてもエンターキーでもマウスのボタンでもお隣のお兄さんのお鼻でも何でも構いません。

Love2Dでキー入力を検知するにはこういうふうにするらしいですよ。

love.keyboard.isDown("space")

というわけで、後はもう適当にゴニョゴニョの世界。 開始ボタン(例えばスペースキー)が「押されたか/まだ押されてないか」のフラグを用意しておいて、 押されてない場合は毎フレームのフレーム数カウントを進めずに0のままにしておくこととします。

-- どこか冒頭付近にでもフラグを宣言しておいて…… isStarted = false ・ ・ (中略) ・ ・ -- 更新処理 function love.update() -- キー入力でフラグを立てる if love.keyboard.isDown("space") then isStarted = true end -- フラグが立ってる場合のみ、フレームカウントを進める if (isStarted) then frame = frame + 1 end ・ ・ (以下略) ・ ・

これできっと願いが叶っていることでしょう。叶っているはずです。叶っていろ〜。

お試し

というわけで、上記2点(BGM、スペースキーで開始)を盛り込んだ main.lua(とお試し動画)です。
気持ちよくBGMが鳴っていることをご確認いただけると存じます。スペースキー云々の件は動画自体には映り込んでませんが霊能力で察知していただければ幸いです。

BGMがついている以外は前回とほぼ同じ内容です。 変更点はソースコードの該当箇所に青でコメントをつけておりますので頑張ってお探しいただければ幸いです(あなたへハートキャッチ丸投げ)。 ちなみに紫コメントはスペースキーで開始関連の処理。

main.lua
require( "imageObj" ) -- 頑張って作った画像クラスを読み込む! require( "textObj" ) -- 頑張って作ったテキストクラスを読み込む! imageList = {} -- 画像オブジェクトを入れるリスト timeTable = {} -- 時系列ごとのタスクの関数オブジェクトを入れるリスト frame = 0 love.window.updateMode ( 800,600 ) -- 念のため、ウィンドウのサイズを明示的に指定しておく love.window.setTitle ( "試しているところ" ) -- 気まぐれにウィンドウのタイトルをセットしてもみる function love.load() -- フォントを取得しておく。 myFont = love.graphics.newFont("HonobonoPopTTF-Regular.ttf", 50) bgm = love.audio.newSource("iroasetayugure.mp3","stream") isBgmFadeOut = false -- 画像のラベルを指定(重なり順に。後に書いた方が手前) imageLabel = { "narration1", "narration2", "narration3", "narration4" } -- ここからフレームごとの処理を書いていく -- 1フレーム目:画像を2枚読み込んでいます。位置も設定。 timeTable[1] = function() -- BGM演奏開始 bgm:play() imageList["narration1"] = TextObj.new ( myFont, "なぜ" ) imageList["narration1"]:setColor ( 1.0, 1.0, 1.0, 1.0 ) imageList["narration1"]:setPosition(400, 300) imageList["narration1"]:setScale(10.0, 10.0) imageList["narration1"]:changeScale(1.0, 0.1) imageList["narration1"]:changeAngle(3600, 35) end timeTable[150] = function() imageList["narration1"]:moveY(100, 10) imageList["narration2"] = TextObj.new ( myFont, "このyoは" ) imageList["narration2"]:setColor ( 1.0, 1.0, 1.0, 1.0 ) imageList["narration2"]:setPosition(400, 300) imageList["narration2"]:setScale(10.0, 10.0) imageList["narration2"]:changeScale(1.0, 0.1) imageList["narration2"]:changeAngle(3600, 35) end timeTable[300] = function() imageList["narration2"]:moveY(200, 10) imageList["narration3"] = TextObj.new ( myFont, "このよう" ) imageList["narration3"]:setColor ( 1.0, 1.0, 1.0, 1.0 ) imageList["narration3"]:setPosition(400, 300) imageList["narration3"]:setScale(10.0, 10.0) imageList["narration3"]:changeScale(1.0, 0.1) imageList["narration3"]:changeAngle(3600, 35) end timeTable[450] = function() imageList["narration4"] = TextObj.new ( myFont, "なのか!?" ) imageList["narration4"]:setColor ( 1.0, 1.0, 1.0, 1.0 ) imageList["narration4"]:setPosition(400, 400) imageList["narration4"]:setScale(10.0, 10.0) imageList["narration4"]:changeScale(1.0, 0.1) imageList["narration4"]:changeAngle(3600, 35) end timeTable[600] = function() imageList["narration1"]:changeScale ( 10, 0.2 ) imageList["narration1"]:moveX ( 1600, 30 ) end timeTable[620] = function() imageList["narration2"]:changeScale ( 10, 0.2 ) imageList["narration2"]:moveX ( -1600, 30 ) end timeTable[640] = function() imageList["narration3"]:changeScale ( 10, 0.2 ) imageList["narration3"]:moveX ( 1600, 30 ) end timeTable[660] = function() imageList["narration4"]:changeScale ( 10, 0.2 ) imageList["narration4"]:moveX ( -1600, 30 ) end timeTable[750] = function() imageList["narration1"]:setPosition(400, 300) imageList["narration1"]:setScale(0.01, 0.01) imageList["narration1"]:changeScale(3.0, 0.05) -- BGMフェードアウト開始フラグを立てる(update側で察知して対応してもらう) isBgmFadeOut = true end end -- 開始フラグ。最初はfalse isStarted = false -- 更新処理 function love.update() -- スペースキーで開始フラグを立てる if love.keyboard.isDown("space") then isStarted = true end -- 開始フラグが立っている場合のみ、フレーム数をカウントする。 if (isStarted) then frame = frame + 1 end -- BGMフェードアウト判定 & 処理 if (isBgmFadeOut) then v = bgm:getVolume() v = v - 0.005 if (v < 0) then v = 0 end bgm:setVolume(v) end -- 時系列(フレーム)に沿って各タスクを実行 for key, value in pairs(timeTable) do if (key == frame) then value() end end -- 画像オブジェクトの更新処理 for key, value in pairs(imageList) do value:update() end end -- 描画処理 function love.draw() -- 画像オブジェクトの描画処理 for i = 1, #imageLabel, 1 do key = imageLabel[i] if ( imageList[key] ~= nil ) then imageList[key]:draw() end end end

フォントは『ほのぼのポップ』(Nontynet様)
BGMは『色あせた夕暮れ 』(甘茶の音楽工房 様)です。ありがとうございます。