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の部分、つまりセーブロードの画面を作ってます。
今回は以上です。