JavaScript
canvas
ゲーム制作
ハイブリッドアプリ

webフォントで文字を描画する(HTML5でブラウザゲームを作る)

スマートフォンは機種によりインストールフォントがかなり違い、ブラウザゲーム等の場合は表示に大きな差異がでてしまいます。
そこで、その差異を吸収しつつ見た目を良くするためにwebフォントを導入します。

HMG大富豪
https://hasemonmon.net/df5/

下準備

まずはフリーフォントファイル(ttf)を用意します。
自分のアプリのイメージに合うフリーフォントを頑張って探しましょう。

次にフォントの変換を行います。
日本語を含むフォントの場合、ファイルサイズが平気で10MBとかになってしまいます。
これではまともにweb上で扱えません。
そこで自分が使いたい文字だけを抽出してサブセットを作る事になります。
(ちなみにHMG大富豪で使用したサブセットファイルは15kb程度です。)

変換は武蔵システムのサブセットフォントメーカーというツールを使います。
http://opentype.jp/subsetfontmk.htm
font_50per.png

これを使いサブセットを作った後は、スマホで扱える様にWOFF形式に変換します。
こちらも武蔵システムさんのWOFFコンバーターというツールを使います。
これらはWindows用のフリーソフトなので大変ありがたいです。(感謝)
ツールの使い方は武蔵システムさんのサイトに詳しく載っていますので確認してください。

使用方法

まずはHTMLのHEAD部分にwebフォント用の記述を追加します。
読み込むファイル形式はターゲットとなるブラウザにより若干変化します。
スマホメインであれば以下の2ファイルでOKです。

    <style type="text/css">
        @font-face {
            font-family: 'hm_tb';   /* フォント名 */
            src: url('font/hm_tb.woff') format('woff'),
                url('font/hm_tb.ttf') format('truetype');   /* フォントファイル */
        }
    </style>

追加したフォントのフォント名を指定してcanvasへ描画します。

<script>
    (window.onload = function() {  // 読み込み完了を待つ
        drawTest();
    })();
    function drawTest(){
        var cv = document.getElementById("TEST_CANVAS");
        var ctx = cv.getContext('2d');
        ctx.fillStyle = "#ccaf89";
        ctx.fillRect(0, 0, 320, 320);
        ctx.font = "60px hm_tb";    // サイズとフォント名を指定
        ctx.fillStyle = "#ff0000";
        ctx.fillText("WebFont", 25, 160);
    }
</script>

これで完了。のはずが、何故かうまくいきません。

出力結果(失敗&成功)
Screenshot from 2017-09-08 06-30-30.pngScreenshot from 2017-09-08 06-31-07.png

何度かリロードすると成功と失敗が繰り返されます。

当時ここでしばらく嵌りました...
最初、読み込みが間に合ってないのかと思いsetTimeoutで時間をおいたりもしましたがまだまだ安定しません。
そして最終的にうまく行った解決策は、canvasから使用するまえに、そのフォントでDOMへ書き込むことでした。

<span style="
    font-family: 'hm_tb';
">sample</span>

僕の場合これで完全に問題解決したのですが、正しい原因や他にもっと良い方法がありましたらご指摘おねがいします。
(HMG大富豪ではスプラッシュ画面に背景色と同じ色に指定したテスト用の文字を描画しています。)

以下は今回のサンプルの全ソースです。

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    <meta http-equiv="Content-Style-Type" content="text/css" />
    <style type="text/css">
        @font-face {
            font-family: 'hm_tb';   /* フォント名 */
            src: url('font/hm_tb.woff') format('woff'),
                url('font/hm_tb.ttf') format('truetype');   /* フォントファイル */
        }
    </style>
    <title>webフォントテスト</title>
</head>
<body>
    <span style="
        font-family: 'hm_tb';
    ">sample</span><br>
    <canvas id="TEST_CANVAS" width="320" height="320"></canvas>
</body>
<script>
    (window.onload = function() {  // 読み込み完了を待つ
        setTimeout(drawTest, 200);
    })();
    function drawTest(){
        var cv = document.getElementById("TEST_CANVAS");
        var ctx = cv.getContext('2d');
        ctx.fillStyle = "#ccaf89";
        ctx.fillRect(0, 0, 320, 320);
        ctx.font = "60px hm_tb";    // サイズとフォント名を指定
        ctx.fillStyle = "#ff0000";
        ctx.fillText("WebFont", 25, 160);
    }
</script>
</html>

【宣伝】
小粒でシンプルな簡単ゲームですがハイブリッドアプリ二作目作りました。
今回のフォントは実際にこのゲームで利用しています。(前回のキャンバス陰影処理なども使っています)
大富豪では採用できなかったサウンド関連も実装しましたので後々そのあたりの解説も記事にしたいと思います。
リバーシ
apple-touch-icon-180x180.png