Unity 消消乐教程和源码
本文提供全流程,中文翻译。 Chinar坚持将简单的生活方式,带给世人! (拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) |
1
Start Game —— 游戏逻辑稍复杂,先贴代码,抽空慢慢讲
有耐心的朋友可以跳转到SiKi学院,观看视频:SiKi学院
SiKi学院——是本人发现的网络教程做的很完善的网络课堂,推荐大家多学,多看
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
/// <summary>
/// 开始游戏脚本
/// </summary>
public class StartGame : MonoBehaviour {
/// <summary>
/// 加载游戏
/// </summary>
public void LoadTheGame()
{
SceneManager.LoadScene(1);
}
/// <summary>
/// 退出游戏
/// </summary>
public void ExitGame()
{
Application.Quit();
}
/// <summary>
/// 初始化函数
/// </summary>
void Start()
{
Button button = GameObject.Find("Exit_Button").GetComponent<Button>();
button.onClick.AddListener(ExitGame);
button = GameObject.Find("Start_Button").GetComponent<Button>();
button.onClick.AddListener(LoadTheGame);
}
}
2
GameManager —— 游戏总控类脚本
控制游戏所有逻辑的实现
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
/// <summary>
/// 游戏控制脚本
/// </summary>
public class GameManager : MonoBehaviour
{
private static GameManager _instance; //单例
public static GameManager Instance
{
get { return _instance; }
set { _instance = value; }
}
private void Awake()
{
_instance = this;
}
//大网格的行列数
public int xLie;
public int yHang;
public float fillTime; //填充时间
public GameObject gridPrefab; //背景块
//消消乐物品的种类
public enum SweetsType
{
EMPTY, //空物体
NORMAL, //普通
BARRIER, //障碍物
HANG_CLEAR, //行消除
LIE_CLEAR, //列消除
RAINBOWCANDY, //彩虹糖
COUNT //标记类型
}
//物品的预制体的字典 —— 可以通过物品的种类,来得到相对应的物体
private Dictionary<SweetsType, GameObject> sweetPrefabDict;
//由于字典不会直接在 Inspector面板上显示,所以需要用结构体(因为结构体,经过序列化,可以显示)
[System.Serializable] //加上可序列化特性
public struct SweetPrefab
{
public SweetsType type;
public GameObject prefabs;
}
public SweetPrefab[] sweetPrefabs; //结构体数组
private GameSweet[ , ] sweets; //物品的数组,二维数组,中间必须加逗号
private GameSweet pressedSweet; //按下的物品
private GameSweet enterSweet; //松开的物品
private Text TimeText; //倒计时文本框
private float TimeCountDown = 60; //倒计时,时间
private bool IsGameOver; //是否结束游戏
[HideInInspector] public int PlayerScore; //分数
private Text PlayerScoreText; //玩家分数文本框
private float AddScoreTime; //累加时间
private float CurrentScore; //当前分数
public GameObject GameOverPanel; //结束游戏界面
private Text FinalScoreText; //最终得分
/// <summary>
/// 初始化函数
/// </summary>
void Start()
{
TimeText = GameObject.Find("Time_Text").GetComponent<Text>(); //获取文本框
PlayerScoreText = GameObject.Find("Score_Internal_Text").GetComponent<Text>();
Button button = GameObject.Find("ReTurn_Button").GetComponent<Button>(); //添加重玩按钮方法
button.onClick.AddListener(RePlay);
//实例化字典
sweetPrefabDict = new Dictionary<SweetsType, GameObject>();
for (int i = 0; i < sweetPrefabs.Length; i++) //遍历结构体数组
{
if (!sweetPrefabDict.ContainsKey(sweetPrefabs[i].type)) //如果字典里,不包含结构体里 对应的类型
{
sweetPrefabDict.Add(sweetPrefabs[i].type, sweetPrefabs[i].prefabs); //添加 结构体 到字典里
}
}
sweets = new GameSweet[ xLie, yHang ]; //实例化二维数据,第一个维度是列,第二个是行
for (int x = 0; x < xLie; x++)
{
for (int y = 0; y < yHang; y++)
{
CreateNewSweet(x, y, SweetsType.EMPTY); //调用创建按钮的方法
}
}
Destroy(sweets[4, 4].gameObject);
CreateNewSweet(4, 4, SweetsType.BARRIER);
Destroy(sweets[4, 3].gameObject);
CreateNewSweet(4, 3, SweetsType.BARRIER);
Destroy(sweets[1, 1].gameObject);
CreateNewSweet(1, 1, SweetsType.BARRIER);
Destroy(sweets[7, 1].gameObject);
CreateNewSweet(7, 1, SweetsType.BARRIER);
Destroy(sweets[1, 6].gameObject);
CreateNewSweet(1, 6, SweetsType.BARRIER);
Destroy(sweets[7, 6].gameObject);
CreateNewSweet(7, 6, SweetsType.BARRIER);
for (int x = 0; x < xLie; x++) //实例化背景
{
for (int y = 0; y < yHang; y++)
{
//实例化方块背景
GameObject chocolate = (GameObject) Instantiate(gridPrefab, CorrectPosition(x, y), Quaternion.identity);
chocolate.transform.parent = transform; //设置父物体
}
}
StartCoroutine(AllFill()); //开启协成
}
/// <summary>
/// 更新函数
/// </summary>
void Update()
{
if (IsGameOver) return; //如果游戏结束,直接跳出
TimeCountDown -= Time.deltaTime; //倒计时
if (TimeCountDown <= 0)
{
TimeCountDown = 0;
IsGameOver = true;
GameOverPanel.SetActive(true); //激活结束游戏界面
FinalScoreText = GameObject.Find("LastScore_Text").GetComponent<Text>();
FinalScoreText.text = PlayerScore.ToString(); //最终得分:赋值
Button button = GameObject.Find("RePlay_Button").GetComponent<Button>(); //添加游戏结束界面:按钮方法
button.onClick.AddListener(RePlay);
button = GameObject.Find("ReturnMain_Button").GetComponent<Button>();
button.onClick.AddListener(ReturnToMain);
return;
}
TimeText.text = TimeCountDown.ToString("0"); //由于,是浮点型变量,所以强转取整数
if (AddScoreTime <= 0.03f)
{
AddScoreTime += Time.deltaTime;
}
else
{
if (CurrentScore < PlayerScore)
{
CurrentScore++;
PlayerScoreText.text = CurrentScore.ToString();
AddScoreTime = 0;
}
}
}
/// <summary>
/// 背景块的实际位置
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public Vector3 CorrectPosition(int x, int y)
{
//实例化巧克力的实际位置
return new Vector3(transform.position.x - xLie / 2f + x, transform.position.y + yHang / 2f - y);
}
/// <summary>
/// 生成物品方法
/// </summary>
/// &l