FAQ (日本語)

恐らく初心者が LÖVE に関して疑問に思うであろうよく尋ねられる質問

いつから LÖVE はありますか?

rude によれば:

実際に、私はそれがどのように始まったか覚えていません。実のところ、いつ始めたのかはよく覚えていません。もしかすると己への挑戦に過ぎないだけなのかもしれません。しかしながら、それがどういう物語であっただろうかということを私に書くことを誰かが強いたならば:

えーと、その頃の私は簡単に使えて、あまり悩むところがない全ての環境で動作する 2D 中心のゲームフレームワークを探しておりましたが、そのどれもが私の要求を満たすものではありませんでした。多くのエンジンと利用可能なフレームワークが存在しましたが、それらは 2D ゲームで使用するのに API に魅力がなく、あまりにも 3D に傾倒していました。そうして私は自分用の API の開発に取り組み始めました。この上なく幸福な麦芽酒のように、ついに子供たちが笑い、共に自由に遊ぶことができる Z 軸を知らぬ輝かしく自由な世界。 *一粒の涙*

……など。


Unity と何が違うの?

あくまで偏った意見ですが、いくつかかいつまんでみます。

  • 2Dゲーム専用のフレームワークです (公式ではそうですが、コミュニティにより VR 対応の LÖVR、 3D 対応の LOVE3D が開発中です)。
  • ビジュアルエディタはありません。統合開発環境もありません。そのかわり、自分の好きな開発環境を構築する楽しみがあります。もちろん頑張ればシューティングゲームエディタなどのユーティリティを製作することも可能です。
  • Zオーダーがありませんので、ライブラリを使うか自分で組む必要があります。愛用者のなかには、フレームワークのお約束を押し付けられないのがいいという人もいます。ゲーム開発に限らない汎用性があるのも魅力の一つです。
  • Unity と違って、開発環境は非常に軽量です。最軽量構成(LOVE2D, Sakura Editor, Grafx2, Tiled, MilkyTracker, Audacity)でしたら 50~100MB くらいのディスク占有量で開発環境の構築が行えます。スティックPC程度のスペックで十分快適に動作しますので負担が少なくて済みます。
  • USBストレージに導入して、出先のネットカフェやゲームジャムでの開発ができます。
  • 開発に使用する言語は Lua ですので、ComputerCraft からの移行先としても十分価値があります。
  • Android スマートフォン、タブレットだけでゲームの開発が行えます(ベネッセ製のチャレンジタブレットシリーズへの導入は未確認ですが、可能だと思います)。

これはほかのゲームエンジンではあまり見かけない特徴です。これによりインディーズゲームデベロッパーの開発環境だけに限らず、一般に広く使われる可能性があります。


また、

  • 軽量な開発環境なので、時代遅れの機材しか導入できいない財政難の自治体では助かります。また、教育機関で大量導入したり、教材を作成するためにも使えますし、生徒間のコミュニケーションツールとして使うこともできます。
  • また、数学や算数嫌いの生徒に、数学はこうやって使うとゲームでも使える実例を提示することにもなると思います。


  • 以上の特性から、開発者の技術力や個性、温かみが出やすいものと思います。

このように、特筆すべき特徴はいくつもあるのに、日本国内ではなかなか価値を理解されないゲームエンジンでもあります。

初心者ですが、なにから学んだらよいのかわかりません。

市販の書籍、あるいは大学の講義資料を探して自分でカリキュラムを組むのも良いです。参考として、下記のもので検索をすれば色々と出てきます。

  • 開発環境環境の構築(ZeroBrane Studio)、基本的なシェル操作 (PowerShell, bash)、ゲームの起動方法
  • プログラミング言語 Lua (テーブル、メタテーブル、コルーチン、テーブル、正規表現など)
  • LOVE 関連 (コールバック、タイマー、ファイルシステム、スレッド、キーボード、ジョイスティック、グラフィックス、イベントなど)
  • ゲームプログラミングの基本概念 (ゲームステート、座標系、当たり判定、パス検索、AI、スプライト、シェーダー、GLSL、ゲーム数学など)
  • コードリーディング
  • 中学程度の基礎英語能力

