public static GridBall Generate(Transform parentTF, bool wasBallShot = false) { GridBall gridBall = PoolManager.I.GetPooler("GridBall").Get <GridBall>(); gridBall.transform.SetParent(parentTF); gridBall.transform.localPosition = Vector3.zero; gridBall.transform.localScale = Vector3.one * 0.7f; gridBall.transform.localRotation = Quaternion.identity; gridBall.DetectParentBallGrid(); float a = 1f; if (!wasBallShot) { if (Random.Range(1, 100) == 50) { a = 0.5f; } } gridBall.SetRandomColor(a); gridBall.neighbors = gridBall.GetNeighbors(); foreach (GridBall gb in gridBall.neighbors) { if (!gb.neighbors.Contains(gridBall)) { gb.neighbors.Add(gridBall); } } return(gridBall); }
public override void OnInspectorGUI() { DrawDefaultInspector(); GridBall gridBall = (GridBall)target; if (GUILayout.Button("Refresh Material")) { EditorCommon.RefreshBallMaterialByColor(gridBall); } }
protected void MergeBalls(GridBall ballToMergeInto) { isInGrid = false; transform.DOMove(ballToMergeInto.transform.position, 0.5f).OnComplete(() => { var newData = GameplayManager.Instance.GameSettings.BallSettings.FindAll(d => d.Value <= score * 2).OrderByDescending(d => d.Value).First(); ballToMergeInto.SetInfo(newData); ballToMergeInto.ProcessMerge(); Destroy(gameObject); }); }
public static GridBall GenerateGridBall(Transform parentTF) { GameObject gridBallPrefab = AssetDatabase.LoadAssetAtPath <GameObject>("Assets/Bubble Shooter VR/Prefabs/GridBall.prefab"); GameObject gridBallGO = (GameObject)PrefabUtility.InstantiatePrefab(gridBallPrefab); GridBall gridBall = gridBallGO.GetComponent <GridBall>(); gridBall.transform.SetParent(parentTF); gridBall.transform.localPosition = Vector3.zero; gridBall.transform.localScale = Vector3.one * 0.7f; gridBall.transform.localRotation = Quaternion.identity; gridBall.ballColor = (BallColor)Random.Range(1, (int)BallColor.LENGTH); EditorCommon.RefreshBallMaterialByColor(gridBall); return(gridBall); }
public void OnTriggerEnter(Collider other) { GridBall parentGridBall = this.transform.parent.GetComponent <GridBall>(); if (parentGridBall != null) { BallShot ballShotThatHitMe = other.GetComponent <BallShot>(); if (ballShotThatHitMe != null) { // only sense flying balls if (ballShotThatHitMe.state == BallShot.State.Flying) { // before processing anything else, snap a new GridBall into place GridBall newGridBall = ballShotThatHitMe.SnapTo(parentGridBall.ballGrid, this); // TODO: everything below this belongs in a different class - maybe use command pattern // then start processing what happens after the ball exists switch (ballShotThatHitMe.ballType) { case BallType.PaintSplash: // turn all touched balls the same color foreach (GridBall neighborBall in newGridBall.neighbors) { neighborBall.ballColor = newGridBall.ballColor; } break; case BallType.Bomb: // TODO: pop all balls in a radius break; default: // basic match-3 popping GameMgr.I.StartCoroutine(this.PopChainLoop(newGridBall)); break; } } } else { Debug.LogWarning("grid ball sensor hit with something other than a ball shot", this); } } else { Debug.LogWarning("orphaned grid ball sensor", this); } }
public List <GridBall> GetNeighbors() { List <Collider> collidersList = new List <Collider>(Physics.OverlapSphere(this.transform.position, testSphereRadius)); List <GridBall> neighbors = new List <GridBall>(); for (int i = collidersList.Count - 1; i >= 0; i--) { GridBall neighborBall = collidersList[i].GetComponent <GridBall>(); if (neighborBall != null) { neighbors.Add(neighborBall); } } return(neighbors); }
public void CheckIfConnectedToWall() { this.isConnectedToWall = false; int loopSafety = 0; List <GridBall> searched = new List <GridBall>() { this }; Stack <GridBall> searchStack = new Stack <GridBall>(); searchStack.Push(this); while (searchStack.Count > 0) { GridBall gb1 = searchStack.Pop(); // gb1.SetColor(BallColor.Default); // for debugging List <Collider> collidersList = new List <Collider>(Physics.OverlapSphere(gb1.transform.position, WALL_TEST_RADIUS)); for (int i = collidersList.Count - 1; i >= 0; i--) { WallCube WallCube = collidersList[i].GetComponent <WallCube>(); if (WallCube != null) { gb1.isConnectedToWall = true; this.isConnectedToWall = true; return; } } foreach (GridBall gb2 in gb1.neighbors) { if (!searched.Contains(gb2)) { searched.Add(gb2); searchStack.Push(gb2); } } loopSafety++; if (loopSafety > 10000) { Debug.LogError("loop safety!"); break; } } }
public IEnumerator GenerateLoop() { this.SetState(State.Generating); this.GenerateWalls(); for (int z = this.zMax; z >= this.zMin; z--) { Transform wallTF = this.GetOrCreateLayer(z); int yBottom = this.yMin; int yTop = this.yMax; for (int y = yBottom; y <= yTop; y++) { Transform rowTF = this.GetOrCreateRow(z, y, wallTF); int xLeft = this.xMin; int xRight = this.xMax; if (Utils.IsOdd(xSize)) { if ((xSize + 1) % 4 == 0) { if ((Utils.IsEven(z) && Utils.IsEven(y)) || (Utils.IsOdd(z) && Utils.IsOdd(y))) { xLeft++; } } else { if ((Utils.IsEven(z) && Utils.IsOdd(y)) || (Utils.IsEven(y) && Utils.IsOdd(z))) { xRight--; } } } for (int x = xLeft; x <= xRight; x++) { Transform colTF = this.GetOrCreateColumn(x, rowTF); GridBall gridBall = GridBall.Generate(colTF); gridBall.gridCoords = new Vector3(x, y, z); } yield return(new WaitForSeconds(ROW_GENERATE_DELAY)); } } this.SetState(State.Default); }
public static void GenerateRandomBallGrid(BallGrid ballGrid) { for (int z = ballGrid.zMax; z >= ballGrid.zMin; z--) { Transform wallTF = ballGrid.GetOrCreateLayer(z); int yBottom = ballGrid.yMin; int yTop = ballGrid.yMax; for (int y = yBottom; y <= yTop; y++) { Transform rowTF = ballGrid.GetOrCreateRow(z, y, wallTF); int xLeft = ballGrid.xMin; int xRight = ballGrid.xMax; if (Utils.IsOdd(ballGrid.xSize)) { if ((ballGrid.xSize + 1) % 4 == 0) { if ((Utils.IsEven(z) && Utils.IsEven(y)) || (Utils.IsOdd(z) && Utils.IsOdd(y))) { xLeft++; } } else { if ((Utils.IsEven(z) && Utils.IsOdd(y)) || (Utils.IsEven(y) && Utils.IsOdd(z))) { xRight--; } } } for (int x = xLeft; x <= xRight; x++) { Transform colTF = ballGrid.GetOrCreateColumn(x, rowTF); GridBall gridBall = BallGridEditor.GenerateGridBall(colTF); gridBall.RefreshGridCoords(); } } } }
public GridBall SnapTo(BallGrid ballGrid, GridBallSensorNode sensorNode) { this._state = State.Snapping; this.StopCoroutine("CountdownToRecycle"); this.ballCollider.enabled = false; this.ballRigidBody.velocity = Vector3.zero; this.ballRigidBody.angularVelocity = Vector3.zero; // instantiate a grid ball in the correct spot and recycle this ball GridBall gridBall = sensorNode.GetComponentInParent <GridBall>(); Vector3i direction = new Vector3i( Mathf.RoundToInt(Utils.RoundAwayFromZero(sensorNode.transform.localPosition.x)), Mathf.RoundToInt(Utils.RoundAwayFromZero(sensorNode.transform.localPosition.y)), Mathf.RoundToInt(Utils.RoundAwayFromZero(sensorNode.transform.localPosition.z)) ); Vector3i newPos = BallGrid.GetNeighborCoords(new Vector3i(gridBall.gridCoords), direction); Transform wallTF = ballGrid.GetOrCreateLayer(Mathf.RoundToInt(newPos.z)); Transform rowTF = ballGrid.GetOrCreateRow(Mathf.RoundToInt(newPos.z), Mathf.RoundToInt(newPos.y), wallTF); Transform colTF = ballGrid.GetOrCreateColumn(Mathf.RoundToInt(newPos.x), rowTF); GridBall newGridBall = colTF.GetComponentInChildren <GridBall>(); if (newGridBall == null) { newGridBall = GridBall.Generate(colTF, wasBallShot: true); newGridBall.RefreshGridCoords(); } else { Debug.LogWarningFormat("grid ball already exists at zyx {0}", newPos.ToString()); } newGridBall.SetColor(this.ballColor); this.Recycle(); return(newGridBall); }
public static void RefreshBallMaterialByColor(GridBall gridBall) { string matPath = "Assets/Bubble Shooter VR/Materials"; switch (gridBall.ballColor) { case BallColor.Red: matPath = string.Format("{0}/Ball Red.mat", matPath); break; case BallColor.Blue: matPath = string.Format("{0}/Ball Blue.mat", matPath); break; case BallColor.Yellow: matPath = string.Format("{0}/Ball Yellow.mat", matPath); break; case BallColor.Green: matPath = string.Format("{0}/Ball Green.mat", matPath); break; case BallColor.Orange: matPath = string.Format("{0}/Ball Orange.mat", matPath); break; case BallColor.Violet: matPath = string.Format("{0}/Ball Violet.mat", matPath); break; default: matPath = string.Format("{0}/Ball Default.mat", matPath); break; } gridBall.modelRenderer.material = AssetDatabase.LoadAssetAtPath <Material>(matPath); }
public void RemoveGridBall(GridBall gridBall) { activeBalls.Remove(gridBall); }
public IEnumerator PopChainLoop(GridBall newGridBall) { // set this before we lose a reference to it when the new grid ball pops BallGrid currentBallGrid = newGridBall.ballGrid; currentBallGrid.SetState(BallGrid.State.Popping); List <GridBall> ballCluster = new List <GridBall>() { newGridBall }; List <GridBall> searched = new List <GridBall>(ballCluster); Queue <GridBall> searchQueue = new Queue <GridBall>(ballCluster); List <GridBall> adjacentBallsThatSurvived = new List <GridBall>(); while (searchQueue.Count > 0) { GridBall curBall = searchQueue.Dequeue(); if (curBall.ballColor == newGridBall.ballColor) { if (!ballCluster.Contains(curBall)) { ballCluster.Add(curBall); } foreach (GridBall gb in curBall.neighbors) { if (!searched.Contains(gb)) { searched.Add(gb); searchQueue.Enqueue(gb); } } } else { if (!adjacentBallsThatSurvived.Contains(curBall)) { adjacentBallsThatSurvived.Add(curBall); } } } if (ballCluster.Count >= 3) { foreach (GridBall gb in ballCluster) { gb.RemoveFromWall(); yield return(new WaitForSeconds(POP_DELAY)); } } int loopSafety = 0; List <GridBall> searched2 = new List <GridBall>(); while (adjacentBallsThatSurvived.Count > 0) { GridBall survivorBall = adjacentBallsThatSurvived[0]; searched2.Add(survivorBall); adjacentBallsThatSurvived.RemoveAt(0); survivorBall.CheckIfConnectedToWall(); if (!survivorBall.isConnectedToWall) { foreach (GridBall gb in survivorBall.neighbors) { if (!searched2.Contains(gb) && !adjacentBallsThatSurvived.Contains(gb)) { adjacentBallsThatSurvived.Add(gb); } } survivorBall.RemoveFromWall(); yield return(new WaitForSeconds(POP_DELAY)); } loopSafety++; if (loopSafety > 10000) { Debug.LogError("loop safety!"); break; } } currentBallGrid.SetState(BallGrid.State.Default); }