示例#1
0
            public static void ClearBalls(BallGrid ballGrid)
            {
                for (int z = ballGrid.zMax; z >= ballGrid.zMin; z--)
                {
                    for (int y = ballGrid.yMin; y <= ballGrid.yMax; y++)
                    {
                        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++)
                        {
                            DestroyImmediate(ballGrid.GetGridBall(new Vector3i(x, y, z)));
                        }
                    }
                }
            }
示例#2
0
 public void Setup()
 {
     UseSubstituteLogging();
     _useSubstitueGameManager = UseSubstitueGameManager();
     _ballFactory             = Substitute.For <IBallFactory>();
     _ballGrid = new BallGrid(_ballFactory, new OrphanedBallFinder(), null);
 }
示例#3
0
            public override void OnInspectorGUI()
            {
                DrawDefaultInspector();

                BallGrid ballGrid = (BallGrid)target;

                if (GUILayout.Button("Generate"))
                {
                    BallGridEditor.GenerateRandomBallGrid(ballGrid);
                }

                if (GUILayout.Button("Clear Balls"))
                {
                    BallGridEditor.ClearBalls(ballGrid);
                }
            }
示例#4
0
文件: Tile.cs 项目: fishtaco567/LD47
    public bool Move(Vector3Int move, BallGrid grid)
    {
        if (grid == null)
        {
            return(false);
        }

        if (move.x + x < grid.gridSize.x && move.y + y < grid.gridSize.y && move.z + z < grid.gridSize.z && move.x + x >= 0 && move.y + y >= 0 && move.z + z >= 0)
        {
            var oldGridPoints = GridPoints();
            x += move.x;
            y += move.y;
            z += move.z;
            var newGridPoints = GridPoints();

            foreach (Vector3Int gridPoint in newGridPoints)
            {
                if (grid.tileGrid[gridPoint.x, gridPoint.y, gridPoint.z] == null || grid.tileGrid[gridPoint.x, gridPoint.y, gridPoint.z] == this)
                {
                }
                else
                {
                    x -= move.x;
                    y -= move.y;
                    z -= move.z;
                    return(false);
                }
            }

            foreach (Vector3Int gridPoint in oldGridPoints)
            {
                grid.tileGrid[gridPoint.x, gridPoint.y, gridPoint.z] = null;
            }

            foreach (Vector3Int gridPoint in newGridPoints)
            {
                grid.tileGrid[gridPoint.x, gridPoint.y, gridPoint.z] = this;
            }

            OnValidate();

            return(true);
        }
        return(false);
    }
示例#5
0
            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();
                        }
                    }
                }
            }
示例#6
0
            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);
            }
示例#7
0
            public static void GenerateWalls(BallGrid ballGrid)
            {
                Transform extentsTF = ballGrid.transform.FindChild("Extents");

                // shift the walls over slightly for any even sized rows (because the grid ends up offset)
                float zShift = ballGrid.zMax + ballGrid.zMin;
                float yShift = ballGrid.yMax + ballGrid.yMin;
                float xShift = ballGrid.xMax + ballGrid.xMin;

                if (ballGrid.xSize % 2 == 0 && xShift == 0)
                {
                    xShift = 1f;
                }
                if ((ballGrid.xSize + 1) % 4 == 0)
                {
                    xShift++;
                }
                extentsTF.transform.localPosition =
                    new Vector3(
                        xShift * (BallGrid.GRID_SPACING_X / 2f),
                        yShift * (BallGrid.GRID_SPACING_Y / 2f),
                        zShift * (BallGrid.GRID_SPACING_Z / 2f)
                        );

                float zPadding = (ballGrid.zSize / 2f * BallGrid.GRID_SPACING_Z) + 0.68f;
                float yPadding = (ballGrid.ySize / 2f * BallGrid.GRID_SPACING_Y) + 0.63f;
                float xPadding = (ballGrid.xSize / 2f * BallGrid.GRID_SPACING_X) + 0.63f;

                float zWallDim = (ballGrid.zSize + 1f) / 2f;
                float yWallDim = (ballGrid.ySize + 1f) / 2f;
                float xWallDim = (ballGrid.xSize + 1f) / 2f;

                Transform zMinExtentTF = extentsTF.FindChild("z min");

                if (ballGrid.zMinWall)
                {
                    zMinExtentTF.transform.localPosition = Vector3.back * zPadding;
                    WallCube wallCube = BallGridEditor.GenerateWallCube(zMinExtentTF, Vector3.zero);
                    wallCube.transform.localScale = new Vector3(xWallDim, yWallDim, 1f);
                }

                Transform zMaxExtentTF = extentsTF.FindChild("z max");

                if (ballGrid.zMaxWall)
                {
                    zMaxExtentTF.transform.localPosition = Vector3.forward * zPadding;
                    WallCube wallCube = BallGridEditor.GenerateWallCube(zMaxExtentTF, Vector3.zero);
                    wallCube.transform.localScale = new Vector3(xWallDim, yWallDim, 1f);
                }

                Transform yMinExtentTF = extentsTF.FindChild("y min");

                if (ballGrid.yMinWall)
                {
                    yMinExtentTF.transform.localPosition = Vector3.down * yPadding;
                    WallCube wallCube = BallGridEditor.GenerateWallCube(yMinExtentTF, Vector3.zero);
                    wallCube.transform.localScale = new Vector3(xWallDim, 1f, zWallDim);
                }

                Transform yMaxExtentTF = extentsTF.FindChild("y max");

                if (ballGrid.yMaxWall)
                {
                    yMaxExtentTF.transform.localPosition = Vector3.up * yPadding;
                    WallCube wallCube = BallGridEditor.GenerateWallCube(yMaxExtentTF, Vector3.zero);
                    wallCube.transform.localScale = new Vector3(xWallDim, 1f, zWallDim);
                }

                Transform xMinExtentTF = extentsTF.FindChild("x min");

                if (ballGrid.xMinWall)
                {
                    xMinExtentTF.transform.localPosition = Vector3.left * xPadding;
                    WallCube wallCube = BallGridEditor.GenerateWallCube(xMinExtentTF, Vector3.zero);
                    wallCube.transform.localScale = new Vector3(1f, yWallDim, zWallDim);
                }

                Transform xMaxExtentTF = extentsTF.FindChild("x max");

                if (ballGrid.xMaxWall)
                {
                    xMaxExtentTF.transform.localPosition = Vector3.right * xPadding;
                    WallCube wallCube = BallGridEditor.GenerateWallCube(xMaxExtentTF, Vector3.zero);
                    wallCube.transform.localScale = new Vector3(1f, yWallDim, zWallDim);
                }
            }
            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);
            }