工場裏のアーカイブス

素人によるiPhoneアプリ開発の学習記 あと機械学習とかM5Stackとか

SpriteKitでビットマップフォント(2、BMGlyph版)

昔の記事では「Glyph Designer」というソフトウェアを用いてビットマップフォントを作成し、それをSpriteKitで使用する方法についてメモしました。

chemicalfactory.hatenablog.com
しかしながら、当時はGlyph Desingerは買い切り型のソフトウェアだったのですが、現在では月額制となってしまったようです(本記事作成時点では月¥900から、数ヶ月や年単位契約によるディスカウントもあるようですが)。趣味で細々とアプリ開発を嗜む身としては、ビットマップフォントの作成頻度がそこまである訳でもなく、少々重い金額です。

そこで代替となるソフトウェアを探していたのですが、良さげなものとして「BMGlyph」を見つけましたので、現在はこちらを使用しております。

bmGlyph

bmGlyph

  • Stéphane QUERAUD
  • 開発ツール
  • ¥1,220
apps.apple.com

本記事作成時点では¥1,220の買い切り型であり、日本語フォント対応、グラデーションやテクスチャによる文字の装飾、プレビューなど機能はかなり充実しており、イメージした通りのビットマップフォントが比較的容易に作成出来ると感じました(先日リメイクが完了して再リリースした「門清ドリルi」は、BMGlyphで作成したビットマップフォントを活用しています)。

操作法も比較的直感的で分かりやすく、公式ヘルプ(英語)内容の日本語訳を作成した素晴らしい外部サイトもあります。
mmorley.hatenablog.com

ただし上記サイトで解説されているフォントファイルの出力法はCocos2d向けとなっております。BMGlyphはSpriteKit向けのフォントファイルを出力する機能も備えていますが、公式サイトによるとSpriteKitでそれを扱うためには、以下のGitHubで公開されている「BMGlyphLabel」という専用のクラスを導入する必要があります。自分で試した限りでは、昔の記事のようにSKLabelNodeで扱うことは出来ないようです。
github.com

BMGlyphからSpriteKit向けに出力したフォントファイルを、BMGlyphLabelを用いて扱う方法に言及した日本語記事はほとんど無いようですので、どこかで誰かの役に立つかもしれないと信じて、本記事にメモしてみます。
 

SpriteKit向けフォントファイルの作成

まずはBMGlyphでお好みのビットマップフォントを作成します。ここでは例として、デフォルトのアルファベット・数字・記号に加えて、ひらがな、カタカナのテキストに対応したものにしてみました。そしてフォントはヒラギノ明朝 ProN W3としました。後ほど同フォントを設定した標準的なSKLabelNodeと比較してみたいと思います。

そしてフォントサイズは 24 にしようと思いますが、本記事執筆時点において現役のiPhone/iPad機種は、ほぼRetinaディスプレイ対応であり、画面スケールは2倍(@2x、iPhone 8や11など)または3倍(@3x、iPhone Xや11 Proなど)のいずれかとなります。@2xの機種の画面上で、フォントサイズが24に見えるよう表示するためには、サイズ48のフォントファイルを用意する必要があります。@3xの機種ならサイズ72 が必要です。そこで、ここではフォントサイズ(Font Size欄)を72に設定しておきます。

f:id:fleron:20200304224016p:plain

ビットマップフォントの編集が終わったら、BMGlyphの画面上方にある「Publish」をクリックして、フォントファイルの出力設定画面を呼び出します。最初はここで何をすれば良いのか分からず戸惑いましたが、こちらでは@2x向け、@3x向けなどと複数の出力設定を作成しておくことで、一括でそれらに対応したフォントファイルを出力することが出来ることが分かりました。
f:id:fleron:20200304233340p:plain

実例を示します。「Targets」欄で「+」を押すことで新しい出力設定を作成出来ます。また「duplicate」では既存の出力設定を複製出来ます。ここでは@2x向け、@3x向けの2種類を作成して、それぞれの内容を編集します。
f:id:fleron:20200304232452p:plain
f:id:fleron:20200304234257p:plain

  • Directory Path:フォントファイルの出力先となるフォルダを指定します。各出力設定では全て揃えておいた方が無難と思います。
  • File Name:フォントファイルの名前です。本例では「BMSample」としています。こちらも全て揃えておいた方が無難です。
  • Suffix:重要項目であり、こちらで「@2x」「@3x」などの対象を区別します。
  • Force Font Face:強制的にフォントの書体名を与えることが出来るようですが、通常は空白で構わないようです。
  • Scale:出力設定ごとに、フォントファイルのスケールを変更するための重要項目です。今回は元々のフォントを72に設定しているので、@3x向けの設定では100%(スケール変更なし)、@2x向けの設定では66%(@3xの2/3、すなわちFont Size 48相当)とすることで、いずれの画面スケールの機種でも、画面上ではフォントサイズ24に見えるよう表示されます。
  • Scale Quality:通常はデフォルトで問題ないようです。
  • Format:こちらは忘れずに、全ての設定項目で「SpriteKit」に変更しておきます。

