mieki256's diary



2021/09/16(木) [n年前の日記]

#1 [love2d] love2dで疑似ラスタスクロールを使って立体的な見た目にできるか試した

love2d 11.3 を使って、疑似ラスタースクロールのみを利用して、立体的な見た目にできるか実験してみた。

いやまあ、仕組み自体は分かっているのだけど、どんな元画像を用意すればいいのか、どんなスクロール値を設定すればいいのか、そこらへんが分からなかったので…。実際に描いて/書いてみないと分からんなと…。

こんな感じになった。マウスカーソルの横位置によってスクロール速度が変わるようにしてみた。




一応、love.js ( _LoVE Web Builder )を使って、Webブラウザ上でも動く版も用意してみた。

_05_fake_rasterscroll_e

Windows10 x64 21H1 + Firefox 92.0 64bit、Google Chrome 93.0.4577.82 64bit では動いてるように見えるけど、どうだろう…。

ソースと使用画像。 :

ソースと使用画像は以下。

_main.lua
-- Fake raster scroll

-- init
function love.load()

  -- set filter
  love.graphics.setDefaultFilter("nearest", "nearest")

  -- set canvas size
  scr_w, scr_h = 1280, 720
  canvas = love.graphics.newCanvas(scr_w, scr_h)

  -- get window width and height
  wdw_w, wdw_h = love.graphics.getDimensions()

  scr_scale = math.min((wdw_w / scr_w), (wdw_h / scr_h))
  scr_ofsx = (wdw_w - (scr_w * scr_scale)) / 2
  scr_ofsy = (wdw_h - (scr_h * scr_scale)) / 2

  -- load image
  img = love.graphics.newImage("bg1.png")
  img2 = love.graphics.newImage("bg2.png")

  -- make Quad (raster)
  imgs = {}
  bg_x_list = {}
  for i = 1, img:getHeight() do
    local x = 0
    local y = i - 1
    imgs[i] = love.graphics.newQuad(x, y, img:getWidth(), 1, img:getDimensions())
    bg_x_list[i] = 0
  end

  bg_x = 0
end

-- update
function love.update(dt)
  local w0 = 684
  local w1 = 1195

  local mx = love.mouse.getX()
  local d = mx - (scr_w / 2)
  
  bg_x = (bg_x + 2 * d * dt) % w0
  
  -- set bg_x_list
  local x0 = -bg_x
  local x1 = -bg_x * w1 / w0
  for i = 1, img:getHeight() do
    local y = i - 1
    bg_x_list[i] = x0 + y * (x1 - x0) / (img:getHeight() - 1)
  end
  
end

-- draw
function love.draw()
  -- set canvas
  love.graphics.setCanvas(canvas)

  -- fill BG color
  love.graphics.setColor(0, 0, 1.0)
  love.graphics.rectangle("fill", 0, 0, scr_w, scr_h)

  -- draw bg upper
  love.graphics.setColor(1.0, 1.0, 1.0)
  love.graphics.draw(img2, -bg_x, 0)

  -- draw raster
  local y = scr_h - img:getHeight()
  love.graphics.setColor(1.0, 1.0, 1.0)
  for i = 1, img:getHeight() do
    love.graphics.draw(img, imgs[i], bg_x_list[i], (y + i - 1))
  end

  -- unset canvas
  love.graphics.setCanvas()

  -- draw canvas to window
  love.graphics.setColor(1.0, 1.0, 1.0)
  love.graphics.draw(canvas, scr_ofsx, scr_ofsy, 0, scr_scale, scr_scale)

  -- print FPS
  love.graphics.print("FPS: "..tostring(love.timer.getFPS()), 10, 10)
end

function love.keypressed(key, isrepeat)
  -- ESC to exit
  if key == "escape" then
    love.event.quit()
  end
end

_conf.lua
function love.conf(t)
  t.window.title = "Fake Raster Scroll"
  t.window.width = 1280
  t.window.height = 720
  t.window.vsync = true
  t.modules.joystick = false
  -- t.window.fullscreen = true
  -- t.window.fullscreentype = "exclusive"
