using System.Collections; using System.Collections.Generic; using UnityEngine; using BoardState = System.Collections.Generic.List>; using TileList = System.Collections.Generic.List; using UnityEngine.UI; using TMPro; public class GameBoardRender : MonoBehaviour { // Auto assign so that I can copy stuff around like a shmuk - Texel private GameBoard board; public TMPro.TextMeshPro ScoreText; public TMPro.TextMeshPro ComboText; public TextMeshPro NickNameText; [Header("Positioning")] public Transform basePoint; public float width, height; [Header("Extra")] public TileRender place1; public TileRender place2; public TileRender place3, place4; // Next tile display public GameObject Happy, Sad, Idle; private float soonestChangeTime = 0f; public void SetAnimation() { bool enableHappy = false, enableSad = false, enableIdle = false; if (Time.time < soonestChangeTime) return; switch(board.desiredAnimation) { case GameBoard.AnimationName.Happy: soonestChangeTime = Time.time + 3f; enableHappy = true; break; case GameBoard.AnimationName.Sad: soonestChangeTime = Time.time + 2f; enableSad = true; break; case GameBoard.AnimationName.Idle: enableIdle = true; break; } if (Happy) Happy.SetActive(enableHappy); if (Sad) Sad.SetActive(enableSad); if (Idle) Idle.SetActive(enableIdle); } // Dramatically slow falls in combo mode public float tileSpeed => board.Combo > 0 ? 15 : 20; GameObject tilePrefab => GameBoardInstance.instance.tilePrefab; void Start() { // Auto-assign off same object - Texel board = GetComponent(); } float comboTime = 0f; float comboDuration = 3f; public void SetComboLevel(int num) { if (!ComboText) return; if (num == 0) return; comboTime = Time.time; if (num == 1) ComboText.text = "NICE"; else ComboText.text = string.Format("{0}x COMBO", num); } public void SetScoreValue(int value) { if (ScoreText) ScoreText.text = string.Format("{0:D6}", value); } Transform corner; private void Awake() { var pos = basePoint.position; var rowOffset = basePoint.right * width; var columnOffset = basePoint.up * height; pos += rowOffset * 0.5f + columnOffset * 0.5f; for (var i = 0; i < GameBoard.COLUMN; ++i) { var t = new GameObject("column" + i.ToString()).transform; t.SetParent(basePoint); t.position = pos + rowOffset * i; t.localRotation = Quaternion.identity; t.localScale = Vector3.one; } corner = new GameObject("corner").transform; corner.SetParent(basePoint.GetChild(0)); corner.localPosition = Vector3.zero; corner.localRotation = Quaternion.identity; corner.localScale = Vector3.one; corner.SetParent(transform, true); place1 = Instantiate(GameBoardInstance.instance.tilePrefab, corner).GetComponent(); place2 = Instantiate(GameBoardInstance.instance.tilePrefab, corner).GetComponent(); place3 = Instantiate(GameBoardInstance.instance.tilePrefab, corner).GetComponent(); place4 = Instantiate(GameBoardInstance.instance.tilePrefab, corner).GetComponent(); place1.transform.localPosition = Vector3.zero; place2.transform.localPosition = Vector3.zero; place3.transform.localPosition = Vector3.zero; place4.transform.localPosition = Vector3.zero; } public void Render(BoardState state) { if (Time.time + comboDuration > comboTime) { if (ComboText) ComboText.text = ""; } // render for (var i = 0; i < state.Count; ++i) { var root = basePoint.GetChild(i); var t = state[i]; DrawStack(root, t); } } public void RebuildStack(BoardState state){ for (var i = 0; i < state.Count; ++i) { var root = basePoint.GetChild(i); var t = state[i]; RebuildStack(root, t); } } public void RenderName(){ if (NetworkManager.inRoom && board.authorityID != -1){ var player = NetworkManager.net.CurrentRoom.GetPlayer(board.authorityID); NickNameText.text = player.NickName; } } // Spawn a fading 'ghost' of a tile as an activator for the cool effect public void Ghost(TileInfo tile, (int x, int y) ghostPos) { //var tileGo = Instantiate(tilePrefab,corner); var tileGo = Instantiate(tilePrefab, corner); var tr = tileGo.GetComponent(); tr.renderer.sortingOrder = 3; // Draw infront of the others! tileGo.transform.localPosition = new Vector3(ghostPos.x * width, ghostPos.y * height); //Debug.Log("Ghosting", tr.gameObject); //Debug.Break(); StartCoroutine(HandleGhost(tr,tile.color)); } public void Crumble(TileInfo tile, (int x, int y) crumblePos) { // Copypastecopypastecopypast - Texel var tileGo = Instantiate(tilePrefab, corner); var tr = tileGo.GetComponent(); tr.renderer.sortingOrder = 3; // Draw infront of the others! tileGo.transform.localPosition = new Vector3(crumblePos.x * width, crumblePos.y * height); StartCoroutine(HandleCrumble(tr, tile.color, tile.kind)); } // Float up and fade out IEnumerator HandleGhost(TileRender tr, TileColor color) { float opacity = 1f; while (opacity > 0f) { opacity -= Time.deltaTime; // Move up about one unit over a second? tr.transform.localPosition += new Vector3(0, Time.deltaTime, 0); tr.SetDisplay(color, TileKind.Activator); tr.renderer.color = new Color(1, 1, 1, opacity); yield return null; } Destroy(tr.gameObject); } // Fall down and fade out IEnumerator HandleCrumble(TileRender tr, TileColor color, TileKind kind) { float opacity = 2f; float sideVel = Random.value - 0.5f; float fallSpeed = 0.9f + (Random.value * 0.3f); while (opacity > 0f) { opacity -= Time.deltaTime; tr.transform.localPosition += new Vector3(sideVel * Time.deltaTime, fallSpeed * -Time.deltaTime, 0); tr.SetDisplay(color, kind); tr.renderer.color = new Color(1, 1, 1, opacity); yield return null; } Destroy(tr.gameObject); } public void RenderPlacement(TileInfo left, TileInfo right, (int x, int y) leftPosition, (int x, int y) rightPosition){ place1.transform.localPosition = new Vector3(leftPosition.x * width, leftPosition.y * height); place2.transform.localPosition = new Vector3(rightPosition.x * width, rightPosition.y * height); place3.transform.localPosition = new Vector3(board.nextRootX * width, board.nextRootY * height); place4.transform.localPosition = new Vector3(board.nextRootX * width, (board.nextRootY - 1f) * height); var np = board.nextPair; place3.SetDisplay(np.left.color, np.left.kind); place4.SetDisplay(np.right.color, np.right.kind); place1.SetDisplay(left, left.color, left.kind); place2.SetDisplay(right, right.color, right.kind); } void RebuildStack(Transform root, TileList tiles){ var spawnOffset = 0f; var maxHeight = height * (GameBoard.ROW + 1); for(var i = 0; i < tiles.Count; ++i){ var tile = tiles[i]; var tilestate = tile.kind; var tileinstance = 0; var ttransform = i < root.childCount ? root.GetChild(i) : null; var trender = ttransform != null ? ttransform.GetComponent() : null; // new tiles, place them at the top if (ttransform == null){ var t = Instantiate(tilePrefab, root).transform; t.localPosition = new Vector3(0f, Mathf.Max(maxHeight, spawnOffset)); t.localRotation = Quaternion.identity; t.localScale = Vector3.one; t.GetComponent().id = tileinstance; spawnOffset = t.localPosition.y + height; } // not in sync, stop destroying else if (tileinstance != trender.id){ ttransform.parent = null; Destroy(ttransform.gameObject); i--; } // in sync, continue else { spawnOffset = ttransform.localPosition.y + height; } } // any excess tiles are removed while(tiles.Count < root.childCount){ var child = root.GetChild(root.childCount - 1); child.parent = null; Destroy(child.gameObject); } } private static Dictionary colorConversion = new Dictionary(){ { TileColor.Blue, Color.blue }, { TileColor.Green, Color.green }, { TileColor.Red, Color.red }, { TileColor.Yellow, Color.yellow} }; void DrawStack(Transform root, TileList tiles){ var dest = 0f; var speed = Time.deltaTime * tileSpeed; for(var i = 0; i < tiles.Count; ++i){ var tile = tiles[i]; var tilekind = tile.kind; var tilecolor = tile.color; var ttransform = root.GetChild(i); var trender = ttransform.GetComponent(); if (tilekind != TileKind.Air){ // pos var pos = ttransform.localPosition.y; ttransform.localPosition = new Vector3(0f, Mathf.MoveTowards(pos, dest, speed)); dest += height; // color ttransform.gameObject.SetActive(true); trender.SetDisplay(tile, tilecolor, tilekind); // counter trender.SetCounter(tilekind == TileKind.Trash ? tile.counter.ToString() : ""); } else { ttransform.gameObject.SetActive(false); } } } }