“RUN” それは魔法の言葉

私とコンピュータの思い出を、だらだらと綴ります。最近はHSP3でのゲーム作り日記です

94.HSPでゲーム&ウォッチのヘルメットを作ろう その12

最後はおまけ。
Windowsで開発していながら、Windowsで動くexeファイルの生成を一度もしたことがなかったので、練習がてらexe化にチャレンジした。

exe化するだけなら簡単。スクリプトエディタで、「実行ファイル自動作成」のメニューを選ぶだけ。
しかし、そのままexeファイルにしても、同じフォルダに、プログラム内で使っている画像と音声ファイルが存在しないとエラーになる。
それに、アプリケーションのウィンドウサイズが、hsp3dish.iniファイルの記述通りにならず、小さいサイズになってしまう。

この問題を解決するために、今動いているプログラムの冒頭に、ファイルをパッケージングするための記述を追加していった。

まず、exeファイル名。#packopt name で、ファイル名を指定できる。
ウィンドウサイズは、#packopt xsizeと、#packopt ysizeで指定すればいい。

読み込んで使用しているファイル群は、#pack "ファイル名" で書いて行く。暗号化してパッケージする#epack も用意されているらしいが、今回は特に不要なので、そのまま追加する、#packで書いて行った。
ファイルの保存先パスにサブフォルダがある場合は、サブフォルダのパスまで記述すれば、フォルダ階層も作成できるみたい。
ただ、今回のゲーム&ウォッチ再現では、ファイル数も少なく、全部同じ階層に保存しているので、ファイル名だけ羅列していった。

しかし、落とし穴がここにあった。(ちゃんと制限事項に書いてあるのだがw)
ファイル名が12文字以内でないと、exeを実行すると、エラーになる。
画像のファイル名は、helmet_xxx.png みたいに、ヘルメットで使っていることがわかるようにしていたが、軒並み12文字を超えてしまい、エラーになった…
元のファイル名から、接頭辞のhelmet_を全部取ってしまい、12文字以内のファイル名に変更して、無事単独のexeファイルで動くようになった。

#packopt name "helmet"
#packopt xsize 1015		; 横サイズ
#packopt ysize 671		; 縦サイズ

#pack "body.png"
#pack "player.png"
#pack "tool1.png"
#pack "tool2.png"
#pack "tool3.png"
#pack "tool4.png"
#pack "tool5.png"
#pack "door.png"
#pack "missmark.png"
#pack "digitalfont.png"
#pack "miss.png"
#pack "gamemode.png"
#pack "mralarm.png"
#pack "bgm.wav"
#pack "door.wav"
#pack "miss.wav"
#pack "missclear.wav"

これだけ記述を追加しなくてはならず、HSP3DishでAndroidアプリにしたときに影響すると嫌なので、新しいフォルダを作って、hspファイル、中で使用しているファイルをすべてコピーした後、別物のファイルとして作るようにした。
同じソース内で、パッケージの記述でOSごとに分岐できるんだろうけど、調べて苦労するよりも分けた方が早いww

あとはexeファイルのアイコン画像が、HSPお決まりのスープカップの画像になる。
このアイコンを変更するためのユーティリティ「Let's HSPIC!」があった。ほんと長年使われている言語、開発環境だけあって、誰かが何かツールを作ってくれている。ありがたい。
アイコンは、icoファイルを事前に作成しておく。画像の加工に使っているフリーソフトGIMPでは、icoファイルへのエクスポートもできるので、作業員と工具の部分を切り出して、アイコン画像にした。
四角く枠を作って、元の筐体のように紫系の色を付けた。
出来たのがこれ。

f:id:CORO3:20210603003245j:plain

配布するわけじゃないけど、アプリになったーって実感は得られるね。

ここまで作った後に、すでにHSP3.5で、アイコンの埋め込みに対応していたことを知ったw
#packopt icon "アイコン.icoを書いておいて、自動作成するだけだったww
かくして、ファイアも同じ要領でexe化したのだった。

93.HSPでゲーム&ウォッチのヘルメットを作ろう その11

開発中にHSP3DishでAndroidのアプリに変換して、見栄えや操作感を試していたのだが、途中から起動せずに落ちるようになってしまった。
画像ファイルをassetフォルダに入れてないときに落ちていたので、何度も確認してassetフォルダに置いてみたがダメ。
少し放置していたが、そうもいかなくなったので、原因を特定することにした。
動いていた時点のソースから、付け加えた部分のプログラムを削除して、ビルド。スマホにインストールしては確認を繰り返した。
しかし、一向に改善しない。

どこに問題があるのかわからないので、ざっくりプログラムを全部消して、1行メッセージを表示するだけにした。
これでも動かない…
もしやと思い、変数の初期値を設定しているところを消すと、動いた…
さらに絞り込んでいくと、どうやら2次元配列に値を代入するところがだめだと分かった。

配列に対して初期値をセットするのに、カンマ区切りで書けるのはすごく楽だった。
Windows上で動かす限りは、2次元配列でも大丈夫な書き方だったのだが、うまく動かない。
HSPの公式掲示板で、2015年に全く同じ書き方で困っている人の質問スレッドを見つけ、解決できる!と思ったら…
ファイルに書いておいて読み込むという代替方法が示されていた…
さすがに面倒なので、1つずつ代入すれば動くんじゃね?と思い、試したら大丈夫だった。
今後も、2次元以上の多次元配列の時はこういう風に書くか、ファイルから読み込むか、データ量次第で切り替える必要がある。

