Hextrategy SAVE、LOADを実装した


2019年 10月 4日
 
 
 SAVE、LOADを実装した。

 今回は 1ヶ月くらいだったかな。

 色々と方法を考えたけど、まずデータを「システムデータ」「ゲームデータ」「ユニットデータ」「アイテムデータ」の 4つに分割してセーブデータを作る事にし、データの格納方法は結局オーソドックスにデータを順番に足す方法になった。
 
 

 システムデータは一つだけで、残りのゲームデータ、ユニットデータ、アイテムデータはセーブヶ所事に作られる。

 データの格納方法は、結局ユニットデータ、アイテムデータは足す詰め込み方式だと量が多くて訳が分からなくなるので、そのまま ud(ユニットデータ)、id(アイテムデータ)の変数を別個にセーブする事にした。

 残りのゲームデータを配列変数 dtn2に順番に放り込んで BSAVE命令でセーブする事にした。

 本当は一つのセーブヶ所事に一つのファイルの方がスマートなんだろうけど、そこは初心者なので技術的に難しいし、誰もセーブファイルを覗いたりしないだろうという事だ。
 
 
 ではソースを見てみよう。

;------- SAVE LOAD -------
#deffunc save1
dt_no=1
; システムデータ -----------

	n=;データ総数
	 dim dtn1,n

; メインボリューム
; BGMボリューム
; SEボリューム

; プレイヤーカラー
; プレイヤー数
; 減らすHEX

	bsave "sy_data"+dt_no+".dat",dtn1

	return


#deffunc save2