end

_bg1.png (1.25MB)
_bg2.png (528KB)

分かったこと。 :

台形に見えている部分がループするわけだけど、台形の、上辺の幅と下辺の幅が分かれば、プログラム側の処理というか、ラスタースクロール値の算出については全然難しくなかったなと…。幅の狭いほうを基準として、幅の広いほうは何倍の速度でスクロールするかを考えれば楽かもしれない。

bg1_note.png

また、ループ部分がこのくらいの幅であっても、結局のところ、「ある程度スクロールしたらスクロール値をリセットする」という方法で対処できると分かった。

元画像についても、初期状態の見た目が画像の左半分に収まるように描けばどうにかなる、と分かった。ただ、その元画像を作るのがちょっと面倒だった気もするけれど…。

bg1.png


さておき、今のハードウェアならこのくらいの大きさの画像をベタで持っても問題無いだろうけど、昔のゲーム機 ―― メガドラあたりでこういうBGを持とうとしたらセル? パターン? キャラ? の領域(1セル8x8ドット)をかなり圧迫しそうだなと今更ながら気付いたりもして。節約術が求められそう。
  • 初期画面の左半分は、右半分を水平反転してキャラ数を節約。
  • ループ幅を狭くしたラインをキャラ単位で部分的に用意してキャラ数を節約。
  • ベタ部分を極力増やしてキャラ数を節約。
等々の工夫が必要だったのではないかと…。仕組みは簡単でも、当時のVRAM容量内に収めるために結構苦労したのではないかなあ。どうなんだろう。

念のために書いておくけど、今時のハードウェアで、ラスタースクロールをわざわざ疑似的に再現してまで、新規にこういう処理を書く必要は全く無いです…。3DCGだのポリゴンだので描画すればいいじゃん、で済んでしまうので…。まあ、こういうのって、プログラマーにとっての頭の体操と言うかお遊びパズルと言うかそういう感じのアレってことで…。

元画像の作り方。 :

メモしておかないと作業手順を忘れそうなので一応メモしておく。 *1

今回は、GIMP 2.10.22 x65 Portable samj版を使って作業した。

まずは、ループ部分になる画像を用意する。今回は 1280x720 のウインドウサイズで表示するので、ループ部分も 1280x720 のサイズにしておいた。

make_ss01.png


横方向に並べる。フィルター → カラーマッピング → 並べる、を選択。ちなみに、GIMP 2.8 の場合は、カラーマッピングではなくてマップになってた気がする。

make_ss02.png


11枚とか15枚とかそのぐらいの数を並べる。単位を「%」にすると楽。

make_ss03.png


ずらりと横に並んだ画像ができた。

make_ss04.png


奥のほうをちょっと暗めにしておくと後々遠近感が出るので、グラデーションツールで少し化粧する。

make_ss05.png


ここから遠近感をつけた変形をするけれど、ガイドを作って、制御点をガイドに吸着させると作業が楽。画像 → ガイド → 均等にガイド、を選択。この「均等にガイド」は追加スクリプト。

make_ss06.png


_均等にガイド(Grid of guides)

ちなみに、かつて日本のGeoCitiesで公開されていた 「GIMP2を使おう」というサイトは、GeoCities のサービス終了で消滅してしまったのだけど、GeoLog Project のおかげで閲覧だけなら今でも可能らしい。ありがたや…。

_GeoLog Project

閑話休題。遠近感をつけて変形させる。遠近法ツールを選択。

make_ss07.png


遠近感をつけた変形ができた。ポイントとしては、台形の幅の広い辺(この場合は下辺)が、画面横幅(今回は1280ドット)よりちょっと狭い程度の長さになるようにしておくと、最終的な画像の横幅が画面2枚分よりは少なくなってイイ感じかもしれない。

make_ss08.png

