ユーザ用ツール

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン前のリビジョン
次のリビジョン
前のリビジョン
ハイハイスクールアドベンチャー_android版 [2025/09/19 04:12] – [モノクロアイコンのデザインについて] arakiハイハイスクールアドベンチャー_android版 [2025/10/02 23:59] (現在) – [独自の設定要素] araki
行 27: 行 27:
  それでは Good Luck!!!............  それでは Good Luck!!!............
  
- +{{::hhsadvrev:title.png?400|}} 
-{{::hhsadv:android001.png?400|}} +{{::hhsadvrev:isako.png?400|}}
-{{::hhsadv:android002.png?400|}}+
  
 ===== 概要 ===== ===== 概要 =====
行 36: 行 35:
 Google Play Storeには登録していないので、インストールにはちょいとひと手間かかります。 Google Play Storeには登録していないので、インストールにはちょいとひと手間かかります。
  
-Android 12, 13, 14での動作は確認しましたが、他のバージョンでの動作については不明です。+Android 16での動作は確認しましたが、他のバージョンでの動作については不明です。
  
 ===== ダウンロードとインストール ===== ===== ダウンロードとインストール =====
  
-こちらから[[https://www.wildtree.jp/~araki/HHSAdv120.apk|APKファイル]]をダウンロードして、インストールしてください。+こちらから[[https://www.wildtree.jp/~araki/HHSAdv121.apk|APKファイル]]をダウンロードして、インストールしてください。
  
  
行 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だから」といわれていろいろめんどくさいので、今回は採用していない。
行 224: 行 223:
 {{::hhsadvrev:custom_icon.png?200|カスタムアイコン}} {{::hhsadvrev:custom_icon.png?200|カスタムアイコン}}
 {{::hhsadvrev:materialyou.png?200|Material You}} {{::hhsadvrev:materialyou.png?200|Material You}}
 +
 +==== 独自の設定要素 ====
 +
 +{{::hhsadvrev:文字の大きさ.png?400|}}
 +
 +このゲームを最初に実装したころは Android 2.2とか2.3で端末画面も4インチないくらいのサイズだったので、画面の解像度も低く、あまり気にならなかったのですが、さすがに、昨今の大画面、高解像度のスクリーンでは、メッセージを表示している文字が小さく感じるようになってきました。((決して、老化が原因ではない……と信じてるから!))
 +
 +いえ、たぶん、システム設定を変えれば多少は大きくなるのでしょうが、そろそろ独自の設定を持ってもいいのでは、と、思いました。
 +
 +が、ドロップダウンで数字を選ぶとか、あんまりイケてない。
 +どうせなら、文字の大きさがわかるボタンで選びたい。((異論はあるかと思いますが。))
 +
 +そう思って、独自の設定ウィジェットを作ることにしました。
 +要するに、Preference クラスを継承して、自前の処理を組み込んでやればいいわけです。
 +が、これがなかなかのはまり要素満載の作業でした。
 +
 +=== 画面幅いっぱいに広がってしまう ===
 +
 +設定画面を開くと、標準の要素は左側にスペースがあって右側に表示されるのですが、標準のレイアウトをレイアウトインスペクタで調べて、可能な限り似せたレイアウトを作っているのに、どうしても左の隙間がつぶれてしまうのです。
 +
 +標準的なレイアウトは、全体を覆うLinearLayout(horizontal)があって、左側からicon_frameというLinearLayout(horizontal)が来て、これが左側に72dpの隙間を作り出し、その隣にRelativeLayoutがあって、その中に titleを表示する TextViewや、スイッチなどの要素が並びます。
 +
 +なので、この構造をまねて、icon_frameには16dpの左マージンをつけて、56dpのMinWidthをつけて、計72dpのスペースをつけるようにしました。
 +
 +その隣には width="0dp" layout_weight="1"のLinearLayout(horizontal)を置いて、この中に、FontSizeInlinePreferenceという自前のクラスの中でボタンを並べます。
 +
 +{{::hhsadvrev:文字の大きさ幅いっぱい.png?400|}}
 +
 +ところが、こんな感じで、左端のスペースをかき消して、幅いっぱいに広がってしまうのです。
 +
 +AIに聞くと、やれ、ボタンに表示してる "Aあ"が悪いだの、レイアウトパラメータに問題があるだの、いろんなことを言って、あれをやれこれをやれと言ってきますがどれも問題を解決するに至りません。
 +
 +仕方がないので、Layout Inspectorでちまちまと、標準のレイアウトと、自前のレイアウトとを比べていきます。
 +
 +すると icon_frameの Visibilityが、標準では INVISIBLEになっているものが、GONEになっているじゃありませんか。
 +とりあえず、FontSizeInlinePreference()のコードのほうで、icon_frame の Visibilityを ItemViewのVisibilityと同じになるようにしてやると、あら不思議。ちゃんと左端にスペースが出るじゃないですか。
 +
 +Visibilityの操作は、親クラスの中で行われているようなので、Android Studioで親クラスの処理を追っていくと、mIconSpaceReservedというprivate変数の値がfalseだとGONEにしていることがわかりました。
 +
 +private の変数なのでコード側からは変更できないですが、XML側でできることがわかり、問題を解消することができました。
 +
 +<code XML>
 +    <PreferenceCategory android:title="@string/pref_screen_settings"
 +        app:allowDividerBelow="false">
 +        <jp.wildtree.android.apps.hhsadvrev.FontSizeInlinePreference
 +            android:key="prefFontSize"
 +            android:title="@string/pref_font_size"
 +            android:defaultValue="16"
 +            app:iconSpaceReserved="true"/>
 +    </PreferenceCategory>
 +</code>
 +
 +=== PrefernceCategoryとの間に線 ===
 +
 +上のうまくいってない画面。「画面の設定」という PreferenceCategoryの表示と、「テキストの大きさ」という項目の間に横線が入っているのが見えるかと思います。
 +
 +ほかの項目では、カテゴリの下には線が入ってないのに、なぜか線が入る。
 +
 +消したい。邪魔だ。
 +
 +だが、Layout Inspectorでもいまいち、犯人がわからない。
 +まあ、幅問題が解決しても、線は横幅いっぱいに出ているので、PreferenceCategory側か、FontSizeInlinePreferenceの一番外側のLinearLayoutのどっちかなわけですが。
 +
 +結論から言うと、PreferenceCategory側でした。
 +app:allowDividerAboveとapp:allowDividerBelowというパラメータがあって、これが線を引くかどうかの制御をしていました。
 +しかし、ほかの要素ではこれ特に指定してないのだから、allowDividerAboveが trueで、allowDividerBelowがfalseがデフォルト値じゃないのかって思うんですが、やや解せぬ思いは残りましたが、線は消せました。
 +
 +<code XML>
 +    <PreferenceCategory android:title="@string/pref_screen_settings"
 +        app:allowDividerBelow="false">
 +</code>
  
 ==== モノクロアイコンのデザインについて ==== ==== モノクロアイコンのデザインについて ====
行 243: 行 313:
 このデザインをモノクロ化したものが、今回のアイコンとなっています。 このデザインをモノクロ化したものが、今回のアイコンとなっています。
  
 +==== 処理のタイミング ====
 +
 +クレジットロールはActivityとして実装しています。
 +呼び出しは Intent で行いますが、呼び出した時点で処理されるわけではなく、登録だけされて、呼び出しはユーザプログラム側の処理が済んでシステムに処理が戻されたタイミングになります。
 +
 +何がいいたいかというと、例えばゲームの開始時、オープニングのクレジットロールを呼び出すとともに、画面をゲームの初期画面に書き換えるのですが、オープニングの処理が始まる前に画面が書き換わるので、一瞬ちらっとゲームの開始画面が出た後にクレジットロールが始まります。
 +
 +かっこ悪い。
 +
 +暗転している裏で書き換えてほしいのに、舞台裏が見えちゃっているようでイケてません。
 +
 +エンディングでも同じで、タイトル画面に戻ってからクレジットロールが始まります。
 +
 +回避するためには、クレジットロール側の処理が終わって、Main Activityに処理が戻されるときに書き換えればいいことになります。
 +
 +具体的には、処理が戻ってくるときに onResume() が呼び出されるので、ここで適切な書き換えをすればいいことになります。
 +
 +単純に、ここに、オープニング処理から戻されたらしいならこれ、クリアしたらしいならこれ、という処理を書くと、スクリーンロックから復帰したり、タスクマネージャで別のアプリから戻されたときにも、onResume()が呼ばれるので、余計なタイミングでの呼び出しが発生することになります。
 +
 +そこで、onResumeOnce という ()->Unit 型の ArrayListを作って、クレジットロールを呼び出すときに、画面書き換えの一連の処理を登録して、onResume()側では呼び出したら捨ててしまうという処理にすればいいのではないかと考えてそのようにしています。
 +
 +<code kotlin>
 +
 +val onResumeOnce: ArrayList<()->Unit> = ArrayList<()->Unit>()
 +...
 +override fun onResume()
 +{
 +    ...
 +    if (onResumeOnce.isEmpty()) return
 +    for(f in onResumeOnce) {
 +        f()
 +    }
 +    onResumeOnce.clear()
 +}
 +...
 +onResumeOnce.add {
 +  // 処理を書くと onResume()の中で一度だけ呼ばれます
 +}
 +</code>

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also, you acknowledge that you have read and understand our Privacy Policy. If you do not agree, please leave the website.

More information