ゲームの得点を保存しよう!

ゲームのハイスコアとかを保存したいと思うことがあります。
そんな時に読んでください。
では、スクリプト『tokuten.as』を解説していきます。
実際のスクリプトとは違った順番で並んでいますので、
ぜひ、ダウンロードして実験してください。

■初期化

 

	#include "hspda.as"

	dim sc,10		;スコアデータ
	sdim nm,30,10		;元の名前データ
	sdim nm2,30,10		;ソート後の名前データ
	alloc sd,1000		;データ読みこみ書きこみ用バッファ

	datamax=5

最初に”hspda”という機能拡張を使用するためにinclude命令で「hspda.as」を読みこんでいます。
今回は得点のソートをするので、新機能を使ってみることにしました。
標準の命令だけでもソートは出来るのですが、無理をせずにDLLを使ってみましょう。
そして、使用する変数の初期化をしています。
配列は沢山確保しましたが、得点ランキングに残すのは5つです。

■データファイルのチェック

	;データファイルのチェック
	;存在する場合は読みこむ
	;ない場合はこのスクリプト内のデータを使う

	chdir exedir
	skiperr 1
	bload "tokuten.txt",sd
	ernum=err
	skiperr 0

	if ernum=12:goto *top1	;12 is ファイルが無い

得点と名前を書いたファイルをデータファイルと呼ぶことにします。
作り始めるときに、データファイルを読みこみ->名前入力->データファイルに書き出し、という感じを考えました。
ところが、データファイルを消してしまった場合や、最初に起動した場合はデータファイルが存在しないことも考えられます。
ここではskiperr命令を使って一時的にエラーが出ないようにしています。
「ファイルが存在しない」という時だけ、下のスクリプトを実行します。

*top1
	sc.0=100:nm.0="薄味百"
	sc.1=7000:nm.1="薄味7千"
	sc.2=5000:nm.2="薄味五千"
	sc.3=200:nm.3="薄味二百"
	sc.4=9999:nm.4="薄味最大"

■配列への読みこみ

データファイルの内容が変数sdにbloadできた場合には、下のスクリプトで配列に読みこみます。

 
	;読みこんだデータを配列に変換
	notesel sd
	repeat datamax
	 noteget a,cnt
	 strmid b,a,0,8		;数字部分
	 strmid c,a,8,30	;30の部分は文字の最大値、とりあえず30文字
	 int b:sc.cnt=b
	 nm.cnt=c
	loop
	goto *top2

保存したデータファイルの中身を見てみましょう。

00009999薄味最大
00007000薄味7千
00005000薄味五千
00000300test
00000200薄味二百

数字8桁の後に名前が入っています。
読みこんだ変数sdをnotepad命令を使って1行ずつに分けて、strmid命令で更に分割しています。

■名前入力

 
*top2
	gosub *name_sort	;本当はソートされたものが入っているはずだけど一応ソート
	gosub *name_put		;内容を表示

	mes " "	

	testsc=300		;試しに得点を300としてやってみます
	mes "得点"+testsc

	;最小値と比較
	if sc.4>testsc:goto *name_end		;最小値より小さい場合は終了

	mes "名前を入力してください"
	nowname=""
	input nowname,150,25
	button "OK",*name_add
	stop


配列に入った得点をソートして表示します。
変数testscに得点を入れます。
数値を色々変更して試してみてください。
最小の得点より変数testscの値が小さい場合は、下のスクリプトを実行し、名前入力をせずに終わります。

*name_end
	mes "ランキング5位以内に入りません。"
	stop


■ソートルーチン、表示ルーチン

得点の表示とソートはこのようになっています。

*name_put
	repeat datamax
		p=" "+sc.cnt+":"+nm.cnt
		mes p:loop
	return
*name_sort
	sortval sc,1	;数値により大きい順に
	repeat datamax
		sortget n,cnt
		nm2.cnt=nm.n
	loop
	repeat datamax
		nm.cnt=nm2.cnt
	loop
	return

	stop

表示ルーチン「*name_put」はloopしつつ配列を表示しています。
ソートルーチン「*name_sort」はsortval命令を使っています。
配列scの内容をソートしています。
パラメータに1を指定すると”大きい順”になります。
さて、ソートして順番が並べ替えられるのはいいのですが、そのままだと名前と得点があわなくなってしまいます。
そんな時に使うのがsortget命令です。
ソートの後に、「この値は前は何番にいたの?」という命令です。
「この得点は何番の人の値だったの?」と聞いているわけです。
先ほどのソートの結果を調べて、名前と得点が合うような配置に配列nm2の中に名前をコピーしていきます。
最後に配列nmに戻して終わりです。

■自分の値を加えて、再度ソート

*name_add

	cls

	sc.4=testsc	
	nm.4=nowname
	gosub *name_sort	;最終的にソート
	gosub *name_put		;表示

	;ここから保存
	sd=""
	repeat datamax
	 s=sc.cnt
	 str s,8		;数字の最大桁数
	 sd+=s+nm.cnt+"\n"
	loop
	;mes  sd
	strlen sdl,sd
	bsave "tokuten.txt",sd,sdl
	stop

sc.4には最小の値が入っていて、既にtestscと比較してtestscの方が大きい値だというのがわかっています。
そこに新しいデータをいれます。
そして、またソートします。

結果をデータファイルとして保存します。
数値を8桁の文字に変換して、名前をその後につなげます。
改行コード"¥n"でつないで、一つの文字列にします。
最後に長さを調べてデータファイルを保存すればおわりです。


ソースのダウンロード

実践編の目次に戻る