Love2D(Lua)でゲームをつくる
本体と開発環境のインストール
Love2D(執筆現在11.3)はLuaJIT 2.0.5で動いている。
本体だけでも開発はできるけど、テスト環境を整えるため、LuaJITとパッケージマネージャのLuaRocksをインストールする。
手動ビルドに手間どったので、HereRocksを導入することにした。
LOVE2Dのインストール
LOVE2D本体とコンパイル用のgccをインストール。今回はChocolateyで入れた。
$ cinst love.install mingw -y
HereRocksのインストール
pipで行う。
$ pip install hererocks
LuaJIT + LuaRocksのインストール
今回はLuaJIT2.0.5とLuaRocksの最新版を落とす。
-j
でLuaJIT、-r
でLuaRocksのバージョンを指定。
$ hererocks /c/luajit -j2.0.5 -rlatest --target mingw
PATHを通す。
export LUA_PATH=";;/c/luajit/share/lua/5.1/jit/?.lua";
export LUA_CPATH=";;/c/luajit/bin/?.dll";
export LUA_DEV="/c/luajit";
Love2Dの起動
Windowsだとlovec
でコンソールが表示される。
main.lua
のあるディレクトリで
$ lovec .
で起動。
VS CodeにLua用の拡張機能を追加
設定でランタイムをLuaJITに変更しておく。
"Lua.runtime.version": "LuaJIT",
こちらは補完機能。
tealでLuaの型チェック(WIP)
Luadocではテーブルの型情報が書けない書きづらかったので、tlを導入してみる。
インストール
$ luarocks.bat install tl
使う
$ tl check main.tl
叱られたら修正し、tl.bat gen
で変換。
詳しくはここ。
型定義ファイル
型定義を自作することもできる。
早速Love2D用オレオレ定義ファイルを作った。
- 一部しかない
-
love.graphics.draw
など複数書き方がある場合、自分が使うパターンしか書いてない
ので、もしご入り用の場合は修正してください。
これをtlconfig.lua
に追加すると、自動で読み込んでくれる。
return {
global_env_def = 'love-example',
}
定義ファイルについて詳しくはここ。
コンパイル設定
出力するLuaのバージョンも指定できる。
gen_target = '5.1',
保存したら自動でチェックし、問題なければコンパイル(WIP)
tlファイルでもLua拡張を使いたい
VS Codeにはtealの拡張もあるが、自動補完機能はあるものの定義情報などは出してくれない。(recordの折りたたみはしてくれる)
こちらが情報豊富なのでtlでも引き続き使いたい。ので、言語モードをLuaにしてしまう。コマンドパレットを開き「言語モードの変更」→「'.tl'に対するファイルの関連付けの構成...」→「Lua」を選択。
すると…Lua拡張のDiagnosttic機能がアノテーション部分で大量にエラーを吐く。
"Lua.diagnostics.enable": false
でDiagnostticをOFFにすればいいんだけど、
最低でもendで閉じ忘れだけは事前に検出したいので、miss-end
以外でエラーが出たものをちまちま除外していく。
"Lua.diagnostics.disable": [
"unknown-symbol",
"exp-in-action",
"miss-method",
"undefined-field",
"miss-symbol", // record
"undefined-global", // record
"keyword", // function
// "miss-end", // function
// "unexpect-dots" // 可変長引数
],
また除外フォルダも指定できる。
"Lua.workspace.ignoreDir": [
".vscode",
"types" // 型定義ファイルのフォルダ
],
WIP
- 互換性オプション
- ローカル型定義ファイルの読み込み
Busted+LuacovでLuaのユニットテストとカバレッジ(WIP)
インストール
$ luarocks.bat install busted
$ luarocks.bat install luacov
$ luarocks.bat install luacov-reporter-lcov
使う
参考
Windowsで文字化けする
色がつかない
ansicon
がないのでChocolateyでインストール。
$ cinst ansicon -y
アサーション
assert.are.equal(state, arguments)
で要素の比較、
assert.are.same(state, arguments)
でテーブルの比較ができる。
それぞれfalseの場合両方の情報を表示してくれる。
カバレッジを取る
return {
exclude = {
-- requireで読み込んだ開発用モジュールも対象のため、LuaJITをインストールしたフォルダも除外
'luajit',
'test',
'lib',
},
runreport = true,
reportfile ='coverage/lcov.info',
statsfile ='coverage/luacov.stats.out'
}
$ busted.bat main.lua -c
これで更に
$ luacov -r lcov
とするとlcov.infoに変換してくれる。
こちらの拡張でカバレッジを見れる。
WIP
- tlファイルでカバレッジを見たい
CuteでLove2DのUIテスト自動化(WIP)
普段Love2Dのコールバック関数には
love.mousepressed(x, y, button){
-- ボタンが押されたときの処理
}
というふうに引数を受け取ったあとの処理を書いているけど、普通に関数だけ呼び出すこともできる。
love.mousepressed(10, 10, 1)
上記は座標x10,y10でメインボタンをクリックしたことと同じになる。
これを活用し、例えばボタンの表示されるべき位置を指定してクリックし、Cuteで要素の変化を確認するなど、ブラックボックステストを書いていける。
WIP
- テストの範囲
- cute-headlessとsimple-pre-commitでテスト失敗したらコミット不可にする
とにかくフックをバージョン管理したかったのでシンプルなものを選んだ。
- スクリーンショットを撮って画像差分テストする
VS Code + Local Lua DebuggerでLove2Dのデバッグ(WIP)
Love2Dの場合は
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Love",
"type": "lua-local",
"request": "launch",
"program": {
"command": "love"
},
"args": [
"."
],
"scriptRoots": [
"."
]
}
]
}
main.luaの冒頭で読み込み。
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
require("lldebugger").start()
end
t.console = false
Luaでオブジェクト指向
メタテーブルかファクトリ関数を用いてプロトタイプベースに書ける。
前者は多段継承だと重いらしい。
ファクトリ関数でも関数を先読みさせとくと速度を上げられるそう。
Github Milestoneで進捗管理
- 期日を決められる
- Issuesを登録して進捗度合いを可視化できる
VS Codeで見るにはこれ
マイルストーンごとにアサインされた・自分が作成したIssuesをリスト表示してくれる
Projectsはカンバン管理もできる(自動でタスク移動もできるらしい)
Milestoneとの使い分けはまだ模索中
とりあえずv1.0公開を1月末に設定した。がんばろ
オブジェクト指向の記事
- newを使ってコンポジション
- newはメインクラスかファクトリで行いサブクラスが依存しないようにする
- まずクラスに切り分けてみる
- するかわからない仕様変更は考慮しない
デザインパターンの記事
生成
Factory Method
Decorator
新たな機能を被せて生成
構造
Facade
複数クラスをまたいだ処理を行うクラスをひとつ作る。
Storategy
クラスを切り替えて挙動を変更
Adapter
FlyWeight
インスタンスを共有してメモリを節約する。
振る舞い
Template Method
違う振る舞いをする部分をメソッドに切り出す
→メソッドを抽象クラスに持っていき、具象クラスでそれぞれ違う振る舞いをする同名のメソッドを用意
→残りの部分は共通化できる
Strategy
切り出す部分はTemplatr Methodと共通。
具象クラスから委譲を使って切り出す。
State
ページ遷移に使える
Observer
Command