; ゲームデータ ----------

	n=101
	n+=(25*15)
	n+=mub+(26*mgvb)+(3*25)+(26*mdb)
	n+=(plb*hub*3)+(25*nub*3)
	n+=(hib1+hib2+hib3+hib4+hib5+hib6+hib7+hib8+hib9+hib10+hib11+hib12)*plb
	n+=(nib1+nib2+nib3+nib4+nib5+nib6+nib7+nib8+nib9+nib10+nib11+nib12)*25
	n+=10 ; 予備

	dim dtn2,n ;データ総数 ----------


	dtn2(1)=1	; データバージョン
	dtn2(2)=plb	; plbプレイヤー数
	dtn2(3)=trn	; ターン数
	;dtn2(4)=1	; プレイヤーカラー


	dtn2(21)=pubk	; 国の人数
	dtn2(22)=pubc	; 城の人数
	dtn2(23)=pubs	; 人材府の人数
	dtn2(24)=pubsb	; 〃の最大数

	dtn2(25)=pibk	; 国のアイテム数
	dtn2(26)=pibc	; 城のアイテム数
	dtn2(27)=pibs	; 倉庫のアイテム数
	dtn2(28)=pibsb	; 〃の最大数

	dtn2(31)=hib1	; プレイヤーのアイテム順列数
	dtn2(32)=hib2
	dtn2(33)=hib3
	dtn2(34)=hib4
	dtn2(35)=hib5
	dtn2(36)=hib6
	dtn2(37)=hib7
	dtn2(38)=hib8
	dtn2(39)=hib9
	dtn2(40)=hib10
	dtn2(41)=hib11
	dtn2(42)=hib12

	dtn2(51)=nib1	; NPCのアイテム順列数
	dtn2(52)=nib2
	dtn2(53)=nib3
	dtn2(54)=nib4
	dtn2(55)=nib5
	dtn2(56)=nib6
	dtn2(57)=nib7
	dtn2(58)=nib8
	dtn2(59)=nib9
	dtn2(60)=nib10
	dtn2(61)=nib11
	dtn2(62)=nib12


	n=101
	repeat 25
	 dtn2(n)=pubn(cnt+1)	: n+	; ヒーローのユニット最大数
	loop
	repeat 25
	 dtn2(n)=pubsn(cnt+1)	: n+	; 人材府の数
	loop
	repeat 25
	 dtn2(n)=pubg(cnt+1)	: n+	; 現在のユニット数
	loop

	repeat 25
	 dtn2(n)=pibn(cnt+1)	: n+	; ヒーローのアイテム最大数
	loop
	repeat 25
	 dtn2(n)=pibsn(cnt+1)	: n+	; 倉庫の数
	loop
	repeat 25
	 dtn2(n)=pibg(cnt+1)	: n+	; 現在のアイテム数
	loop


	repeat 25
	 dtn2(n)=map(cnt+1)		: n+	; マップ(0=無し、1=火山、2=水辺、3=草原、4=山、5=森、6沼)
	loop

	repeat 25
	 dtn2(n)=mpl(cnt+1)		: n+	; 支配しているマップ
	loop
	repeat 25
	 dtn2(n)=mpc(cnt+1)		: n+	; 首都
	loop
	repeat 25
	 dtn2(n)=pmp(cnt+1)		: n+	; マナポイント
	loop

	repeat 25
	 dtn2(n)=wp(cnt+1)		: n+	; マップ戦力値
	loop
	repeat 25
	 dtn2(n)=wpb(cnt+1)		: n+	; マップ戦力最大値
	loop
	repeat 25
	 dtn2(n)=wp_cost(cnt+1)	: n+	; 派遣コスト
	loop

	repeat 25
	 dtn2(n)=hde(cnt+1)		: n+	; 既に攻め込むのに使った国
	loop

	repeat 25
	 dtn2(n)=hf(cnt+1)		: n+	; ヒーローの生存フラグ(0=無し、1=プレイヤー、2=コンピューター)
	loop


	repeat mub
	 dtn2(n)=mu(cnt)		: n+	; 0=領主、1~9=部隊
	loop

	repeat 26*mgvb
	 dtn2(n)=mgv(cnt)		: n+	; 政府
	loop

	repeat 3*25
	 dtn2(n)=fsorf(cnt)		: n+	; 出撃フラグ
	loop

	repeat 26*mdb
	 dtn2(n)=md(cnt)		: n+	; マップデータ 
	loop


	repeat plb*hub
	 dtn2(n)=hr1(cnt) : n+	; ヒーローの筋力順列
	loop
	repeat plb*hub
	 dtn2(n)=hr2(cnt) : n+	; ヒーローの魔力順列
	loop
	repeat plb*hub
	 dtn2(n)=hr5(cnt) : n+	; ヒーローの総力順列
	loop


	repeat 25*nub
	 dtn2(n)=nr1(cnt) : n+	; 中立の筋力順列
	loop
	repeat 25*nub
	 dtn2(n)=nr2(cnt) : n+	; 中立の魔力順列
	loop
	repeat 25*nub
	 dtn2(n)=nr5(cnt) : n+	; 中立の総力順列
	loop


	repeat hib1*plb : dtn2(n)=hip1(cnt) : n+ : loop	; 片手
	repeat hib2*plb : dtn2(n)=hip2(cnt) : n+ : loop	; 両手
	repeat hib3*plb : dtn2(n)=hip3(cnt) : n+ : loop	; 槍
	repeat hib4*plb : dtn2(n)=hip4(cnt) : n+ : loop	; 棍棒
	repeat hib5*plb : dtn2(n)=hip5(cnt) : n+ : loop	; 杖
	repeat hib6*plb : dtn2(n)=hip6(cnt) : n+ : loop	; 弓銃
	repeat hib7*plb : dtn2(n)=hip7(cnt) : n+ : loop	; 投射
	repeat hib8*plb : dtn2(n)=hip8(cnt) : n+ : loop	; 盾
	repeat hib9*plb : dtn2(n)=hip9(cnt) : n+ : loop	; 鎧
	repeat hib10*plb: dtn2(n)=hip10(cnt): n+ : loop	; アイテム
	repeat hib11*plb: dtn2(n)=hip11(cnt): n+ : loop	; 魔法
	repeat hib12*plb: dtn2(n)=hip12(cnt): n+ : loop	; 特殊

	repeat nib1*25 : dtn2(n)=nip1(cnt) : n+ : loop	; 片手
	repeat nib2*25 : dtn2(n)=nip2(cnt) : n+ : loop	; 両手
	repeat nib3*25 : dtn2(n)=nip3(cnt) : n+ : loop	; 槍
	repeat nib4*25 : dtn2(n)=nip4(cnt) : n+ : loop	; 棍棒
	repeat nib5*25 : dtn2(n)=nip5(cnt) : n+ : loop	; 杖
	repeat nib6*25 : dtn2(n)=nip6(cnt) : n+ : loop	; 弓銃
	repeat nib7*25 : dtn2(n)=nip7(cnt) : n+ : loop	; 投射
	repeat nib8*25 : dtn2(n)=nip8(cnt) : n+ : loop	; 盾
	repeat nib9*25 : dtn2(n)=nip9(cnt) : n+ : loop	; 鎧
	repeat nib10*25: dtn2(n)=nip10(cnt): n+ : loop	; アイテム
	repeat nib11*25: dtn2(n)=nip11(cnt): n+ : loop	; 魔法
	repeat nib12*25: dtn2(n)=nip12(cnt): n+ : loop	; 特殊


	bsave "gm_data"+dt_no+".dat",dtn2


