2020/01/05(日) [n年前の日記]
#1 [love2d] love2dで簡単なペイントアプリモドキを書いてみたり
love2d を使って、簡単なペイントアプリっぽいものを書いてみたり。
こんな感じになった。環境は Windows10 x64 1909 + love2d 11.3。
こんな感じになった。環境は Windows10 x64 1909 + love2d 11.3。
- キャンバスの上でマウスの左ボタンを押しながらマウスを動かすと緑色で何か描ける。
- Sキーを押すと、フォルダと同階層にpng画像(年-月-日-時-分-秒.png)を保存できる。
- Cキーを押すと、キャンバスをクリア。
◎ ソース。 :
_conf.lua
_main.lua
conf.lua と main.lua を任意のフォルダに入れて、「love フォルダ名」で実行できる。
function love.conf(t) t.version = "11.3" -- love2d version t.window.title = "Simple paint - love2d" t.window.width = 800 t.window.height = 600 -- VSync Off t.window.vsync = 0 -- t.window.fullscreen = true -- t.window.fullscreentype = "exclusive" end
_main.lua
-- Simple paint on love2d function love.load() love.graphics.setDefaultFilter("nearest", "nearest") font = love.graphics.newFont(20) scrw = love.graphics.getWidth() scrh = love.graphics.getHeight() canvas = love.graphics.newCanvas(scrw, scrh) bg = make_checker_canvas(scrw, scrh) love.graphics.setCanvas(canvas) love.graphics.clear(0, 0, 0, 0) love.graphics.setCanvas() mx, my = 0, 0 req_clear_canvas = false req_export = false msg_timer = 0 msg_str = "" end function love.update(dt) mx, my = love.mouse.getPosition() if req_clear_canvas then -- clear canvas req_clear_canvas = false msg_timer = 0.75 msg_str = "Clear canvas" love.graphics.setCanvas(canvas) love.graphics.clear(0, 0, 0, 0) love.graphics.setCanvas() end if love.mouse.isDown(1) then -- draw brush love.graphics.setCanvas(canvas) love.graphics.setColor(0, 1, 0, 1) love.graphics.circle("fill", mx, my, 8) love.graphics.setCanvas() end if req_export then -- export canvas req_export = false msg_timer = 0.75 local filename = os.date("%Y-%m-%d_%H-%M-%S") .. ".png" if export_canvas(canvas, filename) then msg_str = "Export " .. filename else msg_str = "Can not export." end end if msg_timer > 0 then msg_timer = msg_timer - dt if msg_timer <= 0 then msg_timer = 0 end end end function love.draw() love.graphics.setCanvas() love.graphics.clear(0, 0, 0, 1) -- draw bg love.graphics.setColor(1, 1, 1, 1) love.graphics.draw(bg) -- draw canvas love.graphics.draw(canvas) -- draw cursor love.graphics.setColor(1, 1, 1, 1) love.graphics.circle("line", mx, my, 8) -- draw text love.graphics.setFont(font) love.graphics.setColor(1, 1, 1, 1) if msg_timer > 0 then love.graphics.print(msg_str, 2, 40) end love.graphics.print("C)lear S)ave", 10 * 10, 2) love.graphics.print("FPS: " .. tostring(love.timer.getFPS()), 2, 2) end function love.keypressed(key, isrepeat) if key == "escape" then -- ESC key to exit love.event.quit() elseif key == "s" and msg_timer == 0 then req_export = true elseif key == "c" then req_clear_canvas = true end end function export_canvas(canvas, filename) local imagedata = canvas:newImageData() local filedata = imagedata:encode("png") local filepng = io.open(filename, "wb") if filepng ~= nil then filepng:write(filedata:getString()) filepng:close() return true end return false end function make_checker_canvas(w, h) local cnavas = love.graphics.newCanvas(w, h) cnavas:renderTo( function() local start = true local sz = 8 local x, y for y = 0, (h - 1), sz do local fg = start for x = 0, (w - 1), sz do local c = fg and 0.6 or 0.4 love.graphics.setColor(c, c, c, 1) love.graphics.rectangle("fill", x, y, sz, sz) fg = not fg end start = not start end end ) return cnavas end
conf.lua と main.lua を任意のフォルダに入れて、「love フォルダ名」で実行できる。
◎ 少し解説。 :
やってることは以下。
conf.lua 内で、t.window.vsync = 0 を書いて、VSYNC を無効にしてるあたりにちと注意、だろうか。
love2d は、何も設定しないデフォルト状態なら VSYNC が有効になっている。その状態だと更新処理が60FPS前後で呼ばれるので、マウスを動かして画面に何か描こうとすると、軌跡(?)がかなり飛び飛びになってしまう。 *1
しかし、VSYNCを無効にすれば、更新処理が呼ばれる頻度が多くなるので、それほど飛び飛びにはならなかった。手元の環境では、500FPS前後で更新処理が呼ばれてるっぽい。
もっとも、本来は、マウスカーソルが動いた時だけ、距離に応じて線を引くように実装すべきかなと…。そう考えると、マウスカーソルを動かした時に呼ばれるコールバック関数( _love.mousemoved() )を用意して処理したほうがいいのかもしれない。
love2d の API についても一応メモ。
_love.graphics.setCanvas (日本語) - LOVE
_Canvas:renderTo (日本語) - LOVE
_love.graphics.circle (日本語) - LOVE
_love.graphics.rectangle (日本語) - LOVE
さておき。こういう処理を書けたのだから、お絵描きツールっぽい何かしらを、love2d を使って書くことだって不可能ではなかったりするのかもしれないなと…。
- 初期化処理(love.load()内)で、ウインドウサイズと同じサイズの Canvas を作成して。
- 更新処理(love.update(dt)内)で、マウス左ボタンが押されてたら Canvas に緑色の丸を描画。
- 描画処理(love.draw()内)で、Canvas を画面に描画。
conf.lua 内で、t.window.vsync = 0 を書いて、VSYNC を無効にしてるあたりにちと注意、だろうか。
love2d は、何も設定しないデフォルト状態なら VSYNC が有効になっている。その状態だと更新処理が60FPS前後で呼ばれるので、マウスを動かして画面に何か描こうとすると、軌跡(?)がかなり飛び飛びになってしまう。 *1
しかし、VSYNCを無効にすれば、更新処理が呼ばれる頻度が多くなるので、それほど飛び飛びにはならなかった。手元の環境では、500FPS前後で更新処理が呼ばれてるっぽい。
もっとも、本来は、マウスカーソルが動いた時だけ、距離に応じて線を引くように実装すべきかなと…。そう考えると、マウスカーソルを動かした時に呼ばれるコールバック関数( _love.mousemoved() )を用意して処理したほうがいいのかもしれない。
love2d の API についても一応メモ。
- love.graphics.setCanvas(canvas) で、指定した canvas を対象にして描画できるようになる。
- love.graphics.setCanvas() で、デフォルトのキャンバスに対して描画できるようになる。
- canvas:renderTo(func) で、canvas に対して関数 func の処理を実行することもできる。
- love.graphics.circle("fill", x, y, r) で、(x,y) を中心にして塗り潰した円を描画。
- love.graphics.circle("line", x, y, r) で、(x,y) を中心にして線のみの円を描画。
- love.graphics.rectangle("fill", x, y, w, h) で、四角形を描画。
_love.graphics.setCanvas (日本語) - LOVE
_Canvas:renderTo (日本語) - LOVE
_love.graphics.circle (日本語) - LOVE
_love.graphics.rectangle (日本語) - LOVE
さておき。こういう処理を書けたのだから、お絵描きツールっぽい何かしらを、love2d を使って書くことだって不可能ではなかったりするのかもしれないなと…。
*1: 液晶ディスプレイ側のリフレッシュレート設定によって、VSYNC有効時のFPSが違ってくるのかもしれない。自分は120Hz等の液晶ディスプレイを持っていないので、そのあたりは確認できず。
[ ツッコむ ]
#2 [tv] 「チャンネルはそのまま! 」を視聴
たまたまTVをつけていたら、「チャンネルはそのまま! 」なる実写ドラマが流れ始めたので、つい見てしまった。今回は、1話と2話が放送されていたらしい。
北海道のTV局を舞台にしたドラマ。どこかで見たような設定だなと思ったら、漫画「動物のお医者さん」で有名な佐々木倫子先生の漫画作品を原作としたドラマだったのだな…。たしか、原作の最初のあたりだけ、ちょっと読んだような記憶があるわけで。
少なくとも、1話と2話はかなり面白かった。TV業界の独自用語についても勉強になったし…。何より、日常的にTVで流れているのが当たり前の、視聴者側が普段全く気に留めていないアレコレに対し、それぞれをドラマとして盛り上げて、どこか感動的なシーンとして見せてしまうあたりが秀逸というか。
テロップで、登場人物の心の声や精神状態を伝える見せ方も興味深かった。漫画原作の、独特の書き文字を、ドラマ版でも再現していたような気がしたり。
もっとも、漫画の場合は背景を白くして文字が読み易い状態にできるけど、実写ドラマは背景に現実の風景が入ってしまうため、視覚情報が多くなりがちで。そのせいか、テロップがちょっと読み辛い部分はあったけど。一応、テロップを白く縁取りする等、文字情報と背景を分離する努力をしていた気配は感じたけれど。そのあたり、まだもうちょっと、微妙な工夫が必要だったりするのかもしれない。見せ方自体は全然アリだと思えるので、技を発明・発見して使いこなしてほしいなと。
元々は Netflix で独占先行配信されたドラマらしい。何かの賞も取っているそうで。なるほど。さすが Netflix 向け作品、なのだろうか…。
何にせよ、視聴する気は全く無かったのに、結局最後まで見てしまったあたり、これはかなり良い出来のドラマなのではなかろうか。実に良いものを見せていただきました。これはフツーに面白い。素晴らしい。
北海道のTV局を舞台にしたドラマ。どこかで見たような設定だなと思ったら、漫画「動物のお医者さん」で有名な佐々木倫子先生の漫画作品を原作としたドラマだったのだな…。たしか、原作の最初のあたりだけ、ちょっと読んだような記憶があるわけで。
少なくとも、1話と2話はかなり面白かった。TV業界の独自用語についても勉強になったし…。何より、日常的にTVで流れているのが当たり前の、視聴者側が普段全く気に留めていないアレコレに対し、それぞれをドラマとして盛り上げて、どこか感動的なシーンとして見せてしまうあたりが秀逸というか。
テロップで、登場人物の心の声や精神状態を伝える見せ方も興味深かった。漫画原作の、独特の書き文字を、ドラマ版でも再現していたような気がしたり。
もっとも、漫画の場合は背景を白くして文字が読み易い状態にできるけど、実写ドラマは背景に現実の風景が入ってしまうため、視覚情報が多くなりがちで。そのせいか、テロップがちょっと読み辛い部分はあったけど。一応、テロップを白く縁取りする等、文字情報と背景を分離する努力をしていた気配は感じたけれど。そのあたり、まだもうちょっと、微妙な工夫が必要だったりするのかもしれない。見せ方自体は全然アリだと思えるので、技を発明・発見して使いこなしてほしいなと。
元々は Netflix で独占先行配信されたドラマらしい。何かの賞も取っているそうで。なるほど。さすが Netflix 向け作品、なのだろうか…。
何にせよ、視聴する気は全く無かったのに、結局最後まで見てしまったあたり、これはかなり良い出来のドラマなのではなかろうか。実に良いものを見せていただきました。これはフツーに面白い。素晴らしい。
[ ツッコむ ]
以上、1 日分です。