Contents
ワープできるようにする
これまで作成してきた「パックマン」もどきにはワープトンネルがありませんでした。今回はワープトンネルも機能するようにします。
通路の変更
まずフィールド変数の以下の部分を書き換えます。
row11の文字列をワープトンネルにつながるように変更しています。またトンネルの入り口を「L」と「R」にしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public partial class Form1 : Form { string row01 = " ┌───┬───┐ ┌───┬───┐ "; string row02 = " │ │ │ │ │ │ "; string row03 = " │ │ │ │ │ │ "; string row04 = " ├───┼─┬─┴─┴─┬─┼───┤ "; string row05 = " │ │ │ │ │ │ "; string row06 = " │ │ │ │ │ │ "; string row07 = " └───┤ └─┐ ┌─┘ ├───┘ "; string row08 = " │ │ │ │ "; string row09 = " │ ┌─┴─┴─┐ │ "; string row10 = " │ │ │ │ "; string row11 = "L────┼─┤ ├─┼────R"; // 変更部分 string row12 = " │ │ │ │ "; string row13 = " │ ├─────┤ │ "; string row14 = " │ │ │ │ "; string row15 = " ┌───┼─┴─┐ ┌─┴─┼───┐ "; string row16 = " │ │ │ │ │ │ "; string row17 = " └─┐ ├─┬─┴─┴─┬─┤ ┌─┘ "; string row18 = " │ │ │ │ │ │ "; string row19 = " ┌─┴─┘ └─┐ ┌─┘ └─┴─┐ "; string row20 = " │ │ │ │ "; string row21 = " └───────┴─┴───────┘ "; } |
またワープトンネルの入り口「L」と「R」の部分にも通路を描画する必要があります。
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 { Image GetCellImage(int colum, int row) { string str = GetStringMazeCell(colum, row); if(str == "─") return EestWest; else if(str == "│") return NorthSouth; else if(str == "┐") return SouthWest; else if(str == "┌") return SouthEast; else if(str == "┘") return NorthWest; else if(str == "└") return NorthEest; else if(str == "┬") return SouthEastWest; else if(str == "┤") return NorthSouthWest; else if(str == "┴") return NorthEastWest; else if(str == "├") return NorthSouthEast; else if(str == "┼") return Plus; else if(str == "L") // 追加部分 return EestWest; else if(str == "R") // 追加部分 return EestWest; return null; } } |
CanPacmanMoveDirectメソッドの変更
パックマンが移動できるかどうかを判定するCanPacmanMoveDirectメソッドに対して、LとRの部分に対応する処理を追加しました。
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 |
public partial class Form1 : Form { bool CanPacmanMoveDirect(Direct direct) { string str = GetStringMazeCell(pacCellX, pacCellY); if(direct == Direct.North) { if(str == "├" || str == "┼" || str == "┤" || str == "└" || str == "┴" || str == "┘" || str == "│") return true; else return false; } if(direct == Direct.South) { if(str == "┌" || str == "┬" || str == "┐" || str == "├" || str == "┼" || str == "┤" || str == "│") return true; else return false; } if(direct == Direct.East) { if(str == "┌" || str == "┬" || str == "├" || str == "┼" || str == "└" || str == "┴" || str == "─" || str == "L" || str == "R") return true; else return false; } // "L" と "R" の場合に対応できるようにした if(direct == Direct.West) { if(str == "┬" || str == "┐" || str == "┼" || str == "┤" || str == "┴" || str == "┘" || str == "─" || str == "L" || str == "R") return true; else return false; } return false; } } |
MovePacmanDirectメソッドの変更
パックマンを移動させるMovePacmanDirectメソッドでワープトンネルを通過すると反対側に移動できるようにしました。
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 |
public partial class Form1 : Form { async Task<bool> MovePacmanDirect(Direct direct) { if(CanPacmanMoveDirect(direct)) { if(direct == Direct.North) pacCellY--; if(direct == Direct.South) pacCellY++; if(direct == Direct.East) { // 追加部分 if(GetStringMazeCell(pacCellX, pacCellY) == "R") pacCellX = 0; else pacCellX++; } if(direct == Direct.West) { // 追加部分 if(GetStringMazeCell(pacCellX, pacCellY) == "L") pacCellX = 20; else pacCellX--; } for(int i = 0; i < 4; i++) { if(direct == Direct.North) pacPosY -= CELL_HEIGHT / 4; if(direct == Direct.South) pacPosY += CELL_HEIGHT / 4; if(direct == Direct.East) pacPosX += CELL_WIDTH / 4; if(direct == Direct.West) pacPosX -= CELL_WIDTH / 4; Invalidate(); await Task.Delay(PACMAN_DELAY); } Rectangle newRect = GetMazeCell(pacCellX, pacCellY); pacPosX = newRect.X; pacPosY = newRect.Y; OnPacmanMoved(pacCellX, pacCellY); } return true; } } |
モンスターもワープできるようにする
モンスターの動き(いじけ状態も含めて)も同様に対応させる必要があります。
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 60 61 62 63 64 65 66 67 68 69 70 71 |
public partial class Form1 : Form { List<Direct> GetMonstarMoveDirect(int monstar) { List<Direct> directs = new List<Direct>(); string str = GetStringMazeCell(MonstersCellX[monstar], MonstersCellY[monstar]); if(str == "┌") { directs.Add(Direct.South); directs.Add(Direct.East); } if(str == "┬") { directs.Add(Direct.East); directs.Add(Direct.South); directs.Add(Direct.West); } if(str == "┐") { directs.Add(Direct.South); directs.Add(Direct.West); } if(str == "├") { directs.Add(Direct.North); directs.Add(Direct.East); directs.Add(Direct.South); } if(str == "┼") { directs.Add(Direct.North); directs.Add(Direct.East); directs.Add(Direct.South); directs.Add(Direct.West); } if(str == "┤") { directs.Add(Direct.North); directs.Add(Direct.South); directs.Add(Direct.West); } if(str == "└") { directs.Add(Direct.North); directs.Add(Direct.East); } if(str == "┴") { directs.Add(Direct.North); directs.Add(Direct.East); directs.Add(Direct.West); } if(str == "┘") { directs.Add(Direct.North); directs.Add(Direct.West); } // str == "L" || str == "R"のときの処理を追加 if(str == "─" || str == "L" || str == "R") { directs.Add(Direct.East); directs.Add(Direct.West); } if(str == "│") { directs.Add(Direct.North); directs.Add(Direct.South); } return directs; } } |
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 60 61 62 63 64 |
public partial class Form1 : Form { async Task<bool> MonstarMoveDirect(int monstar, Direct direct) { if(direct == Direct.North) { MonstersDirect[monstar] = Direct.North; for(int i = 0; i < 4; i++) { MonstersPosY[monstar] -= CELL_HEIGHT / 4; Invalidate(); await Task.Delay(PACMAN_DELAY); } MonstersCellY[monstar]--; } if(direct == Direct.East) { MonstersDirect[monstar] = Direct.East; for(int i = 0; i < 4; i++) { MonstersPosX[monstar] += CELL_WIDTH / 4; Invalidate(); await Task.Delay(PACMAN_DELAY); } // GetStringMazeCell == "R"のときの処理を追加 if(GetStringMazeCell(MonstersCellX[monstar], MonstersCellY[monstar]) == "R") MonstersCellX[monstar] = 0; else MonstersCellX[monstar]++; } if(direct == Direct.South) { MonstersDirect[monstar] = Direct.South; for(int i = 0; i < 4; i++) { MonstersPosY[monstar] += CELL_HEIGHT / 4; Invalidate(); await Task.Delay(PACMAN_DELAY); } MonstersCellY[monstar]++; } if(direct == Direct.West) { MonstersDirect[monstar] = Direct.West; for(int i = 0; i < 4; i++) { MonstersPosX[monstar] -= CELL_WIDTH / 4; Invalidate(); await Task.Delay(PACMAN_DELAY); } // GetStringMazeCell == "L"のときの処理を追加 if(GetStringMazeCell(MonstersCellX[monstar], MonstersCellY[monstar]) == "L") MonstersCellX[monstar] = 20; else MonstersCellX[monstar]--; } // CELL_HEIGHTが4で割り切れない場合、ずれが発生するのでその補正のための処理 Rectangle newRect = GetMazeCell(MonstersCellX[monstar], MonstersCellY[monstar]); MonstersPosX[monstar] = newRect.X; MonstersPosY[monstar] = newRect.Y; return true; } } |
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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
public partial class Form1 : Form { async Task<bool> IjikeMonstarMoveDirect(int monstar, Direct direct) { int ijikeMonstarMoveCount = ijikeMonstarMoveCounts[monstar]; if(direct == Direct.North) { MonstersDirect[monstar] = Direct.North; for(int i = 0; i < 4; i++) { MonstersPosY[monstar] -= CELL_HEIGHT / 4 / ijikeMonstarSpeedDownRate; Invalidate(); await Task.Delay(PACMAN_DELAY); } if(ijikeMonstarMoveCount % ijikeMonstarSpeedDownRate == 0) { if(GetStringMazeCell(MonstersCellX[monstar], MonstersCellY[monstar]) == "L") MonstersCellX[monstar] = 20; else MonstersCellY[monstar]--; } } if(direct == Direct.East) { MonstersDirect[monstar] = Direct.East; for(int i = 0; i < 4; i++) { MonstersPosX[monstar] += CELL_WIDTH / 4 / ijikeMonstarSpeedDownRate; Invalidate(); await Task.Delay(PACMAN_DELAY); } if(ijikeMonstarMoveCount % ijikeMonstarSpeedDownRate == 0) { if(GetStringMazeCell(MonstersCellX[monstar], MonstersCellY[monstar]) == "R") MonstersCellX[monstar] = 0; else MonstersCellX[monstar]++; } } if(direct == Direct.South) { MonstersDirect[monstar] = Direct.South; for(int i = 0; i < 4; i++) { MonstersPosY[monstar] += CELL_HEIGHT / 4 / ijikeMonstarSpeedDownRate; Invalidate(); await Task.Delay(PACMAN_DELAY); } if(ijikeMonstarMoveCount % ijikeMonstarSpeedDownRate == 0) MonstersCellY[monstar]++; } if(direct == Direct.West) { MonstersDirect[monstar] = Direct.West; for(int i = 0; i < 4; i++) { MonstersPosX[monstar] -= CELL_WIDTH / 4 / ijikeMonstarSpeedDownRate; Invalidate(); await Task.Delay(PACMAN_DELAY); } if(ijikeMonstarMoveCount % ijikeMonstarSpeedDownRate == 0) MonstersCellX[monstar]--; } // ijikeMonstarMoveCountが偶数のときだけ // CELL_HEIGHTが4で割り切れない場合、ずれが発生するのでその補正のための処理 if(ijikeMonstarMoveCount % ijikeMonstarSpeedDownRate == 0) { Rectangle newRect = GetMazeCell(MonstersCellX[monstar], MonstersCellY[monstar]); MonstersPosX[monstar] = newRect.X; MonstersPosY[monstar] = newRect.Y; } return true; } } |