モンスターを一体ずつ巣から出すには?
実際にパックマンではモンスターは1体を除いて巣のなかにいて、時間の経過とともに巣から出てきます。
そこでそのようになるようにプログラムを改良します。
まず巣のなかを以下のように変えます。フィールド変数を変えています。
MoveMonstarメソッドの変更
MoveMonstarメソッドを以下のように変更します。
こでまではモンスターの動きはこれまでの移動方向とは逆の方向に移動することはありませんでした(パワー餌を食べたときは除く)。巣のなかで待機している場合は上下に移動させるためにGetStringMazeCellメソッドが↑や↓を返したときはモンスターの動きを上下反対にしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
public partial class Form1 : Form { async Task<bool> MoveMonstar(int monstar) { bool ret; int ijikeMonstarMoveCount = ijikeMonstarMoveCounts[monstar]++; List<Direct> directs = GetMonstarMoveDirect(monstar); int r = 0; if(MonstersDirect[monstar] == Direct.North) { string str = GetStringMazeCell(MonstersCellX[monstar], MonstersCellY[monstar]); // ↓追加された部分 if(str != "↓") directs.Remove(Direct.South); // ↑追加された部分ここまで r = random.Next(0, directs.Count); } else if(MonstersDirect[monstar] == Direct.South) { string str = GetStringMazeCell(MonstersCellX[monstar], MonstersCellY[monstar]); // ↓追加された部分 if(str != "↑") directs.Remove(Direct.North); // ↑追加された部分ここまで r = random.Next(0, directs.Count); } else if(MonstersDirect[monstar] == Direct.West) { directs.Remove(Direct.East); r = random.Next(0, directs.Count); } else if(MonstersDirect[monstar] == Direct.East) { directs.Remove(Direct.West); r = random.Next(0, directs.Count); } Direct direct; if(isMonsterIjike[monstar] && ijikeMonstarMoveCount % ijikeMonstarSpeedDownRate != 0) direct = MonstersDirect[monstar]; else { if(directs.Count != 0) direct = directs[r]; else{ direct = MonstersDirect[monstar]; } } if(!isMonsterIjike[monstar]) ret = await MonstarMoveDirect(monstar, direct); else ret = await IjikeMonstarMoveDirect(monstar, direct); return ret; } } |
Timer_Tickメソッドの変更
最初は赤以外のモンスターは巣のなかで上下に移動しています。そして時間が経過することで巣の外に出てきます。
そのためにフィールドを表現するための文字列を変更しています。これで時間の経過とともにモンスターは巣の外に出ることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
public partial class Form1 : Form { // 追加されたフィールド変数 int TimerTickCount = 0; private async void Timer_Tick(object sender, EventArgs e) { if(ignoreTick) return; TimerTickCount++; ignoreTick = true; Task<bool> pacTask = MovePacmanDirect(pacDirect); Task<bool> monstarsTask = MoveMonstars(); await pacTask; await monstarsTask; bool isGameOver = false; int monster = IsPacmanDead(); if(monster >= 0 && !isMonsterIjike[monster]) isGameOver = !await OnPacmanDead(); else if(monster >= 0 && isMonsterIjike[monster]) await OnEatMonster(monster); ignoreTick = false; if(IsStageClear) { timer.Stop(); MessageBox.Show("ゲームクリア!"); } if(isGameOver) { timer.Stop(); MessageBox.Show("GameOver"); } // ここから下が追加された部分 if(TimerTickCount > 10) row10 = " │ │↓↓↑↓↓│ │ "; if(TimerTickCount > 20) row11 = "L────┼─┤→→↑←E├─┼────R"; if(TimerTickCount > 30) row11 = "L────┼─┤→→↑←←├─┼────R"; } } |
OnPacmanDeadメソッドの変更
フィールド変数TimerTickCountはミスをしたときにリセットされなければなりません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
public partial class Form1 : Form { async Task<bool> OnPacmanDead() { // モンスターがすぐに巣の外に出てこないようにする TimerTickCount = 0; row10 = " │ │↓↓↓↓↓│ │ "; row11 = "L────┼─┤B→A←C├─┼────R"; // いじけモンスターは元に戻す isMonsterIjike[0] = false; isMonsterIjike[1] = false; isMonsterIjike[2] = false; isMonsterIjike[3] = false; // 残機をひとつ減らす pacRest--; if(pacRest <= 0) return false; await Task.Delay(1000); // パックマンとモンスターをゲーム開始の位置に戻す InitPacman(); InitMonstar(0); InitMonstar(1); InitMonstar(2); InitMonstar(3); Invalidate(); await Task.Delay(1000); return true; } } |