読者です 読者をやめる 読者になる 読者になる

LÖVEでゲームを作ろう 1 日本語でこんにちは

プログラミング フォント

LÖVEオープンソースの2Dゲームエンジンで、Lua言語でゲームを創ることができる。作ったゲームはWindowsとMac OS XLinuxで遊ぶことができる。
MOONGIFTの記事: Luaで作る2Dゲーム「LÖVE」|オープンソース・ソフトウェア紹介を軸としたITエンジニア、Webデザイナー向けブログ

インストール

LÖVE - Free 2D Game Engine からダウンロードしてきて、パスを通しておこう。
Ubuntuならリポジトリからインストールできる。

$ sudo aptitude install love

はじめてのLÖVE

これはLÖVEのWikiにあったハローワールドのコード。

function love.draw()
    love.graphics.print('Hello World!', 400, 300)
end

これをmain.luaというファイル名で新しく作ったディレクトリに保存する。
実行するには、loveコマンドを使う。

$ love (main.luaのあるディレクトリのパス、またはloveパッケージのパス)

カレント・ディレクトリがmain.luaのあるディレクトリなら、

$ love .

でok。

日本語の表示

日本語を表示させようとして次のように変更しても、LÖVEのデフォルトのフォント(Bitstream Vera Sans)にはひらがなや漢字が含まれていないので、文字化けしてしまう。

-- -*- coding: utf-8 -*-
function love.draw()
    love.graphics.print('こんにちは世界!', 400, 300)
end

そこで、日本語の入っているフォントを使うようにする。VL Gothicをダウンロードして、VL-Gothic-Regular.ttfをmain.luaと同じディレクトリに置き、プログラムを次のように変更する。

-- -*- coding: utf-8 -*-
function love.load(arg)
    -- font = love.graphics.newFont(フォントのパス, 文字の大きさ)
    font = love.graphics.newFont('VL-Gothic-Regular.ttf', 32)
end
function love.draw()
    -- 使うフォントの指定
    love.graphics.setFont(font)
    love.graphics.print('こんにちは世界!', 400, 300)
end

フォントを使う場合はフォントのライセンスをよく読み、再配布が可能であることを確認すること。

MoonScriptを使う

Luaの代わりにMoonScriptを使ってみよう。

MoonScript処理系のインストール

Ubuntuだと、まずLuaRocksをインストールして、MoonScript処理系をローカルにインストールして、

$ sudo aptitude install luarocks
$ luarocks --local install moonscript

その後、.bashrcに次のスクリプトを追加してパスを通すのがいいと思う。

# set env for luarocks                                                          
if [ -d "$HOME/.luarocks/" ] ; then
    export PATH=$PATH:$HOME/.luarocks/bin
    export LUA_PATH="$HOME/.luarocks/lib/lua/5.1/?.lua;$HOME/.luarocks/share/lu\
a/5.1/?.lua;;"
    export LUA_CPATH="$HOME/.luarocks/lib/lua/5.1/?.lua;;"
fi

MoonScriptでLÖVE

local font

love.load = (arg) ->
    font = love.graphics.newFont 'VL-Gothic-Regular.ttf', 32
    return

love.draw = ->
    love.graphics.setFont font
    love.graphics.print 'こんにちは世界!', 400, 300
    return

このファイルをmain.moonというファイル名で保存して、Luaにコンパイルする。

$ moonc main.moon

loveパッケージの作成

loveパッケージは単なるZIPファイルの拡張子を.loveに変えたもの。ただし、main.luaはZIPアーカイブのトップレベル・ディレクトリにないといけない。

main.luaのあるディレクトリに移動して、次のコマンドでパッケージにする。

$ zip -9 hello.love main.lua VL-Gothic-Regular.ttf

hello.loveが動くか確認しよう。

$ love hello.love

実行可能形式にする

ゲームはloveパッケージを配ってもいいが、実行可能形式にもできる。といっても、やることはloveの実行ファイルとloveパッケージファイルを連結するだけ。

$ cat /usr/bin/love hello.love > hello
$ chmod +x hello

設定ファイル