まず、LOVE Wiki を大まかに読まれることをお勧めします。わからない用語は検索をすれば出てきます。訳文で出てこなければ原文でを検索してください。

次にオープンソースの LOVE ゲームに付属しているソースに手を加えながら、感覚をつかんでいきます。

そして、時間があればノートやブログを学習メモとして活用する。実際にコードを書いて検証しながら LOVE フォーラムの過去ログを読まれることをお勧めします。

毎日と時間を作って取り組もうとしない人、真似が大嫌いな人、やらない言い訳ばかりしてすぐ飽きる人、何かを買っても壊すのを怖がったり買っただけで満足してしまうコレクター体質の人(あなたが成長するためにモノを使い倒すんですよ)、挫折を恐れる人、過去ログを読まない人・検索しない人、コードを書かない人、他人の書いた良質のコードを読まない・真似ないは確実に挫折します。これは学校や資格の勉強と同じです。自分を変えない限りゲームを作ることは難しいです……。

参考までに、早い人で数日から数週間で簡単な古典ゲーム(ブロック崩し、陣取りゲーム、カードゲームなど)を製作できるようなります。普通の人がそれなりのものを作るのでしたら三か月から一年、長くても三年程度です。

どうして LÖVE にはベクトル用のライブラリが実装されていないの?

slime によれば:

ベクトルオブジェクトを LÖVE の API で使用すると発生する主な問題は Lua にあり、頻繁に使用すると大量の不要情報を生成してしまう傾向があります。したがって LÖVE の関数で使用することに対して、それらを要求してしまうと最適な実行効率を妨げてしまうことになります。一部のエンジンではベクトルを実装するために過酷な努力をしてしまいます: https://www.youtube.com/watch?v=wTjyM7d7_YA#t=23m6s

そのせいで更に API が面倒かつ美しくないものになりかねないため、ベクトルに依存した関数の異形を製作することは望んでいません。

もっと議論する


Python のようにオフサイド(インデント)ルールで記述したいのですが

  • luaty を使用してください。これを使用することで then, do, end の記述が不要になるだけでなく、λ式の使用も一部可能になるようです。
  • または MoonScript, a language that compiles to Lua を使用することでオフサイドルール+オブジェクト指向プログラミングが可能になります。

Q. LOVE Wiki の翻訳活動にしたい

A1. いつまでもできるわけではないので、引き継ぎは歓迎します。興味がありましたら https://twitter.com/isvowel までお問い合わせくださいませ。

Q. LOVE に対応しているスプライトアニメーションエディタはありますか?

A1. 商用では Spine があります(購入前に必ず試用版で十分検証してください)。 ※フリーウェアやオープンソースのものは後程掲載します。

A2. 国産スプライトエディタである Webtech 社 OPTPiX SpriteStudio シリーズに関しては LOVE には対応していません(対応しても採算が取れないものと思われます)。 しかし SS5Player シリーズ を LOVE へ移植すれば対応は可能だと思われます。腕に自信のある方はどうぞ。


Q. 初心者に LOVE のプログラミングの初歩を教えるとしたら?

A. 環境構築はともかく……最初に、オープンソースのゲームを交えながら、「ソースファイルの基本構造=require ステートメント+コールバック関数+変数+スコープ+ゲームステート+ドット記法+関数+return文+配列+メタテーブル+再帰+正規表現+ファイルシステム」……は教えてあげてください(ただしいコードスタイルのことです)。そうしない場合は、異世界の住人を召還することになります。:-)

アンチエイリアシングを無効にするには (Disable a blurry)

(TODO: 復帰後に追記。)

よくある質問の一つです。これはエミュレーター、レトロPCからの移植、アップスケーリング処理、 8bit ビデオコンソール風の低解像度のドット絵を使用したゲームで問題 (座標ずれ、余計なフィルタがかかってしまう) になることがあります。 解決方法は下記のとおりです。

内部処理を理解したい

