Difference between revisions of "TLfres (日本語)"

m (よくある質問と回答)
m
Line 1: Line 1:
 
== TLfres について ==
 
== TLfres について ==
TLfres の目的は[http://dl.dropbox.com/u/3713769/web/Love/TLTools/TLfres%20pic.png 任意のゲームを任意の画面解像度で実行]できるように作成することを非常に容易にすることです。これを使用してもグラフィックスのコード書き直しは要求されません!
+
TLfres の目的は[http://dl.dropbox.com/u/3713769/web/Love/TLTools/TLfres%20pic.png 指定の画面解像度でゲームを実行]できるように作成することを非常に容易にすることです。これを使用してもグラフィックスのコード書き直しは要求されません!
  
 
このライブラリの使用条件は [http://www.opensource.org/licenses/zlib-license.php ZLIB ライセンス]です。
 
このライブラリの使用条件は [http://www.opensource.org/licenses/zlib-license.php ZLIB ライセンス]です。
 
=== ダウンロード ===
 
[http://dl.dropbox.com/u/3713769/web/Love/TLTools/TLfres.lua Dropbox から直接入手]
 
 
=== 連絡先 ===
 
* [http://love2d.org/forums/viewtopic.php?f=5&t=2900 フォーラムのスレッド]
 
* Taehl - SelfMadeSpirit@gmail.com
 
  
 
== 準備 ==
 
== 準備 ==
モジュールにある全ての関数は TLfres 名前空間に存在しており、従ってグローバル変数への干渉を心配する必要はありません。ゲームでは LÖVE 標準解像度である 800x600 を使用して構築されている仮定します:
+
モジュールにある全ての関数は TLfres 名前空間に存在しており、従ってグローバル変数への干渉を心配する必要はありません。ゲームでは LÖVE 標準解像度である 800×600 を使用して構築されている仮定します:
  
# あなたのゲームのフォルダへ TLfres.lua を配置します。
+
# ゲームのフォルダへ tlfres.lua を保存します。
# main.lua の先頭へ、 <code>require"TLfres"</code> の行を追加します。
+
# main.lua の先頭へ <code>local TLfres = require "tlfres"</code> の行を追加します。
# love.draw() の始行へ、 <code>TLfres.transform()</code> の行を追加します。
+
# love.draw() の始行へ <code>TLfres.beginRendering(800, 600)</code> の行を追加します。
# love.draw() の終行へ、 <code>TLfres.letterbox(4,3)</code> の行を追加します。
+
# love.draw() の終行へ <code>TLfres.endRendering()</code> の行を追加します。
 +
# 現在の尺度係数値が必要ならば、 <code>TLfres.getScale(800, 600)</code> を呼び出してください。
 +
# love.mouse.getPosition を呼び出すのではなく <code>TLfres.getMousePosition(800, 600)</code> を呼び出してください。
 +
# love.graphics.setPointSize(x) を呼び出すのではなく <code>love.graphics.setPointSize(x * TLfres.getScale())</code> を呼び出してください (Love は点の大きさを自動的に変更しません)
  
 
== よくある質問と回答 ==
 
== よくある質問と回答 ==
; Q) 何故、これを [[love.graphics.scale (日本語)|love.graphics.scale]] の代わりに使用する必要があるのですか?
+
; Q) この関数を [[love.graphics.scale (日本語)|love.graphics.scale]] の代わりに使う理由は?
: A) 与えられた解像度にて画面を等しく伸張するには技巧的な算術を要求されますが、 TLfres ではそれを処理することができるからです。さらに、ほとんどの人々は伸張されたグラフィックスを嫌います。 ― そのため、 TLfresの letterboxing (レターボックス化) オプションを使用するべきです。画面を伸張する代わりに、正確な比率で大きさを変更し、必要であれば上部&下部へ暗幕帯を描画します。
+
: A) 指定解像度にて画面を等しく伸張するには技巧的な算術を要求されますが、 TLfres ではそれを処理することができるからです。さらに、ほとんどの人々は伸張されたグラフィックスを嫌います。 ― そのため、 TLfres の letterboxing (レターボックス化) オプションを使用するべきです。画面を伸張する代わりに、正確な比率で大きさを変更し、必要であれば上部と下部へ暗幕帯を描画します。
  
 
; Q) どの解像度 / アスペクト比率に対応していますか?  
 
; Q) どの解像度 / アスペクト比率に対応していますか?  
: A) 理論上は、全てです。しかしながら、幅より高さのある画面を使用する場合はレターボックスに作用します。
+
: A) 全部対応しています。
  
