2017/11/01(水) [n年前の日記]
#1 [love2d][lua][raspberrypi] love2dでフルスクリーン表示のテスト
love2dでフルスクリーン表示ができそうか動作確認中。
まずは、Windows10 x64 + love2d 0.10.2上で実験。
 まずは、Windows10 x64 + love2d 0.10.2上で実験。
◎ フルスクリーン表示の標準的な指定の仕方について。 :
love2d は、フルスクリーン表示を指定できる。まずは、標準的な指定方法を試してみる。
使用した画像は以下。License : CC0 ってことで。
_bg_640x480.png
_spaceship_001_64x64.png
ソースは以下。
_conf.lua
_main.lua
結果はこんな感じに。予想通りの表示になった。
使用した画像は以下。License : CC0 ってことで。
_bg_640x480.png
_spaceship_001_64x64.png
ソースは以下。
_conf.lua
function love.conf(t) t.window.width = 640 t.window.height = 480 t.window.title = "Move Sprite Example 02" t.window.vsync = true t.window.fullscreen = true t.window.fullscreentype = "exclusive" endconf.lua の中で以下を指定してるので…。
- t.window.fullscreen = true
- t.window.fullscreentype = "exclusive"
_main.lua
-- sprite move example 02
function love.load()
  -- init
  
  -- get window width and height
  scrw = love.graphics.getWidth()
  scrh = love.graphics.getHeight()
  
  -- load image
  bgimg = love.graphics.newImage("bg_640x480.png")
  playerimg = love.graphics.newImage("spaceship_001_64x64.png")
  
  -- player work
  player = {}
  player.x = scrw / 2
  player.y = scrh / 2
  player.speed = 250
  player.imgw = playerimg:getWidth()
  player.imgh = playerimg:getHeight()
end
function love.update(dt)
  -- update
  
  -- key check
  local ang = -1
  if love.keyboard.isDown("left") then ang = 180
  elseif love.keyboard.isDown("right") then ang = 0
  end
  if love.keyboard.isDown("up") then
    if ang < 0 then ang = 270
    elseif ang == 0 then ang = 270 + 45
    else ang = 180 + 45
    end
  elseif love.keyboard.isDown("down") then
    if ang < 0 then ang = 90
    elseif ang == 0 then ang = 45
    else ang = 180 - 45
    end
  end
  if ang >= 0 then
    local spd = player.speed * dt
    local ra = math.rad(ang)
    player.x = player.x + (spd * math.cos(ra))
    player.y = player.y + (spd * math.sin(ra))
  end
  -- move area check
  local wh = player.imgw / 2
  local hh = player.imgh / 2
  local xmin = wh
  local ymin = hh
  local xmax = scrw - wh
  local ymax = scrh - hh
  player.x = math.min(math.max(player.x, xmin), xmax)
  player.y = math.min(math.max(player.y, ymin), ymax)
end
function love.draw()
  -- draw BG
  love.graphics.setColor(255, 255, 255, 255)
  love.graphics.draw(bgimg, 0, 0)
  -- love.graphics.rectangle("fill", 0, 465, scrw, 150)
  love.graphics.setColor(255, 255, 255, 255)
  
  -- draw player
  ofsx = player.imgw / 2
  ofsy = player.imgh / 2
  love.graphics.draw(playerimg, player.x - ofsx, player.y - ofsy)
  
  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
結果はこんな感じに。予想通りの表示になった。
◎ Raspberry Pi Zero W上で動かすと上手く行かない。 :
上記のソースを、Raspberry Pi Zero W + raspbian stretch + OpenGL ESを使うSDL2 + love2d 0.10.2 で動かしてみる。画面解像度は、1280x720。
酷い結果になった。conf.lua 内で指定したウインドウサイズは無視されて、画面解像度(=1280x720)がウインドウサイズとして取得されてしまっている模様。
酷い結果になった。conf.lua 内で指定したウインドウサイズは無視されて、画面解像度(=1280x720)がウインドウサイズとして取得されてしまっている模様。
◎ 解決策。 :
解決策をググってたら、以下の記事に遭遇した。
_Love2D - Raspberry Pi Forums
_Canvas - LOVE
_love.graphics.setCanvas - LOVE
_Canvas:renderTo - LOVE
_love.graphics.draw - LOVE
ということで、その方法を試してみる。
_conf.lua
_main.lua
結果はこうなった。
アスペクト比の計算をサボってるので、4:3の画面が16:9で引き延ばされて、横に長い見た目になってしまっているけど…。少なくとも、画面一杯に引き延ばして描画することは可能っぽい。
_Love2D - Raspberry Pi Forums
(edit- nevermind, created a workaround!)「仮想スクリーンとして canvas を用意して、そこに描画してから canvas を拡大描画したらそれらしくなった」と言ってるのかな…?
create a low res 'virtual' screen with a canvas.
set its filtering mode to 'nearest' draw all game stuff to there at the end, draw that canvas (scaled up) to the actual high res screen.
result = low res sharp fat pixels on a high res screen.
_Canvas - LOVE
_love.graphics.setCanvas - LOVE
_Canvas:renderTo - LOVE
_love.graphics.draw - LOVE
ということで、その方法を試してみる。
_conf.lua
function love.conf(t) -- t.window.width = 1280 -- t.window.height = 720 t.window.vsync = true t.window.fullscreen = true -- t.window.fullscreentype = "exclusive" end
_main.lua
-- fullscreen disp 01
function love.load()
  -- init
  -- set filter
  love.graphics.setDefaultFilter("nearest", "nearest")
  
  scr_w = 640
  scr_h = 480
  canvas = love.graphics.newCanvas(scr_w, scr_h)
  
  -- get window width and height
  wdw_w = love.graphics.getWidth()
  wdw_h = love.graphics.getHeight()
  
  -- load image
  bgimg = love.graphics.newImage("bg_640x480.png")
  playerimg = love.graphics.newImage("spaceship_001_64x64.png")
  
  -- player work
  player = {}
  player.x = scr_w / 2
  player.y = scr_h / 2
  player.speed = 250
  player.imgw = playerimg:getWidth()
  player.imgh = playerimg:getHeight()
