2021/06/20(日) [n年前の日記]
#1 [love2d] love2dでJSONファイルを読み込む
2Dゲームエンジン love2d を使ってJSONファイルを読み込めないか実験中。Windows10 x64 20H2 + love2d 11.3 で動作確認。
_LoVE - Free 2D Game Engine
love2d は Lua言語でスクリプトを書いていくけど、JSONを扱える標準ライブラリは入ってない。が、ググっていたら、json.lua が love2d で使える、という話を見かけて。
_Arson - your companion for json,lua - LoVE
_rxi/json.lua: A lightweight JSON library for Lua
MITライセンスのライブラリ。コレを使わせてもらおう…。ありがたや。
json.lua をDLして、love2d用のスクリプト ―― main.lua や conf.lua と同階層に置く。
main.lua, conf.lua, data.json は以下。
_main.lua
_conf.lua
_data.json
任意のディレクトリ(jsonread とか)を作成して、main.lua, conf.lua, data.json, json.lua を置いて、love ディレクトリ名 (例: love jsonread)、で実行。
JSONファイルを読み込んで、中に記述された情報を読み取ることができた。
_LoVE - Free 2D Game Engine
love2d は Lua言語でスクリプトを書いていくけど、JSONを扱える標準ライブラリは入ってない。が、ググっていたら、json.lua が love2d で使える、という話を見かけて。
_Arson - your companion for json,lua - LoVE
_rxi/json.lua: A lightweight JSON library for Lua
MITライセンスのライブラリ。コレを使わせてもらおう…。ありがたや。
json.lua をDLして、love2d用のスクリプト ―― main.lua や conf.lua と同階層に置く。
main.lua, conf.lua, data.json は以下。
_main.lua
function love.load() json = require 'json' text = love.filesystem.read('data.json') o = json.decode(text) cur_time = 0 end function love.update(dt) cur_time = cur_time + dt end function love.draw() y = 8 love.graphics.print("ESC to exit.", 8, y) y = y + 32 for key, value in pairs(o) do local fn = value["path"] love.graphics.print(key .. " : " .. fn, 8, y) y = y + 24 end end function love.keypressed(key, isrepeat) if key == "escape" then love.event.quit() end end
_conf.lua
function love.conf(t) t.window.width = 640 t.window.height = 480 t.window.title = "Json read" t.window.fullscreen = false -- t.window.fullscreentype = "exclusive" end
_data.json
{ "Title": { "path": "imgs/img01.png", "start": 1, "area": [{ "link": "Hall", "type": "rect", "pos": [561, 399, 718, 582] } ] }, "Hall": { "path": "imgs/img02.png", "area": [{ "link": "RoomYellow", "type": "poly", "pos": [80, 201, 310, 355, 308, 594, 84, 706] }, { "link": "RoomGreen", "type": "rect", "pos": [471, 378, 673, 564] }, { "link": "RoomBrown", "type": "poly", "pos": [1059, 337, 1231, 194, 1225, 706, 1059, 587] } ] }, ...(中略)... }
任意のディレクトリ(jsonread とか)を作成して、main.lua, conf.lua, data.json, json.lua を置いて、love ディレクトリ名 (例: love jsonread)、で実行。
JSONファイルを読み込んで、中に記述された情報を読み取ることができた。
◎ 少し解説。 :
love2d + json.lua は、おおよそ以下のような使い方になるっぽい。
以下が参考になった。
_How do you read from a file? - LoVE
- json = require 'json' で、jsonライブラリを使えるようにする。
- text = love.filesystem.read('data.json') で、data.json をテキストデータとして読み込む。love.filesystem.read() は love2d で用意されている、テキストファイル読み込み用の関数。
- data = json.decode(text) で、JSONデータとして記述されたテキストを解析して、Luaのテーブルに変換する。
- あるいは、text = json.encode(data) で、Luaのテーブルを JSONデータ文字列に変換することもできるらしい。
以下が参考になった。
_How do you read from a file? - LoVE
[ ツッコむ ]
#2 [love2d] 点が三角形の内外にあるか判定したい
love2d を使って、点が三角形の内外にあるか判定したい。
以下のページが参考になった。
_点が三角形の内側か判定したい - Thoth Children
_点と三角形の当たり判定( 内外判定 )
ベクトルの外積を使って判定できる。
以下のような感じになった。
_main.lua
_conf.lua
判定処理は、checkHitTri(頂点が入った配列, 点のx座標, 点のy座標) で行ってる。点が中に入ってたら true が、外なら false が返る。
triangle_collision というディレクトリを作成して、main.lua と conf.lua を入れて、love triangle_collision で実行。以下のような感じで動いた。
以下のページが参考になった。
_点が三角形の内側か判定したい - Thoth Children
_点と三角形の当たり判定( 内外判定 )
ベクトルの外積を使って判定できる。
以下のような感じになった。
_main.lua
function love.load() polys = { {200, 30, 300, 30, 250, 200}, {400, 100, 600, 60, 500, 200}, {120, 300, 300, 250, 500, 400}, {60, 20, 180, 180, 20, 100}, } hits = {} for i=1, #polys do hits[i] = false end mx, my = 0, 0 end function getCrossVec2D(vx1, vy1, vx2, vy2) return (vx1 * vy2 - vx2 * vy1) end function checkHitTri(pos, xa, ya) local b1, b2, b3 local x1, y1, x2, y2, x3 x1, y1 = pos[1], pos[2] x2, y2 = pos[3], pos[4] x3, y3 = pos[5], pos[6] b1 = (getCrossVec2D(x2 - x1, y2 - y1, xa - x1, ya - y1) < 0) b2 = (getCrossVec2D(x3 - x2, y3 - y2, xa - x2, ya - y2) < 0) b3 = (getCrossVec2D(x1 - x3, y1 - y3, xa - x3, ya - y3) < 0) return ((b1 == b2) and (b2 == b3)) end function love.update(dt) mx, my = love.mouse.getPosition() for i = 1, #polys do hits[i] = checkHitTri(polys[i], mx, my) end end function love.draw() -- clear canvas love.graphics.clear(0, 0, 0, 1) -- draw polygon for i = 1, #polys do if hits[i] then love.graphics.setColor(1, 0, 0, 1) else love.graphics.setColor(0, 1, 0, 1) end love.graphics.polygon("fill", polys[i]) end -- draw text love.graphics.setColor(1, 1, 1, 1) love.graphics.print("ESC to exit.", 8, 8) love.graphics.print("mx, my = " .. mx .. "," .. my, 8, 24) end function love.keypressed(key, scancode, isrepeat) if key == "escape" then love.event.quit() end end
_conf.lua
function love.conf(t) t.window.width = 640 t.window.height = 480 t.window.title = "Collision Triangle" t.window.fullscreen = false -- t.window.fullscreentype = "exclusive" end
判定処理は、checkHitTri(頂点が入った配列, 点のx座標, 点のy座標) で行ってる。点が中に入ってたら true が、外なら false が返る。
triangle_collision というディレクトリを作成して、main.lua と conf.lua を入れて、love triangle_collision で実行。以下のような感じで動いた。
[ ツッコむ ]
#3 [anime] 「Vivy Fluorite Eye's Song」最終回を視聴
BS11で放送されていたTVアニメ。最終回を視聴。
面白かった…。これは良い…。
内容は、少し大人びた初音ミクがターミネーター2する話。ってそんな説明でいいのだろうかと思わないでもないけど、本編内でも「そんなどこかの映画みたいな話…」とセルフツッコミを入れてたし…。
制作は、「進撃の巨人」アニメ版を作ったことで有名な WIT STUDIO。映像クオリティは折り紙付き。原案・シリーズ構成は、「Re:ゼロから始める異世界生活」の原作者、長月達平さん。時間軸が絡んでくる話なので、作家さんの得意分野とマッチしてた印象。
とにかく、歌姫云々という設定が各所でよく効いているなと。歌姫というキーワード・設定から受ける、静かなイメージもあるのだけれど、歌が絡むからには、クライマックスのアクションシーンでやっぱり歌が流れるわけで、そりゃもうほとんどマクロス状態。これで盛り上がらないわけがない。
以前、「はねバド」というバトミントンアニメで、凄味を感じる作画を披露してたアニメーターさんが参加してたそうで。ロボットだからこそアリだろうと思えるアクションシーン・格闘シーンだった気がする。格ゲーの達人達の攻防を見せられてるような感覚。
どういう仕組みでそれが可能になるのか等々、細かい部分の設定は少し気になったけど、「100年の旅」というキーワードを提示されてしまったら、もう細かいところなんてどうでもいいよなと…。や、自分、ガンダムAGEとか好きだったので。100年と聞いたらハイオッケー、全然オッケー、そのまま話を進めてくださいお願いします、みたいなソレなので…。
1クールで奇麗にまとまってた感じもするし、これはなかなかイイ感じのアニメだったのではないかなあ、と…。
面白かった…。これは良い…。
内容は、少し大人びた初音ミクがターミネーター2する話。ってそんな説明でいいのだろうかと思わないでもないけど、本編内でも「そんなどこかの映画みたいな話…」とセルフツッコミを入れてたし…。
制作は、「進撃の巨人」アニメ版を作ったことで有名な WIT STUDIO。映像クオリティは折り紙付き。原案・シリーズ構成は、「Re:ゼロから始める異世界生活」の原作者、長月達平さん。時間軸が絡んでくる話なので、作家さんの得意分野とマッチしてた印象。
とにかく、歌姫云々という設定が各所でよく効いているなと。歌姫というキーワード・設定から受ける、静かなイメージもあるのだけれど、歌が絡むからには、クライマックスのアクションシーンでやっぱり歌が流れるわけで、そりゃもうほとんどマクロス状態。これで盛り上がらないわけがない。
以前、「はねバド」というバトミントンアニメで、凄味を感じる作画を披露してたアニメーターさんが参加してたそうで。ロボットだからこそアリだろうと思えるアクションシーン・格闘シーンだった気がする。格ゲーの達人達の攻防を見せられてるような感覚。
どういう仕組みでそれが可能になるのか等々、細かい部分の設定は少し気になったけど、「100年の旅」というキーワードを提示されてしまったら、もう細かいところなんてどうでもいいよなと…。や、自分、ガンダムAGEとか好きだったので。100年と聞いたらハイオッケー、全然オッケー、そのまま話を進めてくださいお願いします、みたいなソレなので…。
1クールで奇麗にまとまってた感じもするし、これはなかなかイイ感じのアニメだったのではないかなあ、と…。
[ ツッコむ ]
#4 [anime] 「86」最終回を視聴
BS11で放送されていたTVアニメ。最終回を視聴。
少しネタバレ。
ラストカット、仰向けになった主人公の上に描かれる ぐしゃぐしゃした線がなかなか。まあ、そういうことなんだろう…。この感覚は何かに似ているなと思ったけど、もしかして、「未来世紀ブラジル」あたりが近いのだろうか…。 *1 何にせよ、絶望しかない世界観の作品ではあるなと…。
白組が担当してたというCGパートのスタイルが興味深かった。つるんとしたセルルックではなく、テクスチャや反射を載せた感じのリッチな見た目というか。戦場で活躍する、汚れまくって傷だらけになったメカらしさがイイ感じで。あるいは敵側の、機械的・硬質的で、冷酷さを感じさせるキラキラカッチリ感も、ちゃんと対比になっていて、これまたイイ感じ。今後はこういう絵柄・スタイルが増えていくのかなと…。例えば、ボトムズ、ダグラム、ザブングルあたりを、こういうスタイルの3DCGでリメイクしたらどうなるかな、などと妄想してしまったぐらいに、好みの3DCG映像でした。みたいな。
少しネタバレ。
ラストカット、仰向けになった主人公の上に描かれる ぐしゃぐしゃした線がなかなか。まあ、そういうことなんだろう…。この感覚は何かに似ているなと思ったけど、もしかして、「未来世紀ブラジル」あたりが近いのだろうか…。 *1 何にせよ、絶望しかない世界観の作品ではあるなと…。
白組が担当してたというCGパートのスタイルが興味深かった。つるんとしたセルルックではなく、テクスチャや反射を載せた感じのリッチな見た目というか。戦場で活躍する、汚れまくって傷だらけになったメカらしさがイイ感じで。あるいは敵側の、機械的・硬質的で、冷酷さを感じさせるキラキラカッチリ感も、ちゃんと対比になっていて、これまたイイ感じ。今後はこういう絵柄・スタイルが増えていくのかなと…。例えば、ボトムズ、ダグラム、ザブングルあたりを、こういうスタイルの3DCGでリメイクしたらどうなるかな、などと妄想してしまったぐらいに、好みの3DCG映像でした。みたいな。
*1: 自分が見た「ブラジル」は、おそらくはハッピーエンドではない版、だったと思ったけれど、ググってみたら色々な版があるようで、すると自分はどの版を見たのだろう…。
[ ツッコむ ]
以上、1 日分です。