ハイハイスクールアドベンチャー_android版
差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン前のリビジョン次のリビジョン | 前のリビジョン | ||
ハイハイスクールアドベンチャー_android版 [2025/09/19 00:58] – [ランチャーアイコン] araki | ハイハイスクールアドベンチャー_android版 [2025/10/02 23:59] (現在) – [独自の設定要素] araki | ||
---|---|---|---|
行 27: | 行 27: | ||
| | ||
- | + | {{::hhsadvrev:title.png? | |
- | {{::hhsadv:android001.png? | + | {{::hhsadvrev:isako.png?400|}} |
- | {{::hhsadv:android002.png?400|}} | + | |
===== 概要 ===== | ===== 概要 ===== | ||
行 36: | 行 35: | ||
Google Play Storeには登録していないので、インストールにはちょいとひと手間かかります。 | Google Play Storeには登録していないので、インストールにはちょいとひと手間かかります。 | ||
- | Android | + | Android |
===== ダウンロードとインストール ===== | ===== ダウンロードとインストール ===== | ||
- | こちらから[[https:// | + | こちらから[[https:// |
行 69: | 行 68: | ||
もう、SDLと同じでビットマップ作ってそれスクロールさせればいいんじゃない? | もう、SDLと同じでビットマップ作ってそれスクロールさせればいいんじゃない? | ||
- | と、GeminiとCopilotにそれぞれ聞いてみたら、Geminiは「いや、ビットマップは素材の用意が大変だしメモリも食うから RecyclerViewを活用するのがだ太しいやり方だ」といって、新しい方法を提案してきたが、SCrollViewと大差なかった。 | + | と、GeminiとCopilotにそれぞれ聞いてみたら、Geminiは「いや、ビットマップは素材の用意が大変だしメモリも食うから RecyclerViewを活用するのが正しいやり方だ」といって、新しい方法を提案してきたが、ScrollViewと大差なかった ー つまり期待してない動作しかしなかった。 |
Copilotはビットマップを使う方法を速攻で提案してきて、ほぼ完ぺきだった。 | Copilotはビットマップを使う方法を速攻で提案してきて、ほぼ完ぺきだった。 | ||
行 77: | 行 76: | ||
それ以外は、およそ文句の付け所はなかったので、速攻で採用した。 | それ以外は、およそ文句の付け所はなかったので、速攻で採用した。 | ||
- | AIは便利だし、開発の大きな助けになってくれるが、時に頑固で時に忘れっぽくて、しかもGeminiのように効く相手を間違えると、いつまでも盛会にたどり着けなかったりもするので、うまく付き合わないといけない。 | + | AIは便利だし、開発の大きな助けになってくれるが、時に頑固で時に忘れっぽくて、しかもGeminiのように効く相手を間違えると、いつまでも正解にたどり着けなかったりもするので、うまく付き合わないといけない。 |
- | ((今回はGeminiが駄目だったが、Coplitが駄目なこともあるだろう。)) | + | ((今回はGeminiが駄目だったが、Copilotが駄目なこともあるだろう。)) |
行 132: | 行 131: | ||
Kotlinの Byte型は**符号付8ビット整数**なのだ。 | Kotlinの Byte型は**符号付8ビット整数**なのだ。 | ||
- | C頭なわたしは、byte_tみたいなやつはすべからく符号なし8ビット整数だと思い込んでいたのだ。 | + | C頭なわたしは、byte_tみたいなやつはすべからく**符号なし8ビット整数**だと思い込んでいたのだ。 |
地図や、先生などの画像データは、バイト配列で座標や色コードを格納している。 | 地図や、先生などの画像データは、バイト配列で座標や色コードを格納している。 | ||
行 149: | 行 148: | ||
のように、いったん、UByte型((符号なし8ビット整数))に変換してから、整数に拡張すれば問題は起きない。 | のように、いったん、UByte型((符号なし8ビット整数))に変換してから、整数に拡張すれば問題は起きない。 | ||
- | 肩の定義は言語ごとに類似性はあっても独自のものであるので、先入観はすててちゃんと調べないとダメ。 | + | 型の定義は言語ごとに類似性はあっても独自のものであるので、先入観はすててちゃんと調べないとダメ。 |
なお、バッファ自体を UByteArray にすれば、余計な toUByte()がいらなくなり、間違いも減りそうだが、UByteArrayを使おうとすると「それはExperimentalだから」といわれていろいろめんどくさいので、今回は採用していない。 | なお、バッファ自体を UByteArray にすれば、余計な toUByte()がいらなくなり、間違いも減りそうだが、UByteArrayを使おうとすると「それはExperimentalだから」といわれていろいろめんどくさいので、今回は採用していない。 | ||
行 194: | 行 193: | ||
android: | android: | ||
</ | </ | ||
+ | |||
+ | {{:: | ||
=== Material You === | === Material You === | ||
+ | Android13あたりから、Pixel Launcherでは、テーマを適用すると、アイコンがモノクロのものにさし変わる機能が付きました。 | ||
+ | 単にモノクロならいいのかといわれればそこはそうではないのでしょうが、対応のデザインを Matrial Youと呼称しています。 | ||
+ | アプリ側で、カスタムアイコンに加えて、このモノクロのデザインガイドに沿ったアイコンを作って入れておけば、Pixel Launcher上でそっちのアイコンが表示されるのです。 | ||
+ | AIに聞いたりガイドを見たりしながら作業したのですが、一向に出てこない。 | ||
+ | * Asset Studioでモノクロアイコンをつけたすことはできない | ||
+ | * 白黒二値(ただし白と背景だけ)で構成されたPNGファイルまたはベクタデータ(XML)である | ||
+ | * 108dpx108dpで作成 | ||
+ | * ic_launcher.xml(など)の定義ファイルに adaptive-icon要素のエレメントとして、monochrome を足し、このアイコンをポイント | ||
+ | |||
+ | これだけ、って言いきられるので何度もいろいろやったんですが、一向に出てこない。 | ||
+ | ずっといさこちゃんのアイコンのまま。 | ||
+ | |||
+ | 何度もあっちのAI、こっちのAIに聞いて、最後にたどり着いたのが、 | ||
+ | |||
+ | **ic_launcher_round.xml にも monochrome要素足さないとダメ** | ||
+ | |||
+ | ということ。 | ||
+ | |||
+ | round iconは Android 8とかだけの機能だと思っていたのでノーマークだったのですが、結論から言うと、これが効いてました。 | ||
+ | |||
+ | {{:: | ||
+ | {{:: | ||
+ | |||
+ | ==== 独自の設定要素 ==== | ||
+ | |||
+ | {{:: | ||
+ | |||
+ | このゲームを最初に実装したころは Android 2.2とか2.3で端末画面も4インチないくらいのサイズだったので、画面の解像度も低く、あまり気にならなかったのですが、さすがに、昨今の大画面、高解像度のスクリーンでは、メッセージを表示している文字が小さく感じるようになってきました。((決して、老化が原因ではない……と信じてるから!)) | ||
+ | |||
+ | いえ、たぶん、システム設定を変えれば多少は大きくなるのでしょうが、そろそろ独自の設定を持ってもいいのでは、と、思いました。 | ||
+ | |||
+ | が、ドロップダウンで数字を選ぶとか、あんまりイケてない。 | ||
+ | どうせなら、文字の大きさがわかるボタンで選びたい。((異論はあるかと思いますが。)) | ||
+ | |||
+ | そう思って、独自の設定ウィジェットを作ることにしました。 | ||
+ | 要するに、Preference クラスを継承して、自前の処理を組み込んでやればいいわけです。 | ||
+ | が、これがなかなかのはまり要素満載の作業でした。 | ||
+ | |||
+ | === 画面幅いっぱいに広がってしまう === | ||
+ | |||
+ | 設定画面を開くと、標準の要素は左側にスペースがあって右側に表示されるのですが、標準のレイアウトをレイアウトインスペクタで調べて、可能な限り似せたレイアウトを作っているのに、どうしても左の隙間がつぶれてしまうのです。 | ||
+ | |||
+ | 標準的なレイアウトは、全体を覆うLinearLayout(horizontal)があって、左側からicon_frameというLinearLayout(horizontal)が来て、これが左側に72dpの隙間を作り出し、その隣にRelativeLayoutがあって、その中に titleを表示する TextViewや、スイッチなどの要素が並びます。 | ||
+ | |||
+ | なので、この構造をまねて、icon_frameには16dpの左マージンをつけて、56dpのMinWidthをつけて、計72dpのスペースをつけるようにしました。 | ||
+ | |||
+ | その隣には width=" | ||
+ | |||
+ | {{:: | ||
+ | |||
+ | ところが、こんな感じで、左端のスペースをかき消して、幅いっぱいに広がってしまうのです。 | ||
+ | |||
+ | AIに聞くと、やれ、ボタンに表示してる " | ||
+ | |||
+ | 仕方がないので、Layout Inspectorでちまちまと、標準のレイアウトと、自前のレイアウトとを比べていきます。 | ||
+ | |||
+ | すると icon_frameの Visibilityが、標準では INVISIBLEになっているものが、GONEになっているじゃありませんか。 | ||
+ | とりあえず、FontSizeInlinePreference()のコードのほうで、icon_frame の Visibilityを ItemViewのVisibilityと同じになるようにしてやると、あら不思議。ちゃんと左端にスペースが出るじゃないですか。 | ||
+ | |||
+ | Visibilityの操作は、親クラスの中で行われているようなので、Android Studioで親クラスの処理を追っていくと、mIconSpaceReservedというprivate変数の値がfalseだとGONEにしていることがわかりました。 | ||
+ | |||
+ | private の変数なのでコード側からは変更できないですが、XML側でできることがわかり、問題を解消することができました。 | ||
+ | |||
+ | <code XML> | ||
+ | < | ||
+ | app: | ||
+ | < | ||
+ | android: | ||
+ | android: | ||
+ | android: | ||
+ | app: | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | === PrefernceCategoryとの間に線 === | ||
+ | |||
+ | 上のうまくいってない画面。「画面の設定」という PreferenceCategoryの表示と、「テキストの大きさ」という項目の間に横線が入っているのが見えるかと思います。 | ||
+ | |||
+ | ほかの項目では、カテゴリの下には線が入ってないのに、なぜか線が入る。 | ||
+ | |||
+ | 消したい。邪魔だ。 | ||
+ | |||
+ | だが、Layout Inspectorでもいまいち、犯人がわからない。 | ||
+ | まあ、幅問題が解決しても、線は横幅いっぱいに出ているので、PreferenceCategory側か、FontSizeInlinePreferenceの一番外側のLinearLayoutのどっちかなわけですが。 | ||
+ | |||
+ | 結論から言うと、PreferenceCategory側でした。 | ||
+ | app: | ||
+ | しかし、ほかの要素ではこれ特に指定してないのだから、allowDividerAboveが trueで、allowDividerBelowがfalseがデフォルト値じゃないのかって思うんですが、やや解せぬ思いは残りましたが、線は消せました。 | ||
+ | |||
+ | <code XML> | ||
+ | < | ||
+ | app: | ||
+ | </ | ||
+ | |||
+ | ==== モノクロアイコンのデザインについて ==== | ||
+ | |||
+ | モノクロアイコンは、いさこちゃんの白黒化も考えたのですが、ごちゃごちゃしすぎるので断念。 | ||
+ | |||
+ | では、何がいいか? | ||
+ | そういえば、ハイ高校には校章はないのか? | ||
+ | |||
+ | と、いうことで、勝手に校章をデザインしました。 | ||
+ | もちろん、ゼロから考えたわけじゃないですよ。 | ||
+ | |||
+ | どこぞのものを参考にでっち上げたのがこちらです。 | ||
+ | |||
+ | {{:: | ||
+ | Z市の市花がひまわりであることから、太陽を象徴する卍型にハイ高校の頭文字Hを組み合わせてあります。 | ||
+ | 卍の四つの腕は教育目標である、真・善・美・用をあらわし、ひまわりの黄色を基調としています。 | ||
+ | |||
+ | このデザインをモノクロ化したものが、今回のアイコンとなっています。 | ||
+ | |||
+ | ==== 処理のタイミング ==== | ||
+ | |||
+ | クレジットロールはActivityとして実装しています。 | ||
+ | 呼び出しは Intent で行いますが、呼び出した時点で処理されるわけではなく、登録だけされて、呼び出しはユーザプログラム側の処理が済んでシステムに処理が戻されたタイミングになります。 | ||
+ | |||
+ | 何がいいたいかというと、例えばゲームの開始時、オープニングのクレジットロールを呼び出すとともに、画面をゲームの初期画面に書き換えるのですが、オープニングの処理が始まる前に画面が書き換わるので、一瞬ちらっとゲームの開始画面が出た後にクレジットロールが始まります。 | ||
+ | |||
+ | かっこ悪い。 | ||
+ | |||
+ | 暗転している裏で書き換えてほしいのに、舞台裏が見えちゃっているようでイケてません。 | ||
+ | |||
+ | エンディングでも同じで、タイトル画面に戻ってからクレジットロールが始まります。 | ||
+ | |||
+ | 回避するためには、クレジットロール側の処理が終わって、Main Activityに処理が戻されるときに書き換えればいいことになります。 | ||
+ | |||
+ | 具体的には、処理が戻ってくるときに onResume() が呼び出されるので、ここで適切な書き換えをすればいいことになります。 | ||
+ | |||
+ | 単純に、ここに、オープニング処理から戻されたらしいならこれ、クリアしたらしいならこれ、という処理を書くと、スクリーンロックから復帰したり、タスクマネージャで別のアプリから戻されたときにも、onResume()が呼ばれるので、余計なタイミングでの呼び出しが発生することになります。 | ||
+ | |||
+ | そこで、onResumeOnce という ()->Unit 型の ArrayListを作って、クレジットロールを呼び出すときに、画面書き換えの一連の処理を登録して、onResume()側では呼び出したら捨ててしまうという処理にすればいいのではないかと考えてそのようにしています。 | ||
+ | |||
+ | <code kotlin> | ||
+ | |||
+ | val onResumeOnce: | ||
+ | ... | ||
+ | override fun onResume() | ||
+ | { | ||
+ | ... | ||
+ | if (onResumeOnce.isEmpty()) return | ||
+ | for(f in onResumeOnce) { | ||
+ | f() | ||
+ | } | ||
+ | onResumeOnce.clear() | ||
+ | } | ||
+ | ... | ||
+ | onResumeOnce.add { | ||
+ | // 処理を書くと onResume()の中で一度だけ呼ばれます | ||
+ | } | ||
+ | </ |
ハイハイスクールアドベンチャー_android版.1758243517.txt.gz · 最終更新: by araki