; ユニットデータ ----------

	bsave "un_data"+dt_no+".dat",ud


; アイテムデータ ----------

	bsave "it_data"+dt_no+".dat",id


	return



#deffunc load1

; システムデータ -----------

	n=;データ総数
	 dim dtn1,n

	bload "sy_data"+dt_no+".dat",dtn1

; メインボリューム
; BGMボリューム
; SEボリューム

; プレイヤーカラー
; プレイヤー数
; 減らすHEX
	vo_set

	return


#deffunc load2

; ゲームデータ

	n=101
	n+=(25*15)
	n+=mub+(26*mgvb)+(3*25)+(26*mdb)
	n+=(plb*hub*3)+(25*nub*3)
	n+=(hib1+hib2+hib3+hib4+hib5+hib6+hib7+hib8+hib9+hib10+hib11+hib12)*plb
	n+=(nib1+nib2+nib3+nib4+nib5+nib6+nib7+nib8+nib9+nib10+nib11+nib12)*25
	n+=10 ; 予備

	dim dtn2,n ;データ総数 ----------

	bload "gm_data"+dt_no+".dat",dtn2


	dav=dtn2(1)	; データバージョン
	plb=dtn2(2)	; plbプレイヤー数
	trn=dtn2(3)	; ターン数
	;dtn2(4)=1	; プレイヤーカラー


	pubk=dtn2(21)	; 国の人数
	pubc=dtn2(22)	; 城の人数
	pubs=dtn2(23)	; 人材府の人数
	pubsb=dtn2(24)	; 〃の最大数

	repeat plb,1
	 udsh(cnt)=pub*(cnt-1)+1 ; ユニットデータ先頭、英雄
	loop


	pibk=dtn2(25)	; 国のアイテム数
	pibc=dtn2(26)	; 城のアイテム数
	pibs=dtn2(27)	; 倉庫のアイテム数
	pibsb=dtn2(28)	; 〃の最大数

	repeat 25,1
	 udsn(cnt)=plb*pub+nub*(cnt-1)+1 ; ユニットデータ先頭、中立
	loop


; プレイヤーのアイテム順列数
	hib1=dtn2(31)	: dim hip1,hib1*plb+1	; 片手		80
	hib2=dtn2(32)	: dim hip2,hib2*plb+1	; 両手		30
	hib3=dtn2(33)	: dim hip3,hib3*plb+1	; 槍		40
	hib4=dtn2(34)	: dim hip4,hib4*plb+1	; 棍棒		30
	hib5=dtn2(35)	: dim hip5,hib5*plb+1	; 杖		30
	hib6=dtn2(36)	: dim hip6,hib6*plb+1	; 弓銃		50
	hib7=dtn2(37)	: dim hip7,hib7*plb+1	; 投射		30
	hib8=dtn2(38)	: dim hip8,hib8*plb+1	; 盾		40
	hib9=dtn2(39)	: dim hip9,hib9*plb+1	; 鎧		120
	hib10=dtn2(40)	: dim hip10,hib10*plb+1	; アイテム	140
	hib11=dtn2(41)	: dim hip11,hib11*plb+1	; 魔法		140
	hib12=dtn2(42)	: dim hip12,hib12*plb+1	; 特殊		70