;この書き方はAndroidではNG
dim tooly,5,5 ;工具の表示座標の配列
  tooly(0,0)=233,259,279,303,322
  tooly(0,1)=228,258,284,309,334
  tooly(0,2)=235,262,283,303,326
  tooly(0,3)=239,265,285,301,322
  tooly(0,4)=234,255,288,315,336

;Androidで動かないので、配列に一つずつ代入
tooly(0,0)=233: tooly(1,0)=259: tooly(2,0)=279: tooly(3,0)=303: tooly(4,0)=322
tooly(0,1)=228: tooly(1,1)=258: tooly(2,1)=284: tooly(3,1)=309: tooly(4,1)=334
tooly(0,2)=235: tooly(1,2)=262: tooly(2,2)=283: tooly(3,2)=303: tooly(4,2)=326
tooly(0,3)=239: tooly(1,3)=265: tooly(2,3)=285: tooly(3,3)=301: tooly(4,3)=322
tooly(0,4)=234: tooly(1,4)=255: tooly(2,4)=288: tooly(3,4)=315: tooly(4,4)=336

92.HSPでゲーム&ウォッチのヘルメットを作ろう その10

今回は完全に後回しにした、音とバイブレーション関係を作る。
鳴らす音は、4つ。

  1. 工具が落ちる音
  2. 作業員がドアに入った音
  3. ミス音
  4. ミスクリア音

工具が落ちる音は5列分いるが、同じwavファイルをmmloadで読み込むときに、IDを別々に振ることで対応した。

;BGMのwavファイルを読み込み
mmload "helmet_bgm.wav",1
mmload "helmet_bgm.wav",2
mmload "helmet_bgm.wav",3
mmload "helmet_bgm.wav",4
mmload "helmet_bgm.wav",5
	
mmload "helmet_door.wav",6
	
mmload "helmet_miss.wav",7
mmload "helmet_missclear.wav",8

「ファイア」の時は、落下人が移動するごとに音を鳴らしていきたかったが、うまくいかなかった。
しかし、今回のヘルメットでは、工具の列が1つ落下するごとに、1回鳴らせばよいので、何も考えずに作っただけで、それっぽくなり満足。

バイブレーションは、工具が落ちるとき以外は、すべて振動するように追加した。

せっかくなので、音のオンオフ機能を付けることにした。
ゲーム選択画面で、一緒に選択させる。ここでせっかくなので、アラームおじさんに登場いただいた。
画面右上のアラームおじさんをクリックすれば、音のオン・オフが切り替わるようにした。

オン・オフのフラグをもとに、mmplayを実行する前にif文で判定した。
バイブレーションはフラグに関係なく実行させた。

これで一通り完成♪
あとは、ファイアの時と同じように、オリジナルのアイコンの作成をして、差し替えた後に、ビルド。
手持ちのAndoridで遊べるようになった。

完成したゲームはこちら。
youtu.be

91.HSPでゲーム&ウォッチのヘルメットを作ろう その9

次はハイスコアの記録処理を作る。
外部ファイルの読み込み、書き込みの練習として、ハイスコアの記録を題材にした。

テキストファイルに、1行ずつゲームモードごとの点数を書き込んでおき、それを読み込んで、ハイスコアの配列に入れるようにしてみた。

noteset命令で読み込み用のバッファを確保。noteload命令でファイルを読み込む。
読み込んだファイルは、行単位で取得、上書きができる。行数はnotemaxに入っているので、ループを回すときの回数にする。
noteget命令で、読み込んだ行の情報を読み込んで、ハイスコアの配列に代入する。

うん。うまくいった。

;ファイルからハイスコアを読み込んでセットする
notesel filebuf
noteload "hiscore.txt"

dim hiscore,2 ;ハイスコア

repeat notemax
	noteget buf,cnt
	hiscore(cnt)=int(buf)
loop

noteunsel

しかし、Windowsでは読み書きできるのに、Androidでは読み込みしかできない。
そこで別の方法で保存することにした。
bsave命令、bload命令で、バイト単位で保存、読み込みをする。
配列変数をそのままbsave命令で保存、bload命令で読み込むサンプルがあったので、簡単に作れた。

exist命令を使うと、ファイルの存在有無を判定できる。
まず、ファイルが存在するかを確認して、なければ、スコアを0にしてファイルを保存。
存在したら、読み込んで、ハイスコアの配列にセットする。

;ファイルからハイスコアを読み込んでセットする
dim hiscore,2 ;ハイスコア

exist "hiscore.dat"
if strsize>0 {
  bload "hiscore.dat",hiscore
} else {
  ;ファイルがなければいったん保存して作成
  hiscore=0,0
  bsave "hiscore.dat",hiscore
}

この方法なら、Androidでもハイスコアが保存、読み込みできた。
ファイルは、Windowsだと同じフォルダ内に、Androidだとアプリのデータ領域に保存される(らしい)