超雑なプログラムを組む
仕様書を元に倉庫番プログラムを組んでいきましょう
まず、どの場面で何がどういう風に動くかを決めていきましょうか
(仕様書に含めようか迷いましたがここに書きます)
まずは各場面で動くもの
- タイトル :(選択肢)
- ゲーム画面 :プレイヤー、荷物、ゴール
- エンディング:なし?
どういう風に動くか・・・雑に行きましょう
- 選択肢 :キーボードのWで上にSで下に移動、Zで決定
- プレイヤー:キーボードのWASDで上下左右に動く、壁には行けない
- 荷物 :プレイヤーが押したら押した方向に壁がない時に動く
- ゴール :ゲーム開始時に決定されてそれ以降動くことはない
各場面もどうやったら変わるかを雑に決めます
- タイトル→ゲーム画面 :タイトルではじめるを選ぶ
- タイトル→ゲーム終了 :タイトルで終わるを選ぶ
- ゲーム画面→タイトル :プレイヤーが諦めたとき
- ゲーム画面→エンディング:クリアした時
- エンディング→タイトル :Z押したら
書いてない場面には変わらないってことで
こんだけ書けばゲームの流れはできそうですね
文章でプログラム書いてみますか、まずは場面の移り変わりから
void main(){ LABEL:; タイトル if(タイトルではじめるが選ばれた){ ゲーム画面 if(プレイヤーが諦めた){ goto LABEL; } if(クリアした){ エンディング } }else if(タイトルでおわるが選ばれた){ ゲーム終了 } goto LABEL; }
場面の変更はこんな感じですかね、めっちゃ冗長ですしきちんと終わりそうにないですけど
ふむ、そういえばプレイヤーの操作とかにキーボードの入力を受け付ける必要がありましたね
でも、遊んでくれる人が何回入力するかわからないですね・・・
とりあえず製作者がやって欲しいものがくるまで無限ループにしましょうか
void main(){ LABEL:; while(はじめるかおわるが選ばれてない){ 入力受付 タイトル } if(タイトルではじめるが選ばれた){ while(プレイヤーが諦めてない){ 入力受付 ゲーム画面 if(クリアした){ while(Z押されてない){ 入力受付 エンディング } } } }else if(タイトルでおわるが選ばれた){ ゲーム終了 } goto LABEL; }
プレイヤーが諦めたらタイトルに行くので、ゲーム画面でのwhileの条件をそのようにしました
それにしてもなんか複雑になってきましたね、はっはっは
その上に何回も入力受付ってしてますね、いやぁ冗長だ
更にmain文の最後にgotoまで使ってやがる、これはやばい
あとゲーム画面でのwhile終わらなさそう
とりあえず何が悪いかって、if文の多さですよね
更に言うとwhile内whileっていうのも
さて、どうしましょうか
・・・ふむ、そもそも、例えば、タイトルを処理しているとき以外にタイトルを呼び出さなければ問題ないはずですね
つまり、タイトルの時にタイトルの処理のみをしてゲーム画面などの処理をさせなければいい
この場面の時はこの処理を、この場面の時はこの処理を・・・って記述していけばよさそうですね
ってことで
enum 場面制御{ TITLE, GAME, ENDING, GAMEEND, }; void main(){ bool ゲーム終了する = false 場面制御 今の場面 = TITLE while(!ゲーム終了する){ 入力受付 switch(今の場面){ case TITLE: タイトル if(タイトルではじめるが選ばれた){ 今の場面 = GAME; } if(タイトルでおわるが選ばれた){ 今の場面 = GAMEEND; } break; case GAME: ゲーム画面 if(クリアした){ 今の場面 = ENDING; } if(プレイヤーが諦めた){ 今の場面 = TITLE; } break; case ENDING: エンディング if(Z押された){ 今の場面 = TITLE; } break; case GAMEEND: ゲーム終了する = true; break; } } }
場面を管理する変数を付け加えました
さらに、ゲームが終わるかどうかを判断する変数も入れました
これで、入力受付は一回で、動かしたい場面だけ動かせるようになりました
また、今まで行くつもりのなかった場面にも自由に移動できるようになりました
プログラム自体は長くなりましたが、わかりやすくなった、はずです
これで場面の移り変わりのプログラムはだいたい問題なさそうですね
・・・日本語ばっかりできちんとしたプログラムになってない?
気のせいですよやだなぁ
長くなったので一旦区切ります
続きは各場面内での処理を書いていきます