; 中立のアイテム順列
	nib1=dtn2(51)	: dim nip1,nib1*25+1	; 片手		8
	nib2=dtn2(52)	: dim nip2,nib2*25+1	; 両手		3
	nib3=dtn2(53)	: dim nip3,nib3*25+1	; 槍		4
	nib4=dtn2(54)	: dim nip4,nib4*25+1	; 棍棒		3
	nib5=dtn2(55)	: dim nip5,nib5*25+1	; 杖		3
	nib6=dtn2(56)	: dim nip6,nib6*25+1	; 弓銃		5
	nib7=dtn2(57)	: dim nip7,nib7*25+1	; 投射		3
	nib8=dtn2(58)	: dim nip8,nib8*25+1	; 盾		4
	nib9=dtn2(59)	: dim nip9,nib9*25+1	; 鎧		12
	nib10=dtn2(60)	: dim nip10,nib10*25+1	; アイテム	14
	nib11=dtn2(61)	: dim nip11,nib11*25+1	; 魔法		14
	nib12=dtn2(62)	: dim nip12,nib12*25+1	; 特殊		7


	n=101
	repeat 25,1
	 pubn(cnt)=dtn2(n)		: n+	; ヒーローのユニット最大数
	loop
	repeat 25,1
	 pubsn(cnt)=dtn2(n)		: n+	; 人材府の数
	loop
	repeat 25,1
	 pubg(cnt)=dtn2(n)		: n+	; 現在のユニット数
	loop

	repeat 25,1
	 pibn(cnt)=dtn2(n)		: n+	; ヒーローのアイテム最大数
	loop
	repeat 25,1
	 pibsn(cnt)=dtn2(n)		: n+	; 倉庫の数
	loop
	repeat 25,1
	 pibg(cnt)=dtn2(n)		: n+	; 現在のアイテム数
	loop


	repeat 25,1
	 map(cnt)=dtn2(n)		: n+	; マップ(0=無し、1=火山、2=水辺、3=草原、4=山、5=森、6沼)
	loop

	repeat 25,1
	 mpl(cnt)=dtn2(n)		: n+	; 支配しているマップ
	loop
	repeat 25,1
	 mpc(cnt)=dtn2(n)		: n+	; 首都
	loop
	repeat 25,1
	 pmp(cnt)=dtn2(n)		: n+	; マナポイント
	loop

	repeat 25,1
	 wp(cnt)=dtn2(n)		: n+	; マップ戦力値
	loop
	repeat 25,1
	 wpb(cnt)=dtn2(n)		: n+	; マップ戦力最大値
	loop
	repeat 25,1
	 wp_cost(cnt)=dtn2(n)	: n+	; 派遣コスト
	loop

	repeat 25,1
	 hde(cnt)=dtn2(n)		: n+	; 既に攻め込むのに使った国
	loop

	repeat 25,1
	 hf(cnt)=dtn2(n)		: n+	; ヒーローの生存フラグ(0=無し、1=プレイヤー、2=コンピューター)
	loop


	repeat mub
	 mu(cnt)=dtn2(n)		: n+	; 0=領主、1~9=部隊
	loop

	repeat 26*mgvb
	 mgv(cnt)=dtn2(n)		: n+	; 政府
	loop

	repeat 3*25
	 fsorf(cnt)=dtn2(n)		: n+	; 出撃フラグ
	loop

	repeat 26*mdb
	 md(cnt)=dtn2(n)		: n+	; マップデータ 
	loop


	repeat plb*hub
	 hr1(cnt)=dtn2(n) : n+	; ヒーローの筋力順列
	loop
	repeat plb*hub
	 hr2(cnt)=dtn2(n) : n+	; ヒーローの魔力順列
	loop
	repeat plb*hub
	 hr5(cnt)=dtn2(n) : n+	; ヒーローの総力順列
	loop

	repeat 25*nub
	 nr1(cnt)=dtn2(n) : n+	; 中立の筋力順列
	loop
	repeat 25*nub
	 nr2(cnt)=dtn2(n) : n+	; 中立の魔力順列
	loop
	repeat 25*nub
	 nr5(cnt)=dtn2(n) : n+	; 中立の総力順列
	loop


	repeat hib1*plb : hip1(cnt)=dtn2(n)	: n+ : loop	; 片手
	repeat hib2*plb : hip2(cnt)=dtn2(n) : n+ : loop	; 両手
	repeat hib3*plb : hip3(cnt)=dtn2(n) : n+ : loop	; 槍
	repeat hib4*plb : hip4(cnt)=dtn2(n) : n+ : loop	; 棍棒
	repeat hib5*plb : hip5(cnt)=dtn2(n) : n+ : loop	; 杖
	repeat hib6*plb : hip6(cnt)=dtn2(n) : n+ : loop	; 弓銃
	repeat hib7*plb : hip7(cnt)=dtn2(n) : n+ : loop	; 投射
	repeat hib8*plb : hip8(cnt)=dtn2(n) : n+ : loop	; 盾
	repeat hib9*plb : hip9(cnt)=dtn2(n) : n+ : loop	; 鎧
	repeat hib10*plb: hip10(cnt)=dtn2(n): n+ : loop	; アイテム
	repeat hib11*plb: hip11(cnt)=dtn2(n): n+ : loop	; 魔法
	repeat hib12*plb: hip12(cnt)=dtn2(n): n+ : loop	; 特殊

	repeat nib1*25	: nip1(cnt)=dtn2(n)	: n+ : loop	; 片手
	repeat nib2*25	: nip2(cnt)=dtn2(n)	: n+ : loop	; 両手
	repeat nib3*25	: nip3(cnt)=dtn2(n)	: n+ : loop	; 槍
	repeat nib4*25 	: nip4(cnt)=dtn2(n)	: n+ : loop	; 棍棒
	repeat nib5*25	: nip5(cnt)=dtn2(n)	: n+ : loop	; 杖
	repeat nib6*25	: nip6(cnt)=dtn2(n)	: n+ : loop	; 弓銃
	repeat nib7*25	: nip7(cnt)=dtn2(n)	: n+ : loop	; 投射
	repeat nib8*25	: nip8(cnt)=dtn2(n)	: n+ : loop	; 盾
	repeat nib9*25	: nip9(cnt)=dtn2(n)	: n+ : loop	; 鎧
	repeat nib10*25	: nip10(cnt)=dtn2(n): n+ : loop	; アイテム
	repeat nib11*25	: nip11(cnt)=dtn2(n): n+ : loop	; 魔法
	repeat nib12*25	: nip12(cnt)=dtn2(n): n+ : loop	; 特殊



