前回、OpenTKで迷路をつくりました。
壁がある場合、それ以上前に進めないのが普通なのですが、前回のプログラムでは壁を通り抜けて移動することができました。今回は移動しようとしている方向に壁がある場合は移動できないようにします。移動できないことを知らせるために音も鳴らします。
移動するときに本当に移動できるか確認して、移動できる場合だけ移動します。自作メソッド IsInsideOfWalls(double x, double z)は移動先が壁または壁に極めて近い位置であるかどうかを調べるためのメソッドです。壁の内部、または周囲0.1であればtrueを返します。
縦向き、横向きの壁の位置をすべて取得して、それと移動先の座標を比較して結果を返しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
public partial class Form1 : Form { bool IsInsideOfWalls(double x, double z) { List<WallPosition> wallPositionsToEast = GetWallPositionsToEast(); List<WallPosition> wallPositionsToSouth = GetWallPositionsToSouth(); foreach(WallPosition pos in wallPositionsToEast) { if(x > pos.X - 0.1 && x < pos.X + 1.1 && z > pos.Z - 0.15 && z < pos.Z + 0.15) return true; } foreach(WallPosition pos in wallPositionsToSouth) { if(x > pos.X - 0.15 && x < pos.X + 0.15 && z > pos.Z - 0.1 && z < pos.Z + 1.1) return true; } return false; } } |
あとは移動するときにIsInsideOfWallsメソッドを呼び出し、これがfalseを返すときだけ移動の処理を行ないます。移動できないときは音を鳴らします。
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 |
public partial class Form1 : Form { void OnGo() { // 移動先の座標を調べる double newX = EyeX + 0.1f * CosFromInt((int)EyeAngle); double newZ = EyeZ - 0.1f * SinFromInt((int)EyeAngle); if(!IsInsideOfWalls(newX, newZ)) { EyeX = (float)newX; EyeZ = (float)newZ; ShowLabel(); glControl.Refresh(); } else { // 移動できないときは音を鳴らす Console.Beep(500, 200); } } void OnBack() { // 移動先の座標を調べる double newX = EyeX - 0.1f * CosFromInt((int)EyeAngle); double newZ = EyeZ + 0.1f * SinFromInt((int)EyeAngle); if(!IsInsideOfWalls(newX, newZ)) { EyeX = (float)newX; EyeZ = (float)newZ; ShowLabel(); glControl.Refresh(); } else { // 移動できないときは音を鳴らす Console.Beep(500, 200); } } } |