2021/09/15(水) [n年前の日記]
#1 [love2d] love2dで疑似ラスタースクロール
_love2d 11.3
を使って、疑似的にラスタースクロールっぽい見た目の処理ができるか試してみた。環境は Windows10 x64 21H1。
ちなみに、Shader を使った実装は以前試してみたことがあるのだけど。
_love2dのShaderについて試していたり
GLSLで処理を書くのは結構シンドイ感じがして、もうちょっと分かりやすくできないものかと…。
例えばメガドライブでは、特定のメモリ領域にBG(BackGround、背景)のライン毎の横スクロール値をずらずらと列挙しておくと、画面にBGが表示される際に、そのスクロール値群に従って自動(?)でラスタースクロール(ラインスクロール)してくれたわけで。ファミコンみたいに0番スプライトがどうとか考えなくていいので楽ちん。後は、メモリにどんな値を入れておくのか、そこだけを試行錯誤すれば済んだ。
love2d で処理を書く際も、配列にスクロール値をずらずらと指定しておくだけで、そのスクロール値群に従ってラスタースクロールができたら…。そういう状態なら実験するのも楽だろうなと。
そんなわけで、似たようなことができないか実験。
こんな感じになった。
_main.lua
_conf.lua
使用画像。
_bg_1280x720.png
実行すると以下のような見た目になった。
1280x720のウインドウサイズで実行したので、720個もスプライト相当を描画しているはずだけど、AMD Ryzen 7 1700 + GeForce GTX 1060 6GB の環境では60FPSで動いてくれた。
さて、これで別の実験に進むことができそう…。
ちなみに、Shader を使った実装は以前試してみたことがあるのだけど。
_love2dのShaderについて試していたり
GLSLで処理を書くのは結構シンドイ感じがして、もうちょっと分かりやすくできないものかと…。
例えばメガドライブでは、特定のメモリ領域にBG(BackGround、背景)のライン毎の横スクロール値をずらずらと列挙しておくと、画面にBGが表示される際に、そのスクロール値群に従って自動(?)でラスタースクロール(ラインスクロール)してくれたわけで。ファミコンみたいに0番スプライトがどうとか考えなくていいので楽ちん。後は、メモリにどんな値を入れておくのか、そこだけを試行錯誤すれば済んだ。
love2d で処理を書く際も、配列にスクロール値をずらずらと指定しておくだけで、そのスクロール値群に従ってラスタースクロールができたら…。そういう状態なら実験するのも楽だろうなと。
そんなわけで、似たようなことができないか実験。
- BG相当に使う元画像を、横1ライン毎にスプライト扱いにして(Quad を指定してスプライトシートっぽく切り出す)。
- 画面横幅 x 縦1ドットのスプライトを、画面の縦幅分、上から下までずらりと描画。
こんな感じになった。
_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("bg_1280x720.png")
-- make Quad (raster)
imgs = {}
bg_x = {}
for i=1,scr_h do
local x = 0
local y = i - 1
imgs[i] = love.graphics.newQuad(x, y, scr_w, 1, img:getDimensions())
bg_x[i] = 0
end
ang = 0
end
-- update
function love.update(dt)
-- set bg_x
for i=1,scr_h do
a = ang + 2 * (i-1)
bg_x[i] = 16 * math.sin(math.rad(a))
end
ang = ang + 360 * dt
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 raster
love.graphics.setColor(1.0, 1.0, 1.0)
for i=1,scr_h do
love.graphics.draw(img, imgs[i], bg_x[i], (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.window.fullscreen = true -- t.window.fullscreentype = "exclusive" end
使用画像。
_bg_1280x720.png
実行すると以下のような見た目になった。
1280x720のウインドウサイズで実行したので、720個もスプライト相当を描画しているはずだけど、AMD Ryzen 7 1700 + GeForce GTX 1060 6GB の環境では60FPSで動いてくれた。
さて、これで別の実験に進むことができそう…。
[ ツッコむ ]
以上です。