private Vector2Int GetTileGroupStart(Vector2Int startTile, Vector2Int movementDir) { // Inverse movement direction to check backwards Vector2Int inverseDir = movementDir * -1; // Start from first tile Vector2Int groupStart = startTile; // Loop backwards while (true) { Vector2Int next = groupStart + inverseDir; Tile nextTile = TileOwner.GetTileAtIndex(next); // Stop when you reach an empty tile or border if (nextTile == null || next == startTile) { return(groupStart); } if (nextTile.IsMovableTile() == false) { return(groupStart); } // Otherwise continue looping else { groupStart = next; } } }
private bool IsValidMove(Vector2Int startIndex, Vector2Int movementDirection) { if (TileOwner == null) { return(false); } if (attributeTile != null) { return(attributeTile.MoveValidate()); } Vector2Int currentIndex = Vector2Extensions.Minus1Int; int stepCount = 0; while (currentIndex != startIndex) { currentIndex = currentIndex == Vector2Extensions.Minus1Int ? GetNextTileIndex(startIndex, movementDirection, true) : GetNextTileIndex(currentIndex, movementDirection, true); Tile tileAtIndex = TileOwner.GetTileAtIndex(currentIndex); if (tileAtIndex == null) { stepCount++; continue; } if (tileAtIndex.IsMovableTile()) { stepCount++; } } return(stepCount > 1); }
private bool PlayerStuck(TileOwner owner) { var startColor = game.GameGrid[p1Start.Item1, p1Start.Item2].TileColor; var oponentColor = game.GameGrid[p2Start.Item1, p2Start.Item2].TileColor; if (owner == TileOwner.Player2) { oponentColor = game.GameGrid[p1Start.Item1, p1Start.Item2].TileColor; startColor = game.GameGrid[p2Start.Item1, p2Start.Item2].TileColor; } for (var i = 0; i < game.GameGrid.GridDimension; i++) { for (var j = 0; j < game.GameGrid.GridDimension; j++) { Tile tile = game.GameGrid[i, j]; if ((tile.TileColor != startColor && tile.TileColor != oponentColor) || (tile.Owner == TileOwner.None && HasSameOwnerTileNeighbor(owner, i, j))) { return(false); } } } return(true); }
private IEnumerator WaitForEndOfFrame() { yield return(null); if (previousTileType == tileType) { yield break; } if (TileOwner) { TileOwner.HandleTileChange(); TileOwner.CleanupScene(); TileOwner.CheckForPlayer(); } }
private void SetTileIndex(Vector2Int newTileIndex, bool useEditorCode = false, bool isResetting = false) { TileOwner.UpdateTileIndexLocation(tileIndex, newTileIndex, this, false, isResetting); if (useEditorCode) { Vector3 newLocalPosition = TileOwner.GetTileLocalPosition(newTileIndex); newLocalPosition.y = transform.localPosition.y; transform.localPosition = newLocalPosition; } else { TileOwner.StartCoroutine(UpdatePosition(newTileIndex)); } tileIndex = newTileIndex; UpdateObjectName(); }
private void ResetTile(GridManager manager) { if (manager != TileOwner) { return; } StopAllCoroutines(); TileOwner.ForceTileToSlot(startingTileIndex, this); Vector3 newLocalPosition = TileOwner.GetTileLocalPosition(startingTileIndex); newLocalPosition.y = transform.localPosition.y; transform.localPosition = newLocalPosition; tileIndex = startingTileIndex; UpdateObjectName(); }
public Vector2Int GetNextTileIndex(Vector2Int currentIndex, Vector2Int movementDirection, bool overwriteMovable = false) { Vector2Int newIndex = currentIndex; if (currentIndex.x <= TileOwner.GridSize.x - 1 && currentIndex.x + movementDirection.x > TileOwner.GridSize.x - 1) { newIndex.x = 0; newIndex.y = currentIndex.y; } else if (currentIndex.x >= 0 && currentIndex.x + movementDirection.x < 0) { newIndex.x = TileOwner.GridSize.x - 1; newIndex.y = currentIndex.y; } else if (currentIndex.y <= TileOwner.GridSize.y - 1 && currentIndex.y + movementDirection.y > TileOwner.GridSize.y - 1) { newIndex.x = currentIndex.x; newIndex.y = 0; } else if (currentIndex.y >= 0 && currentIndex.y + movementDirection.y < 0) { newIndex.x = currentIndex.x; newIndex.y = TileOwner.GridSize.y - 1; } else { newIndex += movementDirection; } if (overwriteMovable == true) { return(newIndex); } if (TileOwner.GetTileAtIndex(newIndex) != null) { if (TileOwner.GetTileAtIndex(newIndex).IsMovableTile() == false) { return(GetNextTileIndex(newIndex, movementDirection)); } } return(newIndex); }
public int FloodFill(Tuple <int, int> startingPoint, Color newColor, TileOwner owner) { Stack <Tile> tiles = new Stack <Tile>(); HashSet <int> visitedTiles = new HashSet <int>(); int tilesAcquired = 0; Tile startingTile = this[startingPoint.Item1, startingPoint.Item2]; tiles.Push(startingTile); while (tiles.Count > 0) { Tile tile = tiles.Pop(); visitedTiles.Add(tile.Id); if (tile.Owner == owner || (tile.Owner == TileOwner.None && tile.TileColor == newColor)) { if (tile.Owner == TileOwner.None) { ++tilesAcquired; } tile.Owner = owner; tile.TileColor = newColor; int i = tile.Id / GridDimension; int j = tile.Id % GridDimension; TestAndPush(tiles, i + 1, j, visitedTiles); TestAndPush(tiles, i - 1, j, visitedTiles); TestAndPush(tiles, i, j + 1, visitedTiles); TestAndPush(tiles, i, j - 1, visitedTiles); } } return(tilesAcquired); }
private bool HasSameOwnerTileNeighbor(TileOwner owner, int i, int j) { if (game.GameGrid[i - 1, j] != null && game.GameGrid[i - 1, j].Owner == owner) { return(true); } if (game.GameGrid[i + 1, j] != null && game.GameGrid[i + 1, j].Owner == owner) { return(true); } if (game.GameGrid[i, j + 1] != null && game.GameGrid[i, j + 1].Owner == owner) { return(true); } if (game.GameGrid[i, j - 1] != null && game.GameGrid[i, j - 1].Owner == owner) { return(true); } return(false); }
public void SetTileOwner(Vector2 _pos, TileOwner _owner) { grid[(int)_pos.x, (int)_pos.y].owner = _owner; }
public void MoveTile(Vector3 direction, bool ignoreGroupStart = false) { if (TileOwner.IsGridMoving) { return; } Vector2Int movementDirection; if (direction == Vector3Extensions.Right) { movementDirection = Vector2Extensions.Right; } else if (direction == Vector3Extensions.Left) { movementDirection = Vector2Extensions.Left; } else if (direction == Vector3Extensions.Forward) { movementDirection = Vector2Extensions.Up; } else if (direction == Vector3Extensions.Back) { movementDirection = Vector2Extensions.Down; } else { // Invalid movement direction return; } if (Tile.originalTileMover == Vector2Extensions.Minus1Int) { if (IsValidMove(tileIndex, movementDirection) == false) { return; } if (IsMovableTile() == false) { Vector2Int nextTile = GetNextTileIndex(tileIndex, movementDirection, true); if (TileOwner.GetTileAtIndex(nextTile) != null) { TileOwner.GetTileAtIndex(nextTile).MoveTile(direction); return; } } // Save movement starting position Vector2Int startTile = GetTileGroupStart(tileIndex, movementDirection); if (ignoreGroupStart) { startTile = tileIndex; } // If this is part of bigger chunk if (startTile != tileIndex) { TileOwner.GetTileAtIndex(startTile).MoveTile(direction); return; } Tile.originalTileMover = startTile; Tile.lastMovementDirection = movementDirection; OnTileStartedMoving(startTile, movementDirection); } else { if (Tile.originalTileMover == tileIndex) { // Stop the movement, to prevent looping and reset so we can continue correctly for the next iteration if (!Application.isPlaying) { Tile.originalTileMover = Vector2Extensions.Minus1Int; } return; } } Vector2Int newIndex = GetNextTileIndex(tileIndex, movementDirection); if (TileOwner.GetTileAtIndex(newIndex) != null) { TileOwner.GetTileAtIndex(newIndex).MoveTile(direction); } else { if (!Application.isPlaying) { Tile.originalTileMover = Vector2Extensions.Minus1Int; } } if (IsMovableTile()) { SetTileIndex(newIndex, !Application.isPlaying); } }
private IEnumerator AnimateTileWrap(Vector2Int moveTargetIndex, Vector3 movementStartPosition) { // Calculate needed values Vector3 moveTarget = TileOwner.GetTileLocalPosition(moveTargetIndex); Vector3 diff = moveTarget - TileOwner.GetTileLocalPosition(tileIndex); // Keep in mind the proper grid spacing float offset = (moveTargetIndex - tileIndex).x != 0 ? TileOwner.GridSpacing.x : TileOwner.GridSpacing.y; // Calculate movement direction Vector3 moveDirection = offset * 2.0f * new Vector3(-Mathf.Clamp(diff.x, -1, 1), 0, -Mathf.Clamp(diff.z, -1, 1)); // Create temporary tile for tile fading if (TileOwner.TempTile == null) { TileOwner.InitializeTempTile(); } else if (TileOwner.TempTile.activeSelf == false) { TileOwner.TempTile.SetActive(true); } MeshRenderer tempTileRenderer = TileOwner.TempTile.GetComponent <MeshRenderer>(); tempTileRenderer.enabled = true; tempTileRenderer.sharedMaterials = MeshRenderer.sharedMaterials; TileOwner.TempTile.GetComponent <MeshFilter>().sharedMesh = MeshFilter.sharedMesh; TileOwner.TempTile.transform.parent = transform.parent; TileOwner.TempTile.transform.position = transform.position; TileOwner.TempTile.transform.localScale = transform.localScale; TileOwner.TempTile.transform.rotation = transform.rotation; MaterialPropertyBlock tempPropertyBlock = new MaterialPropertyBlock(); tempTileRenderer.GetPropertyBlock(tempPropertyBlock); for (int i = 0, length = meshRenderer.sharedMaterials.Length; i < length; i++) { PropertyBlock.SetFloat(TileOwner.TileData.fragmentationName, 1.0f); } if (TileOwner.PlayerObject.CurrentTileIndex == moveTargetIndex) { TileOwner.StartCoroutine(TileOwner.PlayerObject.AnimatePlayerWrapping()); } // Setup loop timer float time = 0.0f; float endTime = TileOwner.GridData.TileVerticalMovement[TileOwner.GridData.TileVerticalMovementKeyCount - 1].time; // Loops for fading while (time < endTime) { time += Time.deltaTime; //Resharper might be complaining, but trust me. It can be null if (tempTileRenderer != null) { if (time < TileOwner.GridData.tileWrapFadeOutDuration) { // Fading out effect for (int i = 0, length = tempTileRenderer.sharedMaterials.Length; i < length; i++) { tempPropertyBlock.SetFloat(TileOwner.TileData.fragmentationName, time / TileOwner.GridData.tileWrapFadeOutDuration); for (int j = 0, colorNamesCount = TileOwner.TileData.materialColorNames.Length; j < colorNamesCount; j++) { string materialColorName = TileOwner.TileData.materialColorNames[j]; tempPropertyBlock.SetColor(materialColorName, PropertyBlock.GetColor(materialColorName)); } tempTileRenderer.SetPropertyBlock(tempPropertyBlock); } } else { tempTileRenderer.enabled = false; } } if (time < TileOwner.GridData.tileWrapFadeInDuration) { // Fading in effect for (int i = 0, length = meshRenderer.sharedMaterials.Length; i < length; i++) { PropertyBlock.SetFloat(TileOwner.TileData.fragmentationName, 1.0f - (time / TileOwner.GridData.tileWrapFadeInDuration)); for (int j = 0, colorNamesCount = TileOwner.TileData.materialColorNames.Length; j < colorNamesCount; j++) { string materialColorName = TileOwner.TileData.materialColorNames[j]; tempPropertyBlock.SetColor(materialColorName, PropertyBlock.GetColor(materialColorName)); } meshRenderer.SetPropertyBlock(PropertyBlock); } } else { //meshRenderer.sharedMaterials = originalSharedMaterials; PropertyBlock.SetFloat(TileOwner.TileData.fragmentationName, 0); for (int i = 0; i < TileOwner.TileData.MaterialColorNamesLength; i++) { tempPropertyBlock.SetColor(TileOwner.TileData.materialColorNames[i], PropertyBlock.GetColor(TileOwner.TileData.materialColorNames[i])); } meshRenderer.SetPropertyBlock(PropertyBlock); } // Move tiles (and player if present) if (time < endTime) { if (TileOwner.TempTile != null) { TileOwner.TempTile.transform.localPosition = Vector3.Lerp(movementStartPosition, movementStartPosition + moveDirection, TileOwner.GridData.TileVerticalMovement.Evaluate(time)); } transform.localPosition = Vector3.Lerp(moveTarget - moveDirection, moveTarget, TileOwner.GridData.TileVerticalMovement.Evaluate(time)); } yield return(null); } if (TileOwner.TempTile != null) { TileOwner.TempTile.transform.localPosition = movementStartPosition + moveDirection; } transform.localPosition = moveTarget; // Destroy temporary objects if (TileOwner.TempTile != null) { TileOwner.TempTile.SetActive(false); } // Mark as movement ended moving = false; }
private IEnumerator UpdatePosition(Vector2Int newTileIndex) { moving = true; Vector2Int originalTileIndex = tileIndex; bool willTeleport = WillTeleport(originalTileIndex, lastMovementDirection); TileAudioPlayer.PlayRandomMovementSound(); Vector3 moveTarget = TileOwner.GetTileLocalPosition(newTileIndex.x, newTileIndex.y); Vector3 movementStartPosition = transform.localPosition; float startTime = Time.time; float endTime = Time.time + TileOwner.GridData.TileVerticalMovement[TileOwner.GridData.TileVerticalMovementKeyCount - 1].time; if (willTeleport) { yield return(AnimateTileWrap(newTileIndex, movementStartPosition)); } else { while (Time.time < endTime) { transform.localPosition = Vector3.LerpUnclamped(movementStartPosition, moveTarget, TileOwner.GridData.TileVerticalMovement.Evaluate(Time.time - startTime)); yield return(null); } transform.localPosition = moveTarget; } if (willTeleport == false) { moving = false; } if (originalTileIndex == Tile.originalTileMover) { while (moving) { yield return(null); } if (TileOwner.GetTileAtIndex(TileOwner.PlayerObject.CurrentTileIndex) != null) { OnTileEndedMoving( TileOwner.GetTileAtIndex(TileOwner.PlayerObject.CurrentTileIndex).attribute == Attributes.Reverse ? lastMovementDirection * -1 : lastMovementDirection); Tile.originalTileMover = Vector2Extensions.Minus1Int; } else { OnTileEndedMoving(lastMovementDirection); Tile.originalTileMover = Vector2Extensions.Minus1Int; } // Performance thing, only sync transform changes when we are done moving Physics.SyncTransforms(); } }
public TileDef(TileOwner owner, TileType type) { this.owner = owner; this.type = type; }