public void Initialize(CrossingData data) { GameManager.Instance.Crossings.Add(this); transform.position = data.Position; HorArrow.transform.eulerAngles = new Vector3( HorArrow.transform.eulerAngles.x, HorArrow.transform.eulerAngles.y, data.Row.Angle); VertArrow.transform.eulerAngles = new Vector3( VertArrow.transform.eulerAngles.x, VertArrow.transform.eulerAngles.y, data.Column.Angle); BackgroundImage.sprite = UpSprite; if (data.Column.Index < _shortcuts.GetLength(0) && data.Row.Index < _shortcuts.GetLength(1)) { Shortcut = _shortcuts[data.Row.Index, data.Column.Index]; ShortcutText.text = Shortcut.ToString(); } transform.DOScale(0, 0.5f) .From() .SetDelay(Random.Range(0.2f, 0.4f)) .SetEase(Ease.OutCubic); Observable.EveryUpdate() .Where(_ => !IsDown && !AllowingVertical && Input.GetKeyDown(Shortcut)) .Subscribe(_ => AllowVertical()) .AddTo(this); Observable.EveryUpdate() .Where(_ => !IsDown && AllowingVertical && Input.GetKeyUp(Shortcut)) .Subscribe(_ => DisallowVertical()) .AddTo(this); DisallowVertical(); }
public static TrafficData Generate(LevelData data) { // min 1x1, max 2x2 var rect = FindObjectOfType <Bounds>().Rect; var cols = data.Cols; var rows = data.Rows; var colParts = (cols + 1) * 4; var rowParts = (rows + 1) * 4; var colSegments = new RoadData[cols]; var rowSegments = new RoadData[rows]; #region Roads + Crossings for (var i = 0; i < cols; ++i) { var startSkew = Random.Range(-1, 2) / (float)colParts; var endSkew = Random.Range(-1, 2) / (float)colParts; var startLerp = (i + 1) / (float)(cols + 1) + startSkew; //var endLerp = startLerp - startSkew + endSkew; var endLerp = startLerp - (2 * startSkew); colSegments[i] = new RoadData(i, new Vector2(Mathf.Lerp(rect.xMin, rect.xMax, startLerp), rect.yMax), new Vector2(Mathf.Lerp(rect.xMin, rect.xMax, endLerp), rect.yMin), true); } for (var i = 0; i < rows; ++i) { var startSkew = Random.Range(-1, 2) / (float)rowParts; var endSkew = Random.Range(-1, 2) / (float)rowParts; var startLerp = (i + 1) / (float)(rows + 1) + startSkew; //var endLerp = startLerp - startSkew + endSkew; var endLerp = startLerp - (2 * startSkew); rowSegments[i] = new RoadData(i, new Vector2(rect.xMin, Mathf.Lerp(rect.yMax, rect.yMin, startLerp)), new Vector2(rect.xMax, Mathf.Lerp(rect.yMax, rect.yMin, endLerp)), false); } var crossings = new CrossingData[cols * rows]; var crossingIndex = 0; for (var i = 0; i < rows; ++i) { for (var j = 0; j < cols; ++j) { var col = colSegments[j]; var row = rowSegments[i]; crossings[crossingIndex++] = new CrossingData { Column = col, Row = row, Position = Intersect(col, row) }; } } #endregion var pathGrid = new Vector2[2 * cols + 3, 2 * rows + 3]; #region Path Grid // corners pathGrid[0, 0] = new Vector2(Bounds.Rect.xMin, Bounds.Rect.yMax); pathGrid[pathGrid.GetLength(0) - 1, 0] = new Vector2(Bounds.Rect.xMax, Bounds.Rect.yMax); pathGrid[0, pathGrid.GetLength(1) - 1] = new Vector2(Bounds.Rect.xMin, Bounds.Rect.yMin); pathGrid[pathGrid.GetLength(0) - 1, pathGrid.GetLength(1) - 1] = new Vector2(Bounds.Rect.xMax, Bounds.Rect.yMin); // road start and end for (var i = 0; i < pathGrid.GetLength(1); i += 2) { for (var j = 0; j < pathGrid.GetLength(0); j += 2) { // filter corners if ((i == 0 || i == pathGrid.GetLength(1) - 1) && (j == 0 || j == pathGrid.GetLength(0) - 1)) { continue; } // filter crossings if (i > 0 && i < pathGrid.GetLength(1) - 1 && j > 0 && j < pathGrid.GetLength(0) - 1) { continue; } if (i == 0) { pathGrid[j, i] = colSegments[(j - 2) / 2].Start; } else if (i == pathGrid.GetLength(1) - 1) { pathGrid[j, i] = colSegments[(j - 2) / 2].End; } else if (j == 0) { pathGrid[j, i] = rowSegments[(i - 2) / 2].Start; } else if (j == pathGrid.GetLength(0) - 1) { pathGrid[j, i] = rowSegments[(i - 2) / 2].End; } } } // crossings crossingIndex = 0; for (var i = 2; i < pathGrid.GetLength(1) - 2; i += 2) { for (var j = 2; j < pathGrid.GetLength(0) - 2; j += 2) { pathGrid[j, i] = crossings[crossingIndex++].Position; } } // vertical inbetweens for (var i = 1; i < pathGrid.GetLength(1); i += 2) { for (var j = 0; j < pathGrid.GetLength(0); j += 2) { pathGrid[j, i] = (pathGrid[j, i - 1] + pathGrid[j, i + 1]) / 2; } } // horizontal inbetweens for (var i = 0; i < pathGrid.GetLength(1); i += 2) { for (var j = 1; j < pathGrid.GetLength(0); j += 2) { pathGrid[j, i] = (pathGrid[j - 1, i] + pathGrid[j + 1, i]) / 2; } } // diagonal inbetweens for (var i = 1; i < pathGrid.GetLength(1); i += 2) { for (var j = 1; j < pathGrid.GetLength(0); j += 2) { pathGrid[j, i] = (pathGrid[j - 1, i] + pathGrid[j + 1, i] + pathGrid[j, i - 1] + pathGrid[j, i + 1]) / 4; } } #endregion #region Path //var turns = 1; var turns = Mathf.Min(rows + 1, data.Turns); var downs = 2 + rows; var path = new Vector2[3 + rows + turns]; int pathCol; var pathRow = 0; do { pathCol = Random.Range(0, pathGrid.GetLength(0)); } while (pathCol % 2 == 0 && pathCol > 0 && pathCol < pathGrid.GetLength(0)); path[0] = pathGrid[pathCol, pathRow++]; pathCol = Mathf.Clamp(pathCol, 1, pathGrid.GetLength(0) - 1); path[1] = pathGrid[pathCol, pathRow]; --downs; var turned = false; for (var i = 2; i < path.Length - 1; ++i) { if (!turned && Random.value < turns / Mathf.Max(1f, (float)downs)) { goto turn; } else { goto down; } turn: var dir = (pathGrid.GetLength(0) / 2 - pathCol) > 0 ? 2 : -2; pathCol += dir; pathCol = Mathf.Clamp(pathCol, 1, pathGrid.GetLength(0) - 1); --turns; turned = true; goto next; down: pathRow += 2; --downs; turned = false; goto next; next: path[i] = pathGrid[pathCol, pathRow]; } ++pathRow; path[path.Length - 1] = pathGrid[pathCol, pathRow]; #endregion #region Waves var waves = new List <WaveData.Entry>(); for (var i = 0; i < 100; ++i) { var wave = new WaveData.Entry(); wave.Amount = data.WaveAmtStart + (data.WaveAmtGrowth * i); wave.Delay = data.WaveDelay; wave.Frequency = data.WaveFreqStart + (data.WaveFreqGrowth * i); wave.Speed = data.WaveSpeedStart + (data.WaveSpeedGrowth * i); waves.Add(wave); } #endregion return(new TrafficData { Columns = colSegments, Rows = rowSegments, Crossings = crossings, Path = new PathData { PointGrid = pathGrid, Points = path, }, WaveData = new WaveData { Waves = waves } }); }