LÖVE (Love2D) 入門編:4.画面サイズの設定

(2018.1.28. 公開)

1. 画面サイズは実行環境によって違う

 LÖVE の画面サイズは実行環境によって異なる。Windows, Mac では(他に何も指定しなければ)800x600、ラズパイではその時の画面サイズになる。なお、画面サイズは、下のプログラムを実行すればわかる。string.format() は Lua の組み込み関数の一つ。

-- サンプルプログラム 4-01 main.lua
function love.draw()
  width = love.graphics.getWidth()    -- 現在の画面の横幅
  height = love.graphics.getHeight()  -- 現在の画面の高さ
  love.graphics.print(string.format("%d,%d", width, height), 0, 0)
end

 こんな風になります。左上に小さく "800,600" と表示されています。(見やすくするため、白黒反転で表示しています。本当は黒地に白で表示されています。)

 画面サイズが固定されていないと、ゲームの画面をデザインする時にとても面倒なことになる。幸い、LÖVE では拡大・縮小表示がとても簡単にできる。そこで、ゲームの画面サイズは適当な値に固定しておき、表示の際に全体を拡大・縮小して画面に合わせることにしよう。

2. 表示の時に拡大・縮小する

 ゲームの画面サイズを 400x300 とする。Windows, Mac の環境だとちょうど実画面の半分の解像度になる。ラズパイだと中途半端な倍率になるが、ゲームが動き出したら案外違和感はないものです。

 拡大・縮小表示するためには、love.graphics.scale() を使う。love.draw() で描画する前にこれで拡大率を設定しておけば、それ以降のすべての描画が指定した倍率で拡大・縮小される。

 なお、Web 上で見つかるコード例を見ると、love.draw() の最初に love.graphics.push() でその時点での拡大率を保存しておき、love.draw() の終了直前に love.graphics.pop() で復帰しているものがあるが、この処理は不要。love.graphics.scale() の効果は love.draw() が終了するまで、とドキュメントに明記されている。

-- サンプルプログラム 4-02 main.lua
function love.load()
  width = 400                         -- ゲーム画面の横幅
  height = 300                        -- ゲーム画面の高さ
  swidth = love.graphics.getWidth()   -- 実画面の横幅
  sheight = love.graphics.getHeight() -- 実画面の高さ
  scalex = swidth / width             -- x 方向の拡大率
  scaley = sheight / height           -- y 方向の拡大率
end
function love.draw()
  love.graphics.scale(scalex, scaley) -- 拡大率を設定
  -- 画面サイズを (width,height) と思って描画する
  love.graphics.print(string.format("%d,%d", width, height), 0, 0)
end

 こんな風になります。表示が大きくなりました。表示にムラがあるけど、これはフォントの設定などとも関係している。なかなか「1ドットずつくっきり見える」ようにはなりません。そこにこだわるのはヤメ、と割り切った方が楽だと思います。(「昔のパソコンみたいな表示」とか「ブラウン管テレビに映った微妙ににじんだ表示」とかにこだわりたい人は、各自研究してくださいませ。)

 これだと、画面の縦横比が 3:4 でない場合には、表示が横長になったり縦長になったりします。それはイヤだという人もいるでしょう。たとえば、800x480 の画面だとこんな風になる。明らかに横長になっている。

 縦横比は一定に保って、必要に応じて左右か上下に空白を入れるようにしよう。原点をずらすためには、love.graphics.translate() を使う。原点移動と拡大の順序を入れ替えると結果が違ってくるので、注意が必要。(左右の枠がわかるように、ゲーム画面いっぱいの大きさの四角形を一緒に描いている。)

-- サンプルプログラム 4-03 main.lua
function love.load()
  width = 400                         -- ゲーム画面の横幅
  height = 300                        -- ゲーム画面の高さ
  swidth = love.graphics.getWidth()   -- 実画面の横幅
  sheight = love.graphics.getHeight() -- 実画面の高さ
  if swidth / sheight > width / height then -- 実画面の方が横長
    scale = sheight / height          -- 縦方向で倍率を決める
    transx = math.floor((swidth - width * scale) / 2)  -- 空白の幅
    transy = 0
  else
    scale = swidth / width            -- 横方向で倍率を決める
    transx = 0
    transy = math.floor((sheight - height * scale) / 2) -- 空白の高さ
  end
end
function love.draw()
  love.graphics.translate(transx, transy) -- 原点移動
  love.graphics.scale(scale, scale) -- 拡大率を設定
  -- 画面サイズを (width,height) と思って描画する
  love.graphics.print(string.format("%d,%d", width, height), 0, 0)
  love.graphics.rectangle("line", 0, 0, width, height)  -- 枠の四角を描く
end

 原点をずらす量(空白の幅)を計算する時に math.floor() を使っている。これも Lua の組み込み関数で、数値の小数点以下を切り捨てて整数にするもの(正確には、「その数値を越えない最大の整数値」を返すので、負の数の場合は切り上げになる)。love.graphics.translate() に与える数値はなるべく整数値に丸めておく方がよい。

目次