end
function love.update(dt)
  -- update
  
  -- key check
  local ang = -1
  if love.keyboard.isDown("left") then ang = 180
  elseif love.keyboard.isDown("right") then ang = 0
  end
  if love.keyboard.isDown("up") then
    if ang < 0 then ang = 270
    elseif ang == 0 then ang = 270 + 45
    else ang = 180 + 45
    end
  elseif love.keyboard.isDown("down") then
    if ang < 0 then ang = 90
    elseif ang == 0 then ang = 45
    else ang = 180 - 45
    end
  end
  if ang >= 0 then
    local spd = player.speed * dt
    local ra = math.rad(ang)
    player.x = player.x + (spd * math.cos(ra))
    player.y = player.y + (spd * math.sin(ra))
  end
  -- move area check
  local wh = player.imgw / 2
  local hh = player.imgh / 2
  local xmin = wh
  local ymin = hh
  local xmax = scr_w - wh
  local ymax = scr_h - hh
  player.x = math.min(math.max(player.x, xmin), xmax)
  player.y = math.min(math.max(player.y, ymin), ymax)
end
function love.draw()
  -- set canvas
  love.graphics.setCanvas(canvas)
  
  -- draw BG
  love.graphics.setColor(255, 255, 255)
  love.graphics.draw(bgimg, 0, 0)
  -- love.graphics.rectangle("fill", 0, 465, scr_w, 150)
  love.graphics.setColor(255, 255, 255)
  
  -- draw player
  ofsx = player.imgw / 2
  ofsy = player.imgh / 2
  love.graphics.draw(playerimg, player.x - ofsx, player.y - ofsy)
  
  -- unset canvas
  love.graphics.setCanvas()
  -- draw canvas to window
  love.graphics.setColor(255, 255, 255)
  love.graphics.draw(canvas, 0, 0, 0, wdw_w / scr_w, wdw_h / scr_h)
  
  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
結果はこうなった。
アスペクト比の計算をサボってるので、4:3の画面が16:9で引き延ばされて、横に長い見た目になってしまっているけど…。少なくとも、画面一杯に引き延ばして描画することは可能っぽい。
◎ 少し説明。 :
conf.lua 内では…。
この、conf.lua の内容で…。
main.lua 内では…。
canvas への描画は、以下でできるらしい。
ウインドウへのcanvasの描画は、love.graphics.draw() を使う。
- ウインドウサイズの指定をコメントアウト。
- フルスクリーン表示の種類の指定をコメントアウト。
この、conf.lua の内容で…。
- Raspberry Pi Zeor W 上では「とにかくフルスクリーン表示しろ」という指定になる。ウインドウサイズ = 画面解像度。
- Windows10 x64上では、ウインドウサイズはデフォルトの800x600になり、その800x600の画面がフルスクリーン表示される。
main.lua 内では…。
- 初期化処理(love.load()内)で canvas を作成。
- 描画処理(love.draw()内)では、canvas にゲーム画面を描いてから、その canvas をウインドウに拡大しつつ描画。
- 拡大縮小描画はクッキリした見た目にしたかったので、love.graphics.setDefaultFilter("nearest", "nearest") を記述して、nearestフィルタで拡大縮小するように指定。
canvas への描画は、以下でできるらしい。
love.graphics.setCanvas(canvas) (描画処理) love.graphics.setCanvas()
ウインドウへのcanvasの描画は、love.graphics.draw() を使う。
love.graphics.draw(描画したい画像・キャンバス等, 
                   描画位置x, 描画位置y, 
                   描画方向 ,
                   横方向の拡大縮小率, 縦方向の拡大縮小率)
◎ もう少し説明。 :
luaでローカル変数を使いたい時は、local と頭につけるらしい。
三角関数は以下。
最大値、最小値を取り出すなら以下。
Luaは初めて触ってるわけだけど、このあたりは比較的素直な仕様だなと…。
local ang = 0
三角関数は以下。
- math.sin(ラジアン値)
- math.cos(ラジアン値)
- 度からラジアンの変換は、math.rad(角度)
- ラジアンから度への変換は、math.deg(ラジアン値)
最大値、最小値を取り出すなら以下。
- math.min(値1, 値2) : 最小値を返す。
- math.max(値1, 値2) : 最大値を返す。
Luaは初めて触ってるわけだけど、このあたりは比較的素直な仕様だなと…。
[   ツッコむ ]
以上です。


