For this lesson on how to make 2048 in Unity we will be going over how to create and display a game over screen when there are no more spaces to move and blocks to combine. We will also make it so the players can restart when the receive a game over screen.
Unlock Code and Member Content
GameController2048.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using UnityEngine.UI; using UnityEngine.SceneManagement; public class GameController2048 : MonoBehaviour { public static GameController2048 instance; public static int ticker; [SerializeField] GameObject fillPrefab; [SerializeField] Cell2048[] allCells; public static Action<string> slide; public int myScore; [SerializeField] Text scoreDisplay; int isGameOver; [SerializeField] GameObject gameOverPanel; private void OnEnable() { if(instance == null) { instance = this; } } // Start is called before the first frame update void Start() { StartSpawnFill(); StartSpawnFill(); } // Update is called once per frame void Update() { if(Input.GetKeyDown(KeyCode.Space)) { SpawnFill(); } if(Input.GetKeyDown(KeyCode.W)) { ticker = 0; isGameOver = 0; slide("w"); } if (Input.GetKeyDown(KeyCode.D)) { ticker = 0; isGameOver = 0; slide("d"); } if (Input.GetKeyDown(KeyCode.S)) { ticker = 0; isGameOver = 0; slide("s"); } if (Input.GetKeyDown(KeyCode.A)) { ticker = 0; isGameOver = 0; slide("a"); } } public void SpawnFill() { bool isFull = true; for(int i = 0; i < allCells.Length; i++) { if(allCells[i].fill == null) { isFull = false; } } if(isFull == true) { return; } int whichSpawn = UnityEngine.Random.Range(0, allCells.Length); if(allCells[whichSpawn].transform.childCount != 0) { Debug.Log(allCells[whichSpawn].name + " is already filled"); SpawnFill(); return; } float chance = UnityEngine.Random.Range(0f, 1f); Debug.Log(chance); if(chance <.2f) { return; } else if(chance < .8f) { GameObject tempFill = Instantiate(fillPrefab, allCells[whichSpawn].transform); Debug.Log(2); Fill2048 tempFillComp = tempFill.GetComponent<Fill2048>(); allCells[whichSpawn].GetComponent<Cell2048>().fill = tempFillComp; tempFillComp.FillValueUpdate(2); } else { GameObject tempFill = Instantiate(fillPrefab, allCells[whichSpawn].transform); Debug.Log(4); Fill2048 tempFillComp = tempFill.GetComponent<Fill2048>(); allCells[whichSpawn].GetComponent<Cell2048>().fill = tempFillComp; tempFillComp.FillValueUpdate(4); } } public void StartSpawnFill() { int whichSpawn = UnityEngine.Random.Range(0, allCells.Length); if (allCells[whichSpawn].transform.childCount != 0) { Debug.Log(allCells[whichSpawn].name + " is already filled"); SpawnFill(); return; } GameObject tempFill = Instantiate(fillPrefab, allCells[whichSpawn].transform); Debug.Log(2); Fill2048 tempFillComp = tempFill.GetComponent<Fill2048>(); allCells[whichSpawn].GetComponent<Cell2048>().fill = tempFillComp; tempFillComp.FillValueUpdate(2); } public void ScoreUpdate(int scoreIn) { myScore += scoreIn; scoreDisplay.text = myScore.ToString(); } public void GameOverCheck() { isGameOver++; if(isGameOver >= 16) { gameOverPanel.SetActive(true); } } public void Restart() { SceneManager.LoadScene(0); } }
Cell2048.cs
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class Cell2048 : MonoBehaviour { public Cell2048 right; public Cell2048 down; public Cell2048 left; public Cell2048 up; public Fill2048 fill; private void OnEnable() { GameController2048.slide += OnSlide; } private void OnDisable() { GameController2048.slide -= OnSlide; } private void OnSlide(string whatWasSent) { CellCheck(); Debug.Log(whatWasSent); if(whatWasSent == "w") { if (up != null) return; Cell2048 currentCell = this; SlideUp(currentCell); } if (whatWasSent == "d") { if (right != null) return; Cell2048 currentCell = this; SlideRight(currentCell); } if (whatWasSent == "s") { if (down != null) return; Cell2048 currentCell = this; SlideDown(currentCell); } if (whatWasSent == "a") { if (left != null) return; Cell2048 currentCell = this; SlideLeft(currentCell); } GameController2048.ticker++; if(GameController2048.ticker == 4) { GameController2048.instance.SpawnFill(); } } void SlideUp(Cell2048 currentCell) { if (currentCell.down == null) return; if (currentCell.fill != null) { Cell2048 nextCell = currentCell.down; while (nextCell.down != null && nextCell.fill == null) { Debug.Log("Loop"); nextCell = nextCell.down; } if (nextCell.fill != null) { if (currentCell.fill.value == nextCell.fill.value) { nextCell.fill.Double(); nextCell.fill.transform.parent = currentCell.transform; currentCell.fill = nextCell.fill; nextCell.fill = null; } else if(currentCell.down.fill != nextCell.fill) { Debug.Log("!doubled"); nextCell.fill.transform.parent = currentCell.down.transform; currentCell.down.fill = nextCell.fill; nextCell.fill = null; } } } else { Cell2048 nextCell = currentCell.down; while (nextCell.down != null && nextCell.fill == null) { Debug.Log("here"); nextCell = nextCell.down; } if (nextCell.fill != null) { nextCell.fill.transform.parent = currentCell.transform; currentCell.fill = nextCell.fill; nextCell.fill = null; SlideUp(currentCell); Debug.Log("Slide to Empty"); } } if (currentCell.down == null) return; SlideUp(currentCell.down); } void SlideRight(Cell2048 currentCell) { if (currentCell.left == null) return; if (currentCell.fill != null) { Cell2048 nextCell = currentCell.left; while (nextCell.left != null && nextCell.fill == null) { Debug.Log("Loop"); nextCell = nextCell.left; } if (nextCell.fill != null) { if (currentCell.fill.value == nextCell.fill.value) { nextCell.fill.Double(); nextCell.fill.transform.parent = currentCell.transform; currentCell.fill = nextCell.fill; nextCell.fill = null; } else if (currentCell.left.fill != nextCell.fill) { Debug.Log("!doubled"); nextCell.fill.transform.parent = currentCell.left.transform; currentCell.left.fill = nextCell.fill; nextCell.fill = null; } } } else { Cell2048 nextCell = currentCell.left; while (nextCell.left != null && nextCell.fill == null) { Debug.Log("here"); nextCell = nextCell.left; } if (nextCell.fill != null) { nextCell.fill.transform.parent = currentCell.transform; currentCell.fill = nextCell.fill; nextCell.fill = null; SlideRight(currentCell); Debug.Log("Slide to Empty"); } } if (currentCell.left == null) return; SlideRight(currentCell.left); } void SlideDown(Cell2048 currentCell) { if (currentCell.up == null) return; if (currentCell.fill != null) { Cell2048 nextCell = currentCell.up; while (nextCell.up != null && nextCell.fill == null) { Debug.Log("Loop"); nextCell = nextCell.up; } if (nextCell.fill != null) { if (currentCell.fill.value == nextCell.fill.value) { nextCell.fill.Double(); nextCell.fill.transform.parent = currentCell.transform; currentCell.fill = nextCell.fill; nextCell.fill = null; } else if (currentCell.up.fill != nextCell.fill) { Debug.Log("!doubled"); nextCell.fill.transform.parent = currentCell.up.transform; currentCell.up.fill = nextCell.fill; nextCell.fill = null; } } } else { Cell2048 nextCell = currentCell.up; while (nextCell.up != null && nextCell.fill == null) { Debug.Log("here"); nextCell = nextCell.up; } if (nextCell.fill != null) { nextCell.fill.transform.parent = currentCell.transform; currentCell.fill = nextCell.fill; nextCell.fill = null; SlideDown(currentCell); Debug.Log("Slide to Empty"); } } if (currentCell.up == null) return; SlideDown(currentCell.up); } void SlideLeft(Cell2048 currentCell) { if (currentCell.right == null) return; if (currentCell.fill != null) { Cell2048 nextCell = currentCell.right; while (nextCell.right != null && nextCell.fill == null) { Debug.Log("Loop"); nextCell = nextCell.right; } if (nextCell.fill != null) { if (currentCell.fill.value == nextCell.fill.value) { nextCell.fill.Double(); nextCell.fill.transform.parent = currentCell.transform; currentCell.fill = nextCell.fill; nextCell.fill = null; } else if (currentCell.right.fill != nextCell.fill) { Debug.Log("!doubled"); nextCell.fill.transform.parent = currentCell.right.transform; currentCell.right.fill = nextCell.fill; nextCell.fill = null; } } } else { Cell2048 nextCell = currentCell.right; while (nextCell.right != null && nextCell.fill == null) { Debug.Log("here"); nextCell = nextCell.right; } if (nextCell.fill != null) { nextCell.fill.transform.parent = currentCell.transform; currentCell.fill = nextCell.fill; nextCell.fill = null; SlideLeft(currentCell); Debug.Log("Slide to Empty"); } } if (currentCell.right == null) return; SlideLeft(currentCell.right); } void CellCheck() { if (fill == null) return; if(up != null) { if (up.fill == null) return; if (up.fill.value == fill.value) return; } if (right != null) { if (right.fill == null) return; if (right.fill.value == fill.value) return; } if (down != null) { if (down.fill == null) return; if (down.fill.value == fill.value) return; } if (left != null) { if (left.fill == null) return; if (left.fill.value == fill.value) return; } Debug.Log("Check"); GameController2048.instance.GameOverCheck(); } }
Fill2048.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Fill2048 : MonoBehaviour { public int value; [SerializeField] Text valueDisplay; [SerializeField] float speed; bool hasCombine; public void FillValueUpdate(int valueIn) { value = valueIn; valueDisplay.text = value.ToString(); } private void Update() { if(transform.localPosition != Vector3.zero) { hasCombine = false; transform.localPosition = Vector3.MoveTowards(transform.localPosition, Vector3.zero, speed * Time.deltaTime); } else if(hasCombine == false) { if(transform.parent.GetChild(0) != this.transform) { Destroy(transform.parent.GetChild(0).gameObject); } hasCombine = true; } } public void Double() { value *= 2; GameController2048.instance.ScoreUpdate(value); valueDisplay.text = value.ToString(); } }
using Photon.Chat; using Photon.Pun; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class PhotonChatManager : MonoBehaviour, IChatClientListener { #region Setup [SerializeField] GameObject joinChatButton; ChatClient chatClient; bool isConnected; [SerializeField] string username; public void UsernameOnValueChange(string valueIn) { username = valueIn; } public void ChatConnectOnClick() { isConnected = true; chatClient = new ChatClient(this); //chatClient.ChatRegion = "US"; chatClient.Connect(PhotonNetwork.PhotonServerSettings.AppSettings.AppIdChat, PhotonNetwork.AppVersion, new AuthenticationValues(username)); Debug.Log("Connenting"); } #endregion Setup #region General [SerializeField] GameObject chatPanel; string privateReceiver = ""; string currentChat; [SerializeField] InputField chatField; [SerializeField] Text chatDisplay; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { if (isConnected) { chatClient.Service(); } if (chatField.text != "" && Input.GetKey(KeyCode.Return)) { SubmitPublicChatOnClick(); SubmitPrivateChatOnClick(); } } #endregion General #region PublicChat public void SubmitPublicChatOnClick() { if (privateReceiver == "") { chatClient.PublishMessage("RegionChannel", currentChat); chatField.text = ""; currentChat = ""; } } public void TypeChatOnValueChange(string valueIn) { currentChat = valueIn; } #endregion PublicChat #region PrivateChat public void ReceiverOnValueChange(string valueIn) { privateReceiver = valueIn; } public void SubmitPrivateChatOnClick() { if (privateReceiver != "") { chatClient.SendPrivateMessage(privateReceiver, currentChat); chatField.text = ""; currentChat = ""; } } #endregion PrivateChat #region Callbacks public void DebugReturn(DebugLevel level, string message) { //throw new System.NotImplementedException(); } public void OnChatStateChange(ChatState state) { if(state == ChatState.Uninitialized) { isConnected = false; joinChatButton.SetActive(true); chatPanel.SetActive(false); } } public void OnConnected() { Debug.Log("Connected"); joinChatButton.SetActive(false); chatClient.Subscribe(new string[] { "RegionChannel" }); } public void OnDisconnected() { isConnected = false; joinChatButton.SetActive(true); chatPanel.SetActive(false); } public void OnGetMessages(string channelName, string[] senders, object[] messages) { string msgs = ""; for (int i = 0; i < senders.Length; i++) { msgs = string.Format("{0}: {1}", senders[i], messages[i]); chatDisplay.text += "\n" + msgs; Debug.Log(msgs); } } public void OnPrivateMessage(string sender, object message, string channelName) { string msgs = ""; msgs = string.Format("(Private) {0}: {1}", sender, message); chatDisplay.text += "\n " + msgs; Debug.Log(msgs); } public void OnStatusUpdate(string user, int status, bool gotMessage, object message) { throw new System.NotImplementedException(); } public void OnSubscribed(string[] channels, bool[] results) { chatPanel.SetActive(true); } public void OnUnsubscribed(string[] channels) { throw new System.NotImplementedException(); } public void OnUserSubscribed(string channel, string user) { throw new System.NotImplementedException(); } public void OnUserUnsubscribed(string channel, string user) { throw new System.NotImplementedException(); } #endregion Callbacks }