2022年 7月 22日
と言う訳で、リスタート(RESTART)を実装しました。
これは「そのマップの始めからやり直し」の機能です。
ゲームを始めて
進めて
リスタートで YES
初期の状態に戻ります。
これでいったんゲームオーバーになっても、何度でもやり直せます。
仕組み自体は簡単で、初期の状態をセーブしておくだけです。
////////// スタートデータ ////////// *start_data ; スタートデータセット n=0 sdat(n)=lx : n+ ; スクロール表示位置 sdat(n)=scf : n+ ; スクロールフラグ sdat(n)=dbpl : n+ ; 最大戦力プレイヤー sdat(n)=plb : n+ ; プレイヤー数 sdat(n)=0 : n+ ; 現在の順番 sdat(n)=mb : n+ ; 全HEX数 sdat(n)=ldb : n+ ; 国数 repeat mb : sdat(n)=map(cnt) : n+ : loop ; マップ repeat mb : sdat(n)=hwd(cnt) : n+ : loop ; HEXの外周枠情報 repeat lddb : sdat(n)=ld(cnt) : n+ : loop ; 領土 repeat (ldb+1)*ldlb+1 : sdat(n)=ldl(cnt) : n+ : loop ; 隣接国 repeat ldb+1 : sdat(n)=lpd(cnt) : n+ : loop ; 領土のプレイヤー repeat ldb+1 : sdat(n)=ldcd(cnt) : n+ : loop ; ダイス数 repeat ldb+1 : sdat(n)=ldcu(cnt) : n+ : loop ; キャラクターユニット repeat ldb+1 : sdat(n)=dpd(cnt) : n+ : loop ; 国のダイス表示順番 repeat ldb+1 : sdat(n)=lcx(cnt) : n+ : loop ; 中間座標x repeat ldb+1 : sdat(n)=lcy(cnt) : n+ : loop ; 中間座標y repeat ldb+1 : sdat(n)=ldhx1(cnt): n+ : loop ; 最左ライン repeat ldb+1 : sdat(n)=ldhx2(cnt): n+ : loop ; 最右ライン repeat ldb+1 : sdat(n)=ldhy1(cnt): n+ : loop ; 最上ライン repeat ldb+1 : sdat(n)=ldhy2(cnt): n+ : loop ; 最下ライン repeat plb+1 : sdat(n)=pfd(cnt) : n+ : loop ; プレイヤー操作 repeat plb+1 : sdat(n)=pld(cnt) : n+ : loop ; プレイヤーの領土数 repeat plb+1 : sdat(n)=pdca(cnt) : n+ : loop ; 増ダイス数 repeat plb+1 : sdat(n)=pad(cnt) : n+ : loop ; 行動順 repeat plb+1 : sdat(n)=dp(cnt) : n+ : loop ; 全ダイス戦力数 repeat plb+1 : sdat(n)=dcpn(cnt) : n+ : loop ; 表示ダイスグラNo. repeat plb+1 : sdat(n)=pdsd(cnt) : n+ : loop ; ストックダイス数 repeat 21 : sdat(n)=clpn(cnt) : n+ : loop ; カラー return *start_data_load ; スタートデータロード n=0 lx=sdat(n) : n+ ; スクロール表示位置 scf=sdat(n) : n+ ; スクロールフラグ dbpl=sdat(n) : n+ ; 最大戦力プレイヤー plb=sdat(n) : n+ ; プレイヤー数 padn=0 : n+ ; 現在の順番 mb=sdat(n) : n+ ; 全HEX数 ldb=sdat(n) : n+ ; 国数 repeat mb : map(cnt)=sdat(n) : n+ : loop ; マップ repeat mb : hwd(cnt)=sdat(n) : n+ : loop ; HEXの外周枠情報 repeat lddb : ld(cnt)=sdat(n) : n+ : loop ; 領土 repeat (ldb+1)*ldlb+1 : ldl(cnt)=sdat(n) : n+ : loop ; 隣接国 repeat ldb+1 : lpd(cnt)=sdat(n) : n+ : loop ; 領土のプレイヤー repeat ldb+1 : ldcd(cnt)=sdat(n) : n+ : loop ; ダイス数 repeat ldb+1 : ldcu(cnt)=sdat(n) : n+ : loop ; キャラクターユニット repeat ldb+1 : dpd(cnt)=sdat(n) : n+ : loop ; 国のダイス表示順番 repeat ldb+1 : lcx(cnt)=sdat(n) : n+ : loop ; 中間座標x repeat ldb+1 : lcy(cnt)=sdat(n) : n+ : loop ; 中間座標y repeat ldb+1 : ldhx1(cnt)=sdat(n): n+ : loop ; 最左ライン repeat ldb+1 : ldhx2(cnt)=sdat(n): n+ : loop ; 最右ライン repeat ldb+1 : ldhy1(cnt)=sdat(n): n+ : loop ; 最上ライン repeat ldb+1 : ldhy2(cnt)=sdat(n): n+ : loop ; 最下ライン repeat plb+1 : pfd(cnt)=sdat(n) : n+ : loop ; プレイヤー操作 repeat plb+1 : pld(cnt)=sdat(n) : n+ : loop ; プレイヤーの領土数 repeat plb+1 : pdca(cnt)=sdat(n) : n+ : loop ; 増ダイス数 repeat plb+1 : pad(cnt)=sdat(n) : n+ : loop ; 行動順 repeat plb+1 : dp(cnt)=sdat(n) : n+ : loop ; 全ダイス戦力数 repeat plb+1 : dcpn(cnt)=sdat(n) : n+ : loop ; 表示ダイスグラNo. repeat plb+1 : pdsd(cnt)=sdat(n) : n+ : loop ; ストックダイス数 repeat 21 : clpn(cnt)=sdat(n) : n+ : loop ; カラー return
今問題なのは、これをどのタイミングで実行するかです。
*game_main padn=0 ; 現在の順番 repeat plb if padn2>0 : padn=padn2 : padn2=0 ; ロード復帰 pn1=pad(padn) padn+ : if padn=plb : save 0 : break ; 全部終わり if pfd(pn1)=0 : continue ; 滅んでる ; cu表情 repeat ldb,1 : ldn=cnt if lpd(ldn)!pn1 : continue if ldcu(ldn)=0 : continue cupf(ldcu(ldn))=0 ; フラットに loop if pfd(pn1)=1 : msf=1 ; メインスイッチフラグ if pfd(pn1)=2 : msf=2 ; CPU tarn_endf=0 ; ターンエンドフラグ while tarn_endf=0 switch msf case 1 ; プレイヤー gosub *player if msf=0 : tarn_endf=1 : swbreak if mainf=9 : tarn_endf=1 : swbreak if loadf=1 { gosub *start_data_load ; スタートデータロード tarn_endf=1 : swbreak } swbreak case 2 ; CPU gosub *strategy ;if msf=0 : tarn_endf=1 : swbreak ;if tarn_endf=0 : swbreak gosub *tarn_end if te_kf=3 : save sl_keyn2 ; セーブ if loadf=1 { gosub *start_data_load ; スタートデータロード tarn_endf=1 } swbreak swend wend if mainf!5 : break loop padn2=0 return
見ての通りです。
CPUとプレイヤーで読み書きのタイミングが違います。
そして、通常のデータセーブとリスタートでも、読み書きとゲーム復帰のタイミングが違ってきます。
この辺が、まだ完全ではありません、ゲームからオプションに入って、それぞれの処理をして、それぞれの順番の途中から復帰する、これらが結構ややこしい。
少し抜本的に整理しようかと考えてます、元のメインルーチンはこんな感じなので
while ;---------- メインルーチン ---------- switch mainf case 0 : gosub *initialize : swbreak ; 初期 ; case 1 : gosub *opening : mainf=2 : swbreak ; オープニング ; case 2 : gosub *titl : swbreak ; タイトル case 3 : gosub *game_start : swbreak ; ゲーム開始 ;case 4 : gosub *tutorial ; swbreak ; チュートリアル case 5 : gosub *game_main : swbreak ; ゲームメイン ;case 6 : gosub *option : swbreak ; オプション ;case 8 : gosub *game_over : mainf=2 : swbreak ; ゲームオーバー case 9 : gosub *game_clear : swbreak ; ゲームクリア ;case 10 : gosub *ending : mainf=2 : swbreak ; エンディング swend
この辺にオプション画面を差し込んで、ゲームルーチン(*game_main)から抜けて処理してから、もう一度ゲームルーチンに戻る、という形にすればスッキリするはず。
一応 6番に予約してはありましたけどね。
どうしても増築工法、建て増しソースでスパゲティソースみたいな事になってます。