また、チェックボックスの項目のうち「Redraw when downscaling」は今回のように、設定項目によってフォントファイルのスケールを縮小する場合はチェックを入れておいた方が良いようです。全ての設定が終わったら「PUBLISH!」ボタンを押すと、問題が無ければSuffixごとのXMLファイル、および「〜.atras」のフォント画像が格納されたフォルダが生成されます。
f:id:fleron:20200307004822p:plain

これらのファイルは全て、ビットマップフォントを使用したいプロジェクトに、ドラッグ&ドロップなどで追加しておきます。
 

BMGlyphLabelの利用準備

BMGlyphLabelを利用可能とするために、まずは先述のGitHubより必要なファイルをダウンロードしておきます。なお、こちらはObjective-C版となります。Swift版もあるようですが、本記事執筆時点ではバージョンがSwift 3のものしか無いようですので、Swift 5であればObjective-C版を用いた方が、互換性の問題が生じづらいと思います。
f:id:fleron:20200307010216p:plain

ダウンロード&解凍した「BMGlyphLabel-master」フォルダ内に、「BMGlyphLabel」フォルダがあり、この中に必要なObjective-Cのソースおよびヘッダファイル計4つが入っています。これらをプロジェクトにドラッグ&ドロップで追加します。

f:id:fleron:20200307010545p:plain
f:id:fleron:20200307010557p:plain

このときブリッジングヘッダを作成するか確認するダイアログが表示されますので、作成しておきます。ブリッジングヘッダについては以下の過去記事を参照ください。
f:id:fleron:20200307011836p:plain
※ブリッジングヘッダについての参考記事
chemicalfactory.hatenablog.com

もちろんブリッジングヘッダでは、追加したヘッダファイル2つをインポートしておきます。これで必要な下準備は完了です。

#include "BMGlyphLabel.h"
#include "BMGlyphFont.h"

 

BMGlyphLabelで、ビットマップフォントを表示する

下準備が整ったので、実際にBMGlyphLabelを用いて、SpriteKitでビットマップフォントを表示してみます。

//GameSceneは、SpriteKitのテンプレート(本記事執筆時点ではXcode 11.3)
//を書き換えたものとする。シーンのAnchor Pointは(x, y) = (0.5, 0.5)想定

import SpriteKit

class GameScene: SKScene {

    override func didMove(to view: SKView) {
            
        //BMGlyphから出力したフォントファイル名を指定して、フォントを作成
        let BMSampleFont = BMGlyphFont(name: "BMSample")
        
        //BMGlyphLabelはSKNodeのサブクラスであり、他のノードと大体同様の
        //使い方が可能。ただしAnchor Pointの指定は出来ず、替わりにアラインメントで
        //左右や上下の揃え位置を指定する
        if let label = BMGlyphLabel(text: "BMGlyphのテスト", font: BMSampleFont){
            label.position = CGPoint(x: 0, y: -20)
            label.horizontalAlignment = BMGlyphHorizontalAlignmentCentered
            label.verticalAlignment = BMGlyphVerticalAlignmentMiddle
            label.xScale = 1.0
            label.yScale = 1.0
            self.addChild(label)
        }
        
        //比較のために、SKLabelNodeを用いて、同じフォント、サイズで同じ文字を描いてみる
        let label2 = SKLabelNode(text: "BMGlyphのテスト")
        label2.fontName = "HiraMinProN-W3"
        label2.fontSize = 24
        label2.position = CGPoint(x: 0, y: 20)
        self.addChild(label2)
    }
}


試しに、画面スケールの異なる2機種のシミュレータで動かしてみました。それぞれに応じたスケールのフォントが自動的に使い分けられ、きちんと同様の表示が得られています。

iPhone 8 シミュレータ(@2x)
f:id:fleron:20200307124320p:plain

iPhone 11 シミュレータ(@3x)
f:id:fleron:20200307124334p:plain

xScale、yScaleを変更すれば、フォントサイズを調整することも出来ます。ただし、拡大の場合はやり過ぎると表示が粗くなるので、最初からサイズを大きくしたフォントファイルを用意した方が良いと思います。

if let label = BMGlyphLabel(text: "BMGlyphのテスト", font: BMSampleFont){
	label.position = CGPoint(x: 0, y: -30)
	label.horizontalAlignment = BMGlyphHorizontalAlignmentCentered
	label.verticalAlignment = BMGlyphVerticalAlignmentMiddle
	label.xScale = 3.0
	label.yScale = 3.0
	self.addChild(label)
}
        
let label2 = SKLabelNode(text: "BMGlyphのテスト")
label2.fontName = "HiraMinProN-W3"
label2.fontSize = 72
label2.position = CGPoint(x: 0, y: 30)
self.addChild(label2)


f:id:fleron:20200307130217p:plain