; Q) 非標準の解像度を使用してゲームを作成しました。それを TLfres にて動作させるために全部変更する必要がありますか?
+
; Q) 非標準の解像度を使用してゲームを作成しました。 TLfres に対応するために全部変更しなければらないのでしょうか?
: A) いいえ! ゲーム構築時の解像度にて単に TLfres.setScreen() を呼び出してください(後述を参照)。
+
: A) いいえ! ゲーム構築時の解像度で TLfres.beginRendering() を呼び出してください (詳細は後述)。
  
 
== 関数 ==
 
== 関数 ==
==== TLfres.setScreen ====
+
==== TLfres.beginRendering ====
<source lang="lua">TLfres.setScreen(mode, extent, centered, stretch)</source>
+
<source lang="lua">TLfres.beginRendering(width, height, centered)</source>
これを [[love.graphics.setMode (日本語)|love.graphics.setMode]] の代わりに呼び出してください! これは TLfres の構成および解像度の変更の両方を行います。 LÖVE の標準画面である 800x600 を使用してゲームを作成した場合は、一切の引数を使用する必要はありません。
+
なにか描画する前に [[love.draw (日本語)|love.draw]]() の一行目で、この関数を呼び出してください。これは現在の画面解像度で必要とされる尺度と座標変換 (並進移動) です。絶対画面座標で描画する場合は、この関数の呼び出し前 (または endRendering() の呼び出し後) に描画処理をしてください。
{{param|table|mode| }}このテーブルは画面形状を指定します。それは次のデータを内包しています: w (ピクセル単位での画面の幅), h (ピクセル単位での画面の高さ), full (全画面表示を使用するか否か), vsync (垂直同期を使用するか否か), aa (アンチエイリアシング・サンプルの使用量)。標準では <code>{w=800, h=600, full=false, vsync=false, aa=0}</code> です。
+
{{param|number|width|対象となる Canvas の幅。}}
{{param|number|extent (800)| }}元々ゲームが使用するプログラムされた画面の幅です。また、 TLfres を使用して新しいゲームを制作していれば、この数値はコードにおいて希望する画面幅を表現することができます。例えば、私が数値の 1 を使用するのを好むのであれば、従って全座標の規格化は十進数になります(これはほぼ私のセンスです)。百分率など…を好むのであれば、考慮することで 100 を使用することもできます(この場合は画面中央の x=50 へ何かを描画することです)
+
{{param|number|height|対象となる Canvas の高さ。}}
{{param|boolean|centered (false)| }}false であれば、 LOVE の標準と同じく座標 0, 0 は画面の左上に位置します。 true であれば座標 0, 0 は画面中央になります。既存のゲームへ TLfres を追加するならば false にすべきですが、新しいゲームを制作時にはお好みで設定ができる場合があります。
+
{{param|boolean|centered (false)|true ならば  (0, 0) の座標は Canvas の中央となり、そうでなければ左上角となります。}}
{{param|boolean|stretch (false)| }}true であれば、いかなる解像度であろうと全画面表示で補填するために伸張されます。ゲームで使用するためにプログラムされたアスペクト比率が画面のアスペクト比率と異なる場合は、伸張が発生します。一部の人々はレターボックス化よりこれを好みますが、従って、それは個人の趣味の問題です。伸張されない場合は love.draw() の終行に TLfres.letterbox() が呼ばれているかどうか確認してください。
+
 
 +
==== TLfres.endRendering ====
 +
<source lang="lua">TLfres.endRendering(letterboxColor)</source>
 +