わかっている人や、情報収集・整理に長けていたり、あるいはカンのいい人向けの説明が多いため、どうしても LOVE Wiki の解説では理解できないところが出てくることがあります。そういったときは LOVE ソースコードを読まれたほうが理解がしやすいと思います。

LOVE の基本構造は Lua 処理系に OpenAL, OpenGL, SDL, FreeType などのライブラリを組み込んで扱いしやすくしたフレームワーク(ラッパー)です。フレームワーク自体は C++ で書かれていますが、難易度は高くありません。そのため、これらのライブラリの資料や資産を調べつつ LOVE のソースコードをお読みになられたほうが、より理解を深められるだけでなく将来性や拡張性などの観点各で有利だと考えられます (将来性のない邦訳の改訂、あるいは放置されたり、難しいために解説されにくいサウンドの合成やフォント周りのマイナー機能の記載を待つよりも遥かに良いでしょう)。


図形、線描

function love.draw()
	love.graphics.setLineStyle('smooth')		-- 誤: 線描時のアンチエイリアシング有効化 (デフォルト値)
	love.graphics.line(100, 100, 100, 200)

--	love.graphics.setLineWidth(1)			-- 誤: 線の幅を変えてもフィルタは有効なので効果はありません。
	love.graphics.setLineStyle('rough')		-- 正: 線描時のアンチエイリアシング無効化
	love.graphics.line(200, 100, 200, 200)
end

LOVE のコールバックの正体は?

boot.luaをお読みになられるとわかりますが、その実態は空の無名関数をオーバーライドしたものです(オーバーライドした関数の前に初期化処理が入ります)。それをメインループで順番に呼び出しているわけです。

require

Q. require が正常に動作しません(再帰インクルードを使わない場合)。 A. 下記を確認してください。ほとんどの場合は、これで修正できるでしょう。 それでもだめならば print デバッグを使用して検証してください。

  • 0. require 文の綴りは正しいですか?
  • 1. require 先の文字コードを確認してください。 LOVE/Lua で扱える文字コードは UTF-8 のみであり ShiftJIS は使用できません。
  • 2. require 先のファイルにシンタックスエラーがないかデバッグコンソールを有効にしてエラーを確認してください。
  • 3. require('foobar.lua') となっていませんか? 0.8.0 以降では拡張子を除去して require('foobar') としてください。
  • 4. require 先のファイルの拡張子 .lua はついていますか? ファイルの綴りはあっていますか? パスはあっていますか?
  • 5. 原則として、関数内に require を記述することはできません。 require はファイルの先頭部分に記述してください。
  • 6. require されているファイルが循環参照になっていませんか? Lua 用のインクルードガードを導入してください。
  • 7. 変数名 = require('foobar') となっていますか?
  • 8. require 先のファイルは local 変数名 = {}return 変数名 となっていますか?
  • 9. require 先のファイルに必要な関数は記述されていますか?

文字コード関連の異常終了 (Using a require/dofile when crashing on windows)

Q. require または dofile でソースファイルをインクルードして起動すると、すぐに終了してしまい正常に動作しない。 lovec.exe で確認すると次のようなエラーが出力されています。

X:\hogehige_adventure>lovec .
Error: Syntax error: hogehige_axis.lua:66: '}' expected near '・

stack traceback:
        [C]: at 0x7fffd5f43af0
        [C]: in function 'require'
        main.lua:4: in main chunk
        [C]: in function 'require'
        [string "boot.lua"]:429: in function <[string "boot.lua"]:275>
        [C]: in function 'xpcall'

A. インクルード先のファイルに問題があります。

  • インクルード先のファイルに文法エラーがあるか確認してください。必要であればインクルード先のファイル単体でのテストを行ってください。
  • インクルード先のファイルの文字コードが UTF-8 であるかどうか確認してください。そのままでは LOVE は ShiftJIS を正常に処理できませんので、ダメ字 (エスケープ文字(バックスラッシュ、円マーク)である 0x5C) がファイルにあると上述のエラーになります。
  • まれにマルウェアの感染が疑われます。アンチウィルスソフトウェアでシステム全体を検査・修復してください。