切り抜きツールを選択。サイズは固定にして、(画面横幅 x 2) x 任意の縦幅、を指定。

make_ss09.png


画像の左半分に初期状態の見た目が収まるような配置にする。

make_ss10.png


Enterキーを叩いて切り抜きを実行。画像が得られた。

make_ss11.png


それにしても、なんだか作業が富豪的というか…。メガドラ時代は Photoshop の類は使えなくて、なんでもかんでもドットエディタで頑張ってた記憶があるので、当時のツールでこういう画像を作ろうとしたら結構大変だったのではないかしらん。いや、でも、数年後のPS1やSS向けの開発では Photoshop をガンガン使ってた記憶も…。メガドラも末期の開発では Photoshop 等を使えたのだろうか。どうなんだろう。そういえばX68Kも既にあったっけ…。

*1: いやまあ、メモしてどうするんだという気もするけど…。今後、新規にこんな画像を作らなければいけない機会はまず無いだろうけど…。

#2 [love2d] Firefox 92.0 で love.js が動かない

love2d用の .love ファイルは、LoVE Web Builder というオンラインサービス、love.js というプログラムを使うことで、Webブラウザ上でも動かせる状態に変換できるのだけど。

_LoVE Web Builder - Home
_Davidobot/love.js: LOVE ported to the web using Emscripten, updated to the latest Emscripten and LOVE (v11.3)

しかし、以前日記ページにアップロードしていた love.js使用ファイル群が、Firefox 92.0 64bit上で動かなくなっていた…。環境は Windows10 x64 21H1。ちなみに、Google Chrome 93.0.4577.82 64bit なら動く。Firefox だと動かない。以前の Firefox なら動いていたのだけどな…。なんでだろ。

_love2dをWebブラウザ上で動かしたい
_love.jsをnpm経由でインストールしてみた

当時と今とでは、WebサーバのバージョンとOS種類が違っているけど…。以前は、Apache2 2.2.31-3vl6 + Vine Linux 6.5 32bit だった。と思う。たぶん。今現在は、Apache2 2.4.38-3+deb10u5 + Debian Linux 10 buster 32bit。そのあたりは関係しているのか、いないのか。

Firefox上でF12キーを押して、ウェブ開発ツールを表示して、コンソールに切り替えてみたところ、以下のエラーメッセージが出ていた。
Error: Could not initialize SDL joystick subsystem (Could not set gamepad connect callback)

ジョイスティックなんて使ってないんだけどな…。

これが不思議なことに、ローカル環境(Windows10 x64 21H1上)で Python 3.9.5 64bit を使って簡易httpサーバを立ち上げて、Firefox で該当ページ(http://localhost:8000/)を開くと、同じ .html + .js なのに動作してしまう…。
python -m http.server 8000

また、 _LoVE Web Builder の Run a LoVE Project で .loveファイルを渡して動作確認してみると、そちらでも動いてしまう。何故。Webサーバの設定に問題があるのだろうか…?

とりあえずの対策。 :

ググっていたら、以下のやり取りに遭遇。

_Error: Could not initialize SDL joystick subsystem on Firefox : love2d

ジョイスティック関連でエラーが出ていて、しかし元々のスクリプト内でジョイスティックを使っていないなら、conf.lua の中でジョイスティック用モジュールを無効化することで状況が変わるかもしれない、具体的には以下を記述せよ、とのことで。
-- at conf.lua
function love.conf(t)
  t.modules.joystick = false
end

試してみたところ、この対応で一応動作するようになった。でも、どうしてこんなことになるんだろう…。

今までアップロードしてたそれぞれをアップロードし直し。 :

今までアップロードしてたそれぞれを、conf.lua を修正した状態でアップロードしておいた。

_helloworld_like_tic80
_cubic_bezier
_snake_lovewebbuilder
_05_fake_rasterscroll_e

後で過去ページも修正しておかないと…。

以上、1 日分です。

過去ログ表示

Prev - 2021/09 - Next
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project