はかせのラボ

私の頭の中を書いていく雑記ブログです

落ちモノパズル フォント変更を出来るようにした・改

あいさつ

どうも、はかせです。
今回はフォント変更の改造編です。

改造内容

ちょっと前にフォントを変更できるようにしました。
hakase0274.hatenablog.com

ただこのときフォントが異なっていても同じ文字なら
同じフォントが使われてしまう問題が発生しました。
今回はその問題を解決するための改造を行いました。

問題の原因

これは前からちょいちょい言っていたようにキャッシュの問題でした。
私は1文字ごとに1つのテクスチャを作って複数のテクスチャを描画することで
文字列描画を実装しています。
そのとき都度文字を生成するとパフォーマンスに影響が出るため
新しく生成した文字はキャッシュして使っていました。

問題はここからで
生成した文字のテクスチャはキャッシュしていたのですが、
文字のフォント情報はキャッシュしていなかったのです。

そしてキャッシュの検索は文字を直接キーとして検索していました。
つまりゴシック体の「あ」
明朝体の「あ」
同じ「あ」として保存されています。

なので後で別フォントで「あ」を使おうとしても既存の「あ」があり、
そちらのキャッシュがヒットして使われたというのが問題の全容でした。

問題の解決

これは簡単です。
キャッシュにフォント情報がないことが問題なので、
フォント情報を付けてやれば解決します。
テクスチャ情報の構造体に持たせてもいいですが、
この構造体にあまり必要以上の情報を持たせたくありません。
(素直にpngとかを読み込むときにも使っている構造体なので)

なのでフォント名をkeyとする連想配列を使って文字をキャッシュすることにしました。
C++連想配列については前回記事にあげたので詳しくはそちらでお願いします。
hakase0274.hatenablog.com

実装については概ね記事の通りなのですが、
key値の有無の判定方法が変わっています。
記事では登録したkeyを配列に持ちその配列の中にあるかで判定していましたが、
std::mapのcountを使うことで簡単に出来るという情報を入手し実際に使ってみました。
countはstd::map内に渡されたkeyがいくつあるかを返す関数です。
ただstd::mapはkeyの重複はできないため返ってくる値は必然的に、
0 = 無し
1 = 有り

この2つに限定されます。
なので

std::map<key,value> mp;
if(mp.count(searchKey))
{
    //key有
}
else
{
    //key無
}

このifだけでkeyの有無が判定できます。

改造結果

f:id:hakase0274:20190307232835p:plain
ちゃんと同じ文字でもフォントが変わるようになりました(((o(*゚▽゚*)o)))

あとがき

今回は同じ文字でもフォントを変えれるよう改造した話でした。
実装については概ね前回のstd::mapの動作検証時に済んでいたので
そこまで苦戦はしませんでしたね。
(地味にUnityC#時代含め連想配列を真面目に使うのは初めてだったりします)

それでは今回はこの辺でノシ

今回作ったものはgithubに上げました
github.com

参考

qiita.com