love.exe 使用時は、コンソール (Powershell, DOSプロンプト) にはエラーメッセージを出力しないため、すべてのエラーメッセージを参照できるわけではありません。開発中は love.exe ではなく lovec.exe を使用することをお勧めします。 (keywords: Windows, require, dofile, ShiftJIS, exected near, syntax error, escape char)

画像の色化け

Q. 画像の描画前に前景色を設定すると画像の色がおかしくなります。

A. love.graphics.setColor の設定値は画像の描画にも影響を与えます。これを応用することで画像の色調を変更できます。しかし、正常に描画する前は、初期値に戻す必要があります:

restc = {}

function love.load()
	restc = love.graphics.getColor()

	love.graphics.setColor(55, 110, 237, 255)
	love.graphics.setBackgroundColor(228, 232, 244, 255)

	bgimage = love.graphics.newImage("IMG_20161127_081708.jpg")
end


function resetColor()
	love.graphics.setColor(255, 255, 255 ,255)	-- setColor は画像にも影響します。
end


function love.draw()
		resetColor()
		love.graphics.draw(bgimage)
end

フォント

--
-- 倍角文字とルビの試験実装。あと、フォントのアンチエイリアシング無効化サンプル。
-- 現在では、倍角文字はあまり使用されませんが、ゲーム内で1980年代の日本語ワードプロセッサーやマイコンを
-- 実装したい場合などにいいかもしれません。
--
-- 判明している問題: TrueType フォントではアンチエイリアシングを完全に無効化できないようです (LOVE 0.10.2で確認)
-- これを解決するには、ビットマップフォントを用意して Quad と love.graphics.draw, Canvas を応用した
-- ビットマップフォントレンダリングエンジンを自作する必要があるかもしれません。 
--
-- TODO: 後で コードスニペットへ移動。

function love.load()
	mainFont = love.graphics.newFont("ipaexg.ttf", 32);
	rubiFont = love.graphics.newFont("ipaexg.ttf", 16);
	mainFont:setFilter('nearest', 'nearest', 0)
	love.graphics.setLineStyle('rough')

--	IPAexゴシック体 = love.graphics.newFont("ipaexg.ttf", 32);
--	love.graphics.setFont(IPAexゴシック体);

--	love.graphics.setDefaultFilter('nearest', 'nearest', 0)
end

function love.draw()
--	love.graphics.push()
--	love.graphics.scale(2, 1)
--	love.graphics.print("横倍角", 0, 0)
--	love.graphics.pop()

	love.graphics.setFont(rubiFont);
	love.graphics.print(" よこ  ばい  かく",32, 16)
	love.graphics.setFont(mainFont)
	love.graphics.printf("横倍角", 32, 32, 800, "left", 0, 2.00, 1.00, 0, 0, 0, 0, 0)
	love.graphics.printf("斜体", 256, 32, 800, "left", 0, 2.00, 1.00, 0, 0, -0.25, 0, 0) -- -0.2.5 を -0.50 にしても良い。

	love.graphics.printf("1:2縦倍角", 32, 72, 800, "left", 0, 1.00, 2.00, 0, 0, 0, 0, 0)

--	love.graphics.printf("1:4縦倍角", 32, 148, 800, "left", 0, 1.00, 4.00, 0, 0, 0, 0, 0)

	love.graphics.printf("0.51:02縦倍角", 32, 148, 800, "left", 0, 0.51, 2.00, 0, 0, 0, 0, 0)

end


-- 参考文献
-- FUJITSU OASYS 30 AFⅢ 添付説明書
--

Tween (トゥイーン) とはどういう意味ですか?

普通の英和辞書を調べても変な意味しか載っていませんが、アニメーション用語です。元々の in-between が省略されて TWEEN となったようです。

意味としては開始フレームと終了フレームにある中間生成物、つまり中間フレームです。

もちろん、日本でおなじみの歯ブラシの商品名ではありませんが、歯ブラシequalアニメーションということで、関連づけて意味を記憶するのも良いと思います :-)


関連