conf.luaというファイルに設定を書く。

function love.conf(t)
    -- ウィンドウに表示されるタイトル
    t.title = "Hello, world!"
    -- ゲーム作者の名前
    t.author = "Ryusei Yamaguchi"
    -- ウェブサイトのURL
    t.url = "https://github.com/mandel59/hellolove"
    -- LÖVEのバージョン
    t.version = "0.8.0"
    -- ウィンドウの幅と高さ
    t.screen.width = 800
    t.screen.height = 600
end

設定できる項目はConfig Files - LOVEに載っている。

makeを使う

色々なコマンドを使う時にオプションを毎回指定するのは面倒なので、Makefileを作っておいてmakeコマンドで色々なコマンドを実行できるようにしておく。

# loveパッケージに入れるファイル
archive_files := \
	conf.lua main.lua \
	$(wildcard *.txt) $(wildcard *.ttf)

# loveパッケージのファイル名
love_file := hello.love

# love実行ファイルのパス
love_exec := /usr/bin/love

# 実行可能ファイルのファイル名
executable := hello

all: build
build: $(love_file)
clean:
	-rm -f $(patsubst %.moon,%.lua,$(wildcard *.moon))
	-rm -f $(love_file) $(executable)
release: $(executable)
run: build
	$(love_exec) $(love_file)
.PHONY: all build clean release run

$(love_file): $(archive_files)
	-rm -f $@
	zip -9 $@ $(archive_files)

$(executable): $(love_file)
	cat $(love_exec) $< > $@
	chmod +x $@

%.lua: %.moon
	moonc $<

これをmain.luaのあるディレクトリにMakefileというファイル名で保存する。

これで

$ make

を実行すれば、MoonScriptなども自動的にコンパイルされ、自動的にloveパッケージができるようになる。

フォントをサブセット化する

日本語のフォントは大きい。どうせ全部の文字は使わないので、必要な文字だけ抜き出して使おう。

次の即席スクリプトでサブセット化できる。

#!/usr/bin/env python
import sys, argparse, fontforge

def read_char_set(f):
    cs = set()
    for line in f.readlines():
        for c in unicode(line, 'UTF-8').rstrip('\r\n'):
            cs.add(c)
    return cs

def select(f, cs):
    for c in cs:
        f.selection.select(('more', None), ord(c))

def parser():
    p = argparse.ArgumentParser(description='Subset font.')
    p.add_argument('--latin1', action='store_true', help='include latin1 set')
    p.add_argument('file', type=str, help='input font file')
    p.add_argument('outfile', type=str, help='output font file')
    return p

def subset(infile, outfile, cs):
    f = fontforge.open(infile)

    f.selection.none()
    select(f, cs)
    f.selection.select(('more', None), '.notdef')
    f.selection.invert()
    f.clear()

    f.generate(outfile)

def main():
    p = parser()
    args = p.parse_args()
    cs = read_char_set(sys.stdin)
    if args.latin1:
        for c in range(0x20, 0x100):
            cs.add(unichr(c))
    infile = args.file
    outfile = args.outfile
    subset(infile, outfile, cs)

if __name__ == '__main__':
    main()

このスクリプトを使うには、fontforgeをインストールする必要がある。

$ sudo aptitude install fontforge

次のように、標準入力からサブセットに含めたい文字列を入力する。--latin1オプションはISO/IEC 8859-1の文字を全部入れる。

$ echo 'こんにちは世界!' | python subset.py --latin1 VL-Gothic-Regular.ttf subset.ttf

あるいは

$ cat main.lua | python subset.py --latin1 VL-Gothic-Regular.ttf subset.ttf

フォントのサブセット化を行うことで、VL-Gothic-Regular.ttfは4.1 MBから22.7 kBになった*1
サブセットフォントを作るときはフォントのライセンスをよく読み、改変や再配布が可能であることを確認すること。

ゲームは?

つまづきそうなところ(日本語の表示)は済ませたので、続きはLÖVEのWikiを見たりして頑張る。

*1:ここでは1 kB = 1000 B, 1 MB = 1000 kB. Nautilusの表示に準ずる