すべて描画した後に [[love.draw (日本語)|love.draw]]() の最終行で、この関数を呼び出してください。画面表示範囲外にあるグラフィックスのトリミングをするためにレターボックスを描画します。デフォルトのレターボックスは黒色です。
 +
{{param|table|letterboxColor ({0,0,0, 255})|レターボックスの配色を RGBA で指定します ([[love.graphics.setColor (日本語)#Function 2|love.graphics.setColor]] と同じです)。デフォルトは黒色です。}}
 +
 
 +
==== TLfres.getScale ====
 +
<source lang="lua">TLfres.getScale(width, height)</source>
 +
{{param|number|width|コードで指定された Canvas の幅。}}
 +
{{param|number|height|コードで指定された Canvas の高さ。}}
 +
 
 +
==== TLfres.getMousePosition ====
 +
<source lang="lua">TLfres.getMousePosition(width, height)</source>
 +
これは通常、 [[love.mouse.getPosition (日本語)|love.mouse.getPosition]] を呼び出すときに使用してください。返される位置は指定の寸前になります。
 +
{{param|number|width|コードで指定された Canvas の幅。}}
 +
{{param|number|height|コードで指定された Canvas の高さ。}}
 +
 
 +
== tlfres.lua ==
 +
<source lang="lua">
 +
local lwGetMode    = _G.love.window.getMode
 +
local lgPush        = _G.love.graphics.push
 +
local lgPop        = _G.love.graphics.pop
 +
local lgTranslate  = _G.love.graphics.translate
 +
local lgScale      = _G.love.graphics.scale
 +
local lgRectangle  = _G.love.graphics.rectangle
 +
local lgSetColor    = _G.love.graphics.setColor
 +
local lmGetPosition = _G.love.mouse.getPosition
 +
local min = math.min
 +
 
 +
local TLfres = {}
 +
 
 +
local lastMouseX, lastMouseY = 0, 0
 +
local currentlyRendering
 +
 
 +
-- 内部ヘルパー関数
 +
local function _getRawMousePosition(width, height)
 +
  local x, y = lmGetPosition()
 +
  local w, h = lwGetMode()
 +
  local scale = min(w/width, h/height)
 +
  return (x - (w - width * scale) * 0.5)/scale, (y - (h - height * scale) * 0.5)/scale
 +
end
 +
 
 +
-- これは通常、 love.mouse.getPosition を呼び出すときに使用してください。
 +
-- 返される位置は指定の寸前になります。
 +
function TLfres.getMousePosition(width, height)
 +
  local x, y = _getRawMousePosition(width, height)
 +
  if x >= 0 and x <= width and y >= 0 and y <= height then
 +
      lastMouseX, lastMouseY = _getRawMousePosition(width, height)
 +
  end
 +
  return lastMouseX, lastMouseY
 +
end
  
==== TLfres.transform ====
+
--
<source lang="lua">TLfres.letterbox(w, h, c)</source>
+
-- 希望する寸法と現在の寸法から現在の尺度を計算します。
何かを描画する前に、これを [[love.draw (日本語)|love.draw]]() の一番最初の行で呼び出してください。現在の画面解像度により必要とする画面座標を拡大・縮小および並進移動をします。絶対的な画面座標で何かを描画したい場合は、 TLfres.transform() を呼び出す前に [[love.graphics.push (日本語)|love.graphics.push]]() を使用したいと思うかもしれません。
+
-- レンダリングブロックから呼び出す場合は、引数 width と height は必要に応じて指定してください。
 +
function TLfres.getScale(width, height)
 +
  if currentlyRendering then
 +
      width  = width  or currentlyRendering[1]
 +
      height = height or currentlyRendering[2]
 +
  end
 +
  local w, h = lwGetMode()
 +
  return min(w/width, h/height)
 +
end
  
==== TLfres.letterbox ====
+
-- 拡大と中央揃えにより現在のウィンドウに width×height を収めます。
<source lang="lua">TLfres.letterbox(w, h, c)</source>
+
-- 0,0 は Canvas の左上です。また centered が true ならば中央になります。
グラフィックスの伸張を行わない場合は ( TLfres.setScreen() を参照)、全描画後に、これを [[love.draw (日本語)|love.draw]]() の終行にて呼び出してください。これは画面外にある余白のグラフィックスを整えるためにレターボックスを描画します。それは標準でアスペクト比率 4:3 の黒色のレターボックスになります。
+
-- この関数は love.graphics.push の前とレンダリング後 love.graphics.pop の次行で使用してください。
{{param|number|w (4)|ゲームでの幅に対するアスペクト比率を意味します。}}
+
function TLfres.beginRendering(width, height, centered)
{{param|number|h (3)|ゲームでの高さに対するアスペクト比率を意味します。}}
+
  if currentlyRendering then
{{param|table|c {0,0,0, 255}|レターボックスの配色であり、 RGBA ([[love.graphics.setColor (日本語)|love.graphics.setColor]] と同様) にて指定します。標準では黒色です。}}
+
      error("Must call tlfres.endRendering before calling beginRendering.")
 +
      return
 +
  end
 +
  currentlyRendering = {width, height}
 +
  lgPush()
  
{{#set:LOVE Version=0.7.0}}
+
  local w, h = lwGetMode()
{{#set:Description=簡単に使えて画像伸張を行わずにゲームを任意の画面解像度で実行します。}}
+
  local scale = min(w/width, h/height)
 +
  lgTranslate((w - width * scale) * 0.5, (h - height * scale) * 0.5)
 +
  lgScale(scale)
 +
  if centered then
 +
      lgTranslate(0.5 * width, 0.5 * height)
 +
  end
 +
  return scale
 +
end
 +
 
 +
local _black = {0, 0, 0, 255}
 +
 
 +
-- 座標変換から復帰します。letterboxColor が true ならば黒色でレターボックスの暗幕を描画します。
 +
-- letterboxColor には {r, g, b, a} テーブルを指定できます。
 +
function TLfres.endRendering(letterboxColor)
 +
  if not currentlyRendering then
 +
      error("Must call tlfres.beginRendering before calling endRendering.")
 +
      return
 +
  end
 +
  local width, height = currentlyRendering[1], currentlyRendering[2]
 +
  currentlyRendering = nil
 +
  lgPop()
 +
 
 +
  local w, h = lwGetMode()
 +
  local scale = min(w/width, h/height)
 +
  width, height = width * scale, height * scale
 +
 
 +
  lgSetColor(letterboxColor or _black)
 +
  lgRectangle("fill", 0, 0,  w,  0.5 * (h - height)) -- 上
 +
  lgRectangle("fill", 0, h,  w, -0.5 * (h - height)) -- 下
 +
  lgRectangle("fill", 0, 0,  0.5 * (w - width), h)  -- 左
 +
  lgRectangle("fill", w, 0, -0.5 * (w - width), h)  -- 右
 +
end
 +
 
 +
return TLfres
 +
</source>
 +
 
 +
== 用例 ==
 +
<source lang="lua">
 +
local TLfres = require "tlfres"
 +
 
 +
local CANVAS_WIDTH = 800
 +
local CANVAS_HEIGHT = 600
 +
local POINT_SIZE = 1
 +
 
 +
function love.mouse.getPosition() -- 標準関数をヘルパー関数でオーバーライドします。
 +
  return TLfres.getMousePosition(CANVAS_WIDTH, CANVAS_HEIGHT)
 +
end
 +
 
 +
function love.draw()
 +
  tlfres.beginRendering(CANVAS_WIDTH, CANVAS_HEIGHT)
 +
 
 +
      love.graphics.setPointSize(tlfres.getScale()*POINT_SIZE) -- 点の大きさは自動的に変更されませんので、手動で乗算をしてください。
 +
      love.graphics.points(400, 300) -- 画面寸法の変更に関係なく描画は Canvas の中心で行います。
 +
 
 +
  tlfres.endRendering() -- 黒色でレターボックスを描画します。
 +
end
 +
</source>
 +
 
 +
{{#set:LOVE Version=0.10.2}}
 +
{{#set:Description=簡単に使えて画像伸張を行わずにゲームを指定の画面解像度で実行します。}}
 
{{#set:License=ZLIB license}}
 
{{#set:License=ZLIB license}}
 
{{#set:Author=User:Taehl}}
 
{{#set:Author=User:Taehl}}
 
[[Category:Libraries (日本語)]]
 
[[Category:Libraries (日本語)]]
 
== そのほかの言語 ==
 
{{i18n|TLfres}}
 

Revision as of 09:39, 18 December 2019

TLfres について

TLfres の目的は指定の画面解像度でゲームを実行できるように作成することを非常に容易にすることです。これを使用してもグラフィックスのコード書き直しは要求されません!

このライブラリの使用条件は ZLIB ライセンスです。

準備

モジュールにある全ての関数は TLfres 名前空間に存在しており、従ってグローバル変数への干渉を心配する必要はありません。ゲームでは LÖVE 標準解像度である 800×600 を使用して構築されている仮定します:

  1. ゲームのフォルダへ tlfres.lua を保存します。
  2. main.lua の先頭へ local TLfres = require "tlfres" の行を追加します。
  3. love.draw() の始行へ TLfres.beginRendering(800, 600) の行を追加します。
  4. love.draw() の終行へ TLfres.endRendering() の行を追加します。
  5. 現在の尺度係数値が必要ならば、 TLfres.getScale(800, 600) を呼び出してください。
  6. love.mouse.getPosition を呼び出すのではなく TLfres.getMousePosition(800, 600) を呼び出してください。
  7. love.graphics.setPointSize(x) を呼び出すのではなく love.graphics.setPointSize(x * TLfres.getScale()) を呼び出してください (Love は点の大きさを自動的に変更しません)

よくある質問と回答

Q) この関数を love.graphics.scale の代わりに使う理由は?
A) 指定解像度にて画面を等しく伸張するには技巧的な算術を要求されますが、 TLfres ではそれを処理することができるからです。さらに、ほとんどの人々は伸張されたグラフィックスを嫌います。 ― そのため、 TLfres の letterboxing (レターボックス化) オプションを使用するべきです。画面を伸張する代わりに、正確な比率で大きさを変更し、必要であれば上部と下部へ暗幕帯を描画します。
Q) どの解像度 / アスペクト比率に対応していますか?
A) 全部対応しています。
Q) 非標準の解像度を使用してゲームを作成しました。 TLfres に対応するために全部変更しなければらないのでしょうか?
A) いいえ! ゲーム構築時の解像度で TLfres.beginRendering() を呼び出してください (詳細は後述)。

関数

TLfres.beginRendering

TLfres.beginRendering(width, height, centered)

なにか描画する前に love.draw() の一行目で、この関数を呼び出してください。これは現在の画面解像度で必要とされる尺度と座標変換 (並進移動) です。絶対画面座標で描画する場合は、この関数の呼び出し前 (または endRendering() の呼び出し後) に描画処理をしてください。

number width
対象となる Canvas の幅。
number height
対象となる Canvas の高さ。
boolean centered (false)
true ならば (0, 0) の座標は Canvas の中央となり、そうでなければ左上角となります。

TLfres.endRendering

TLfres.endRendering(letterboxColor)

すべて描画した後に love.draw() の最終行で、この関数を呼び出してください。画面表示範囲外にあるグラフィックスのトリミングをするためにレターボックスを描画します。デフォルトのレターボックスは黒色です。

table letterboxColor ({0,0,0, 255})
レターボックスの配色を RGBA で指定します (love.graphics.setColor と同じです)。デフォルトは黒色です。

TLfres.getScale

TLfres.getScale(width, height)
number width
コードで指定された Canvas の幅。
number height
コードで指定された Canvas の高さ。

TLfres.getMousePosition

TLfres.getMousePosition(width, height)

これは通常、 love.mouse.getPosition を呼び出すときに使用してください。返される位置は指定の寸前になります。

number width
コードで指定された Canvas の幅。
number height
コードで指定された Canvas の高さ。

tlfres.lua

local lwGetMode     = _G.love.window.getMode
local lgPush        = _G.love.graphics.push
local lgPop         = _G.love.graphics.pop
local lgTranslate   = _G.love.graphics.translate
local lgScale       = _G.love.graphics.scale
local lgRectangle   = _G.love.graphics.rectangle
local lgSetColor    = _G.love.graphics.setColor
local lmGetPosition = _G.love.mouse.getPosition
local min = math.min

local TLfres = {}

local lastMouseX, lastMouseY = 0, 0
local currentlyRendering

-- 内部ヘルパー関数
local function _getRawMousePosition(width, height)
   local x, y = lmGetPosition()
   local w, h = lwGetMode()
   local scale = min(w/width, h/height)
   return (x - (w - width * scale) * 0.5)/scale, (y - (h - height * scale) * 0.5)/scale
end

-- これは通常、 love.mouse.getPosition を呼び出すときに使用してください。
-- 返される位置は指定の寸前になります。
function TLfres.getMousePosition(width, height)
   local x, y = _getRawMousePosition(width, height)
   if x >= 0 and x <= width and y >= 0 and y <= height then
      lastMouseX, lastMouseY = _getRawMousePosition(width, height)
   end
   return lastMouseX, lastMouseY
end

-- 
-- 希望する寸法と現在の寸法から現在の尺度を計算します。
-- レンダリングブロックから呼び出す場合は、引数 width と height は必要に応じて指定してください。
function TLfres.getScale(width, height)
   if currentlyRendering then
      width  = width  or currentlyRendering[1]
      height = height or currentlyRendering[2]
   end
   local w, h = lwGetMode()
   return min(w/width, h/height)
end

-- 拡大と中央揃えにより現在のウィンドウに width×height を収めます。
-- 0,0 は Canvas の左上です。また centered が true ならば中央になります。
-- この関数は love.graphics.push の前とレンダリング後 love.graphics.pop の次行で使用してください。
function TLfres.beginRendering(width, height, centered)
   if currentlyRendering then
      error("Must call tlfres.endRendering before calling beginRendering.")
      return
   end
   currentlyRendering = {width, height}
   lgPush()

   local w, h = lwGetMode()
   local scale = min(w/width, h/height)
   lgTranslate((w - width * scale) * 0.5, (h - height * scale) * 0.5)
   lgScale(scale)
   if centered then
      lgTranslate(0.5 * width, 0.5 * height)
   end
   return scale
end

local _black = {0, 0, 0, 255}

-- 座標変換から復帰します。letterboxColor が true ならば黒色でレターボックスの暗幕を描画します。
-- letterboxColor には {r, g, b, a} テーブルを指定できます。
function TLfres.endRendering(letterboxColor)
   if not currentlyRendering then
      error("Must call tlfres.beginRendering before calling endRendering.")
      return
   end
   local width, height = currentlyRendering[1], currentlyRendering[2]
   currentlyRendering = nil
   lgPop()

   local w, h = lwGetMode()
   local scale = min(w/width, h/height)
   width, height = width * scale, height * scale

   lgSetColor(letterboxColor or _black)
   lgRectangle("fill", 0, 0,  w,  0.5 * (h - height)) -- 上
   lgRectangle("fill", 0, h,  w, -0.5 * (h - height)) -- 下
   lgRectangle("fill", 0, 0,  0.5 * (w - width), h)   -- 左
   lgRectangle("fill", w, 0, -0.5 * (w - width), h)   -- 右
end

return TLfres

用例

local TLfres = require "tlfres"

local CANVAS_WIDTH = 800
local CANVAS_HEIGHT = 600
local POINT_SIZE = 1

function love.mouse.getPosition() -- 標準関数をヘルパー関数でオーバーライドします。
   return TLfres.getMousePosition(CANVAS_WIDTH, CANVAS_HEIGHT)
end

function love.draw()
   tlfres.beginRendering(CANVAS_WIDTH, CANVAS_HEIGHT)

      love.graphics.setPointSize(tlfres.getScale()*POINT_SIZE) -- 点の大きさは自動的に変更されませんので、手動で乗算をしてください。
      love.graphics.points(400, 300) -- 画面寸法の変更に関係なく描画は Canvas の中心で行います。

   tlfres.endRendering() -- 黒色でレターボックスを描画します。
end