public bool Overlap(Projection other) { return(this.max >= other.min && other.max >= this.min); }
protected int ShipHasCollided() { int currentCellX = (int)(shipPosition.X / blockSize); int currentCellY = (int)(shipPosition.Y / blockSize); int[,] cellsToTest = { { currentCellX - 1, currentCellY + 1 }, { currentCellX - 1, currentCellY }, { currentCellX + 1, currentCellY - 1 }, { currentCellX, currentCellY - 1 }, { currentCellX - 1, currentCellY - 1 }, { currentCellX, currentCellY }, { currentCellX, currentCellY + 1 }, { currentCellX + 1, currentCellY }, { currentCellX + 1, currentCellY + 1 } }; float shipHalfWidth = textureShip.Width / 2; float shipHalfHeight = textureShip.Height / 2; float yaw = (float)motionManager.DeviceMotion.Attitude.Yaw; Vector2[] shipVertices = { Rotate(new Vector2(shipPosition.X, shipPosition.Y - shipHalfHeight), shipPosition, -yaw), Rotate(new Vector2(shipPosition.X + shipHalfWidth, shipPosition.Y + shipHalfHeight), shipPosition, -yaw), Rotate(new Vector2(shipPosition.X - shipHalfWidth, shipPosition.Y + shipHalfHeight), shipPosition, -yaw) }; Vector2[] shipAxes = { Normal(shipVertices[1] - shipVertices[0]), Normal(shipVertices[2] - shipVertices[1]), Normal(shipVertices[0] - shipVertices[2]) }; for (int i = 0; i < cellsToTest.GetLength(0); i++) { int x = cellsToTest[i, 0]; int y = cellsToTest[i, 1]; if (x >= 24 || y >= 24) { continue; } if (map[y, x] == 1 || map[y, x] == 2) { int cellWorldX = x * blockSize; int cellWorldY = y * blockSize; // SAT Vector2[] blockVertices = { new Vector2(cellWorldX, cellWorldY), new Vector2(cellWorldX + blockSize, cellWorldY), new Vector2(cellWorldX + blockSize, cellWorldY + blockSize), new Vector2(cellWorldX, cellWorldY + blockSize) }; Vector2[] blockAxes = { Normal(blockVertices[1] - blockVertices[0]), Normal(blockVertices[2] - blockVertices[1]) }; bool foundGap = false; for (int j = 0; j < blockAxes.Length; j++) { Vector2 axis = blockAxes[j]; Projection blockProjection = CreateProjection(axis, blockVertices); Projection shipProjection = CreateProjection(axis, shipVertices); if (!blockProjection.Overlap(shipProjection)) { foundGap = true; break; } } if (foundGap) { continue; } for (int j = 0; j < shipAxes.Length; j++) { Vector2 axis = shipAxes[j]; Projection shipProjection = CreateProjection(axis, shipVertices); Projection blockProjection = CreateProjection(axis, blockVertices); if (!shipProjection.Overlap(blockProjection)) { foundGap = true; break; } } if (!foundGap) { return(map[y, x]); } // AABB /* * if (shipPosition.X <= cellWorldX + blockSize && * shipPosition.X + shipSize > cellWorldX && * shipPosition.Y <= cellWorldY + blockSize && * shipPosition.Y + shipSize >= cellWorldY) * { * return true; * } */ } } return(-1); }