public static Collision ClampVelocity2D(RectInt body, RectInt otherBody, Vector2Int velocity, out Vector2Int clampedVelocity) { Collision collision = new Collision(); // horizontal detection, raycast stepping Vector2Int outputVelocity = Vector2Int.Zero; int signX = (velocity.X >= 0)? 1 : -1; for (int x = 1; x <= signX * velocity.X; x++) { int step = x * signX; var stepPos = body.Position + new Vector2Int(step, 0); var stepBB = new RectInt(stepPos, body.Size); // has collision on side if (stepBB.Overlap(otherBody)) { if (signX > 0) { collision.Right = true; } else if (signX < 0) { collision.Left = true; } break; } outputVelocity.X = step; } // vertical detection, raycast stepping int signY = (velocity.Y >= 0) ? 1 : -1; for (int y = 1; y <= signY * velocity.Y; y++) { int step = y * signY; var stepPos = body.Position + new Vector2Int(outputVelocity.X, step); var stepBB = new RectInt(stepPos, body.Size); // has collision on side if (stepBB.Overlap(otherBody)) { if (signY == 1) { collision.Bottom = true; } else if (signY == -1) { collision.Top = true; } break; } outputVelocity.Y = step; } clampedVelocity = outputVelocity; return(collision); }
public bool Init(int tilesX, int tilesY, int roomsNumber, int minRoomSize, int maxRoomSize) { // Create Tile Path grid _gridW = tilesX; _gridH = tilesY; level = new AStarTile[GridW, GridH]; for (int x = 0; x < GridW; x++) { for (int y = 0; y < GridH; y++) { level[x, y] = new AStarTile(new Vector2Int(x, y)); } } //DrawRect(new RectInt(0, 0, 5, 5), LevelTileType.Wall); /* List<RectInt> roomRects = new List<RectInt>(); * * while (roomRects.Count < roomsNumber) * { * RectInt roomRect = MakeRoomRect(minRoomSize, maxRoomSize); * * bool overlap = false; * * for (int compareRoom = 0; compareRoom < roomRects.Count; compareRoom++) * { * if (roomRect.Overlap(roomRects[compareRoom])) * { * overlap = true; * } * } * * if (!overlap) * { * roomRects.Add(roomRect); * } * } * * foreach (RectInt rect in roomRects) * { * DrawRect(rect, LevelTileType.Floor); * } * * Vector2Int rPos = RandomRectPosition(roomRects[0]); * * // level[rPos.x, rPos.y].type = LevelTileType.Door; * foreach (RectInt roomRect in roomRects) * { * int randomRoomIndex = Random.Range(0, roomRects.Count); * * Vector2Int doorPos1 = RandomRectPosition(roomRect); * Vector2Int doorPos2 = RandomRectPosition(roomRects[randomRoomIndex]); * * * * bool succeeded = CalculateAStar(doorPos1, doorPos2); * * if (succeeded) * { * DrawPathLine(level[doorPos2.x, doorPos2.y]); * } * * level[doorPos1.x, doorPos1.y].type = LevelTileType.Door; * level[doorPos2.x, doorPos2.y].type = LevelTileType.Door; * * } */ Random.InitState(5); // Create rooms List <RectInt> roomRects = new List <RectInt>(); int tries = 50; while (tries > 0 && roomRects.Count < roomsNumber) { RectInt roomRect = MakeRoomRect(minRoomSize, maxRoomSize); bool overlap = false; for (int compareRoom = 0; compareRoom < roomRects.Count; compareRoom++) { if (roomRect.Overlap(roomRects[compareRoom].Increase(1))) { overlap = true; } } if (!overlap) { roomRects.Add(roomRect); } } if (roomRects.Count == 0) { return(false); // No rooms generated. } // Write rooms to grid. foreach (RectInt rect in roomRects) { DrawRect(rect, LevelTileType.Wall); DrawRect(new RectInt(rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2), LevelTileType.Floor); } // Create paths. for (int r = 0; r < roomRects.Count; r++) { int rNext = r + 1; if (rNext >= roomRects.Count) { rNext = 0; } RectInt curRect = roomRects[r]; RectInt nextRect = roomRects[rNext]; // Vector2Int startPos = RandomRectPosition(curRect); // Vector2Int endPos = FindNearestPointOnRect(startPos, nextRect); Vector2Int startPos, endPos; FindNearestPoints(curRect, nextRect, out startPos, out endPos); if (IsValidTile(startPos) && IsValidTile(endPos)) { if (CalculateAStar(startPos, endPos)) { DrawPathLine(level[endPos.x, endPos.y]); // Draw doors. Vector2Int startDoorPos = FindDoorPos(curRect, startPos); Vector2Int endDoorPos = FindDoorPos(nextRect, endPos); level[startDoorPos.x, startDoorPos.y].type = LevelTileType.Door; level[endDoorPos.x, endDoorPos.y].type = LevelTileType.Door; } } } return(true); }