SMILE BASIC 小技(8)
BGのキャラ定義の一部がキャラクターコードに対応していることと、BGGETを使うと非常に簡単に自作キーボードを作ることができる。
具体的には、
TOUCH OUT STTM, TX, TY G=BGGET(レイヤー番号,TX,TY,1)
とすると、GにBGのキャラ番号がとれる。
BGの32〜95番には、同一アスキーコードの英数字記号が割り当てられているので、これを使って処理する。
簡易キーボードの例:
前半部分で文字を並べているが、この文字のレイアウトを変えても、判定部分は一切変える必要がない。
実用例としては、この小技を使って、拙作のゲームブック版ドルアーガの塔アドベンチャーシートで、数値入力用パネルを実装している。
ゲームブック「ドルアーガの塔」アドベンチャーシート for プチコン3号 (β2版)
また、上記の小技を使って簡単なゲームを作ってみた。
OSE! Catch The Gyoku
キー【EBNECE3E】
遊び方:
「玉」をタッチでつかまえてください。
ただし、人質になっているキングとクイーンを間違えてタッチしたり、画面外に逃げられると負けになります。
バイナリファイル調査その(2)
型変換調査
(1)
VAR A#[10] A#[0]=1.5 A#[1]=2.5 SAVE "DAT:BINDATA",A# VAR B%[0] LOAD "DAT:BINDATA",B% ?"LEN=";LEN(B%) ?B%[0] ?B%[1] ?B%[2] ?B%[3]
とすると、
LEN=10 1 2 0 0
と表示される。
(2)
VAR A%[10] A%[0]=1 A%[1]=2 SAVE "DAT:BINDATA",A% VAR B#[0] LOAD "DAT:BINDATA",B# ?"LEN=";LEN(B#) ?B#[0] ?B#[1] ?B#[2] ?B#[3]
とすると、
LEN=10 1 2 0 0
と表示される。
つまり、直接的にバイナリとして読み込まれるわけではなく、
LOAD時に、SAVE時の型として一度読み込まれてから、その後に変数に代入されていることがわかる。
バイナリファイル調査その(1)
バイナリファイルサイズ調査
(1)
VAR A[1] a[0]=1 SAVE "DAT:BINTEST",A
とすると、36バイトのファイルが作成された。
(2)
VAR A#[2] A#[0]=1 A#[1]=2 SAVE "DAT:BINTEST",A#
だと44バイト。
(3)
VAR A%[1] A%[0]=1 SAVE "DAT:BINTEST",A%
だと32バイト。
(4)
VAR A%[2] A%[0]=1 A%[1]=2 SAVE "DAT:BINTEST",A%
だと36バイト。
よって、
ヘッダー28バイト+(倍精度小数なら8バイト、整数なら4バイト)*個数
の大きさと思われる。
#ヘッダーが読み取れたら、GRPファイルかそうじゃないか判別できると思って調査しはじめたけど、今のところヘッダーを読み取る方法はない。
PRGINSしたコードを呼び出すことができるか
昨日、いろいろ試していた結果。
あるスロットから他のスロットにPRGINSでコードを追加して、追加したコードを呼び出すことができるか、という研究。
PRGEDIT 3 FUNCNM$="_ABC" IF !CHKCALL(FUNCNM$) THEN PRGINS "COMMON DEF "+FUNCNM$+"()" PRGINS " RETURN 1" PRGINS "END" ENDIF USE 3 PRINT CALL(FUNCNM$) '1が表示される
ポイントは、PRGINSをした後でUSEを実行していること。
おそらく、USEでそのスロットがコンパイルされるようだ。
(その証拠にUSE 3をPRGINSより前に入れると、Undefined functionエラーになる)
第4回大喜利で入賞したLOWERDASHもこの考え方で、起動時にコードを追加している。
が、USEは何回でも呼び出せるので、プログラム中で必要な時にどんどんコードを追加するという使い方ができると思う。
現在作成中の構造体ライブラリには一部にこの考え方を使おうかと思う。
SMILE BASIC 小技(7)
テキストの表示デモの例。
昔からある技をSMILE BASICで焼き直したもの。
他にもたくさんあったと思うが、基本的なものを書いた。
今回は長いので公開キーで。
【D3KKXJAX】
1.ターミナル風 ■を付けて表示する基本型。
FOR I=0 TO LEN(T$)-1 LOCATE X+I,Y:PRINT MID$(T$,I,1);"■"; WAIT 2 NEXT WAIT 30 LOCATE X+I,Y:PRINT " ";
2.真ん中から表示する 文字数が奇数/偶数を考慮する。
M1=FLOOR(LEN(T$)/2-0.5) M2=LEN(T$) DIV 2 FOR I=0 TO FLOOR(LEN(T$)/2-0.5) LOCATE X+M1-I,Y:PRINT MID$(T$,M1-I,1); LOCATE X+M2+I,Y:PRINT MID$(T$,M2+I,1); WAIT 5 NEXT
3.電光掲示板風 長い文字列の一部を場所を変えながら取る。
W=20 FOR I=0 TO LEN(T$)+W*2-1 LOCATE X,Y PRINT MID$(" "*W+T$+" "*W,I,W) WAIT 3 NEXT
4.泡のように現れる 「.oO」を連続するとアニメっぽく見える。
FOR I=0 TO LEN(T$)-1 REPEAT R=RND(LEN(T$)) UNTIL CHKCHR(X+R,Y)==0 LOCATE X+R,Y:PRINT "."; WAIT 3 LOCATE X+R,Y:PRINT "o"; WAIT 3 LOCATE X+R,Y:PRINT MID$(T$,R,1); WAIT 3 NEXT
5.回転しているように見える 「O|」で回転ぽく見える。
FOR I=0 TO 20 LOCATE X,Y ATTR 4*(I MOD 4==2) PRINT T$*(I MOD 2==0)+"|"*LEN(T$)*(I MOD 2==1); WAIT 12 NEXT ATTR 0
6.明るくなって消える 点灯の間隔で明度を表す。
FOR I=0 TO 80 LOCATE X,Y PRINT T$ WAIT 5-MIN(25,ABS(40-I)) DIV 5 LOCATE X,Y PRINT " "*T$ WAIT MIN(25,ABS(40-I)) DIV 5 NEXT
(番外)6.のGPUTCHR版 色で指定した方がクオリティが高い。
FOR I=0 TO 80 L=MIN(255,400-ABS(40-I)*10) GPUTCHR X*8,Y*8,T$,RGB(L,L,L) WAIT 5 NEXT
3号プログラミング 覚え書き(6) スマイルボタン編
・スマイルボタンに設定したプログラムはSLOT 4で実行される。
SLOT 4には他のスロットにはない特有の制限、機能がある。
・スマイルボタンに設定したプログラムからスロット指定なしでEXECされたプログラムもSLOT 4で実行される。
この時、読み込まれたファイルはSLOT 4で実行されるので、SLOT 4の制限が課される。
ただし、SLOT 0〜3にLOADして、EXEC スロット番号とする場合はこの限りではない。SLOT 0〜3に読み込まれたライブラリも同様。EXEC "PRGスロット番号:ファイル名"もスロットにロードしてからEXECするので同様。
スマイルボタンに設定されたプログラム、および、そのプログラムからスロット指定なしでEXECされたプログラムは、いずれも動作が同じになるので、以下では「SLOT 4で実行されるプログラム 」ということにする。
・COMMON DEFが使えない
SLOT 4で実行されるプログラム中にCOMMON DEFがあると、「Can't use in tool program」というエラーになる。
・SLOT 4でのみ、他のプロジェクトのファイルをEXECで直接実行できる
SLOT 4で実行されるプログラムについてのみ、EXEC "プロジェクト名/ファイル名" とすると、他のプロジェクトのファイルを直接実行できる。
なお、SLOT 0〜3でEXEC "プロジェクト名/ファイル名"を実行するとIllegal function callになる。
・CHKFILEで指定するファイル名に必ずファイル種別を付ける必要がある
以前はSLOT 4で実行する場合はファイル種別を付ける必要があったが、現在(Ver.3.2.1で確認)ではSLOT 0〜3と同様につける必要がなくなった。
SMILE BASIC 小技(6)
INC,SHIFT,UNSHIFT,PUSH,POPは文字列にも使うことができる。
VAR A$="ABC",C$ INC A$,"DEF" '文字列の最後に追加 PRINT A$ 'ABCDEF C$=SHIFT(A$) '文字列の先頭の一文字を取る PRINT C$,A$ 'A BCDEF UNSHIFT A$,"Z" '文字列の先頭に文字を付け加える PRINT A$ 'ZBCDEF PUSH A$,"G" '文字列の最後に文字を加える PRINT A$ 'ZBCDEFG C$=POP(A$) '文字列の最後の一文字を取る PRINT C$,A$ 'G ZBCDEF
DECは文字列には使えない模様。(使い方を知ってたら教えてください。)
なお、これらの命令・関数は、文字列を参照型として扱う。
参照型とは何かをここで詳しく書くことはできないが、
概ね以下のように思っていただければよい。
通常、
VAR A$="ABC"
A$=A$+"D"
のようにすると、"ABC"とあったメモリの場所とは別の場所に”ABCD"という文字列が作成され、A$はそこを指すようになる。
これが普通の文字列の動作。
しかし、上記の参照型の命令(例えばINC)の場合、"ABC"とあったメモリの位置に"D"が追加されて、結果として"ABCD"になる。
これはPRINT命令でA$を表示した結果は同じなので、まったく同じことのようだが、別の変数に参照を代入した場合に違いが出てくる。
VAR A$="ABC" VAR B$=A$ A$=A$+"D" PRINT A$ 'ABCD PRINT B$ 'ABC
VAR A$="ABC" VAR B$=A$ INC A$,"D" PRINT A$ 'ABCD PRINT B$ 'ABCD
ここで詳しく説明できないので、詳細は別項を立てる。
SHIFT(文字列)もサンプルで使われてた
SHIFT("文字列")で文字列の頭一文字をとることができますが、
これも実は公式のサンプル中で使われていました。
SYS/STAFFROLLの中です。
使ってよさそうなので、これも小技で紹介することにします。
SMILE BASIC 小技(5)
コンソールへのPRINT時に文字列をセンタリング(中央によせて表示すること)したいことは多い。
LOCATEのX位置を決めるには、画面幅(50文字)の半分(25文字)から、表示したい文字列の長さの半分を引けばよい。
毎回計算するのはめんどうなので、次のような記述を使う。
A$="文字列" LOCATE FLOOR(25-LEN(A$)/2),CSRY PRINT A$
問題になるのは文字列の長さが奇数になる場合で、2で割り切れないので左半分と右半分のどちらが長くなる。
これは個人の好みでどちらかに寄せるしかない。
私は左半分の方を少しだけ長くなるようにした。
右半分の方を少しだけ長くしたい場合は、上記の2行目を
LOCATE FLOOR(25.5-LEN(A$)/2),CSRY
に変えればよい。(FLOORの中に0.5を足す。)
少し応用して、上下画面、WIDTHのサイズに対応するようにしたのが以下。
A$="文字列" D%=DISPLAY() W%=WIDTH() LOCATE FLOOR((50-D%*10)/S%/2-LEN(A$)/2),CSRY PRINT A$
なお、XSCREEN 4の時は、上画面が幅50文字から40文字になるが、現状(Ver.3.2.1)ではXSCREENの設定をとる方法がないので、上記はXSCREEN 4に対応していない。
XSCREEN 4の時は、
LOCATE FLOOR(20/S%-LEN(A$)/2),CSRY
とする。
ドルアーガの塔 アドベンチャーシート for プチコン3号 (β2版)
ゲームブック「ドルアーガの塔」アドベンチャーシート for プチコン3号 (β2版)
β(ベータ)版ですが、よければどうぞ。
マッピングはそのうち入れたいです。
プロジェクト名: EDDRU
公開キー: 4D2PEE7D
DKENNJ3Y K5N353KV XRKE73AV RS3XY3NJ RE3YN3Q4
公開日: 2016/10/02
2016/04/04 2016/03/20 2016/03/16 2016/03/13
バージョン: 0.12
0.10 0.09 0.08 0.06 0.07
幻想迷宮書店さんが、ゲームブック版ドルアーガの塔を、Kindle版にしたものを発売していらっしゃいます。
(元は1986年に東京創元社から刊行され、後に2000年代になってから創土社から復刊されました。創土社版はゲームバランスほかに若干の修正がなされています。Kindle版は創土社版を元に電子書籍化したものになっています。)
Kindleなので、アドベンチャーシートは自前で用意することになりますが、そのアドベンチャーシートをプチコン3号で作りました。(マッピングとかまだ...)
Kindleでまだ買ってない人は買いませう。(アフィやってないです...)
悪魔に魅せられし者 ドルアーガの塔 (幻想迷宮ゲームブック) Kindle版
魔宮の勇者たち ドルアーガの塔 (幻想迷宮ゲームブック) Kindle版
魔界の滅亡 ドルアーガの塔 (幻想迷宮ゲームブック) Kindle版
400〜500円と超お買い得になってます。
■履歴
(10/02)漢字ライブラリによる漢字表示と、なかくんさんの日本語入力FEP「UTIL」への対応
(04/04)ダイスタブにクリアボタン追加、誰の攻撃ターンかを示すことができるラジオボタンを追加、一部項目名をアイコンに差し替え
(03/20)起動時にファイル名入力をキャンセルするとエラーになるバグ修正、セーブデータにセーブ日時を追加、ダイスタブにクリアボタンを追加
(03/16)漢字入力IMEとしてEDKANJIPNL ver0.09を組み込み。EDKANJIPNLの操作ガイドが表示されます。
(03/13)EDKANJIPNLを取り込んで、入力フォームで日本語入力できるようにしました。
辞書にゲームブック版ドルアーガの塔で使いそうな単語を登録しておきました(何が入っているかは秘密)。
ダイスロールを付けました。
ダイスタブに戦闘用の敵項目記入欄を追加しました。
終了用アイコンを追加しました。
数値入力パネルに簡易計算機能を追加しました。
<今後の予定>
・アイコンのグラフィック
・(はるか未来) マッピング
★重要:スロット3へのオートセーブ
間違えて終了してプログラムの変数が消えてしまうと悲しいので、項目をどこか更新すると、数秒後にスロット3にオートセーブします。
EDDRUを起動時にスロット3にセーブデータがあればそれを読み込みます。したがって、プログラムを中断しても、再度STARTすると中断前の状態からはじまります。
起動時にスロット3にセーブデータがなければLOAD画面に移りファイルを指定します。キャンセルすると1巻の初期値が表示されます。
手動でファイルにセーブしたい時は、画面左下のファイルアイコンをタップしてセーブしてください。
★セーブ形式
テキストファイル(JSON形式)になっていますので、プログラム本体がバージョンアップしてもセーブ形式に互換性がなくなることはないようにしています
★UTILの導入方法
「UTIL」はなかくんさんが開発された、日本語入力プログラムです。
文字が大きく、とても使いやすいので今回は外部IMEとして対応するようにしました。
UTILは同梱していないので、自分でダウンロードして、EDDRUのフォルダにコピーする必要があります。
なお、UTILをコピーしない場合でも、内蔵のIMEであるEDKANJIPNLで日本語入力が可能です。
UTILの導入の仕方は、UTILのバージョンによって異なります。現在はVer.2.20とVer.3.00に対応しています。
・UTIL Ver.2.20をお持ちの場合
EDDRUのフォルダに、UTILフォルダから「UTIL」というファイル1個をコピーしてください。
・UTIL Ver.3.00をお持ちの場合
EDDRUのフォルダに、UTILフォルダから「UTIL」「KDAT_P」「KDAT_SG12」「KDAT_SG16」「UF_DIC」というファイル計5個をコピーしてください。
上記ファイルをコピーしておくと、起動時に自動的に読み込まれ、プログラム内で日本語入力に使えるようになります。
■その他蛇足
ダイスにはちょっとだけこだわりがあり、サイコロの三次元的な回転を考慮しています。
といっても三次元で計算しているわけではなく、有向グラフでの状態遷移で表現しています。(例えば、2→1と回転してきた時は、次に遷移するのは3,4,5のいずれか)
なお、一様分布の試行の組み合わせ(掛け算)なので、結果も一様分布になるはずですが、実際に1000回くらい試行しても結構な片寄りがあります。(もとにしているRNDの性質によるものだと思いますが、改善が難しいので了承の上でお使いください。)
あと、画面上でのサイコロ同士の衝突はいい加減です。
本当ならば運動量保存則を使って計算すべきなのでしょうが、とりあえずそれっぽく見えるのでそのままにしています。
サイコロ同士の衝突は、弾性衝突だと仮定すれば、単にお互いの速度を入れ替えればいいだけだと気付いたので、その方針で修正しました。
と思ったら、近い速度で衝突するとサイコロ同士が重なりあって無限ループになるバグが発生するようになってしまった。
とりあえず前の版の公開キーを生かしてあるので、そちらを使ってください。
判定を見直してバグが解消したので衝突を修正した版の方を公開しました。
■その他蛇足2
実はプチコン3号版の以前にmkIIで同じものを作っていた。
ゲームブック ドルアーガの塔のアドベンチャーシートをプチコンで
しかし、文字入力にカタカナしか使えないチープさと、マッピングの箇所で難儀して挫折。。。
今回はその反省を生かし、文字入力にはすでに作ったIMEを組み込み、マッピングはとりあえずほったらかし、とした。
だけどマッピングはそのうちどうにかしたい。。。