; ユニットデータ ----------

	pub=pubk*25+pubc+pubs*pubsb	; プレイヤーのユニットデータ数(130)

	ub=plb*pub+nub*25		; ユニットの最大数
	 dim ud,(ub+10)*udb+1	; ユニットデータ

	bload "un_data"+dt_no+".dat",ud


; アイテムデータ ----------

	pib=pibk*25+pibc+pibs*pibsb	; ヒーローのアイテムデータ数(800)

	ib=pib*plb+nib*25	; アイテムの最大数
	 dim id,(ib+1)*idb	; アイテムデータ

	bload "it_data"+dt_no+".dat",id


	return

 まだ製作途中で全部できてはいないが、ゲームの中断と再開には成功している。

 バグは・・・・しらない。

 見ての通り、ユニツトデータ ud、アイテムデータ idは個別に、変数そのままをセーブ、ロードしている。

 なぜかというと、ゲームがバージョンアップして内部変数が変更になった時に、せーブデータの互換性を考えると、本当はデータ構造に余裕を持たせて普遍の番地を持たせて不動格納すれば良いのだろうけど、それだと余白の分データ量が多くなるし、それならデータ量を抑えるなら加算詰め込み式なんだろうけど、それだとデータ構造が変わった時に対応が難しい、というような事を考えた結果、ユニットとアイテムの膨大なデータはそれだけで取り扱った方が良いだろう、という事になりました。

 要領を得ず済みませんけど、要はそもそもセーブ機能を実装する技術をそんなに知らない、という事ですね。

 例えば、もしかしたら本当は膨大なデータを扱うには MySQLみたいなデータ専用の何かで扱うのが良いのかもしれませんね。
 
 
 残りはゲームデータとして、dtn2(n)の配列変数に、順次データNo.を加算式にデータ格納してます(詰め込み式、かな)

 データのファイル No.は、

bsave “gm_data”+dt_no+”.dat”,dtn2

 のように、間に dt_noとか数字を挟んでやれば、それぞれ別のファイル名になるようです。

 例えば、

bsave “gm_data”+1+”.dat”,dtn2

 と書けば、gm_data1.datというファイルができます。
 
 
 まだ途中なので書いてませんけど、loadの際には

exist “save.dat”
 if strsize=-1 : return

 のように exist命令でそのファイルがあるかどうか確認する作業がいるでしょう。
 
 
 現在は GUIの部分、つまりセーブロードの画面を作ってます。

 今回は以上です。
 
 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です