• 经典游戏案例:仿植物大战僵尸


    学习目标:仿植物大战僵尸核心玩法实现

    游戏画面

    项目结构目录

    部分核心代码

    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.SceneManagement;
    6. using Random = UnityEngine.Random;
    7. public enum ZombieType
    8. {
    9. Zombie1,
    10. ConeHeadZombie,
    11. BucketHeadZombie,
    12. }
    13. [Serializable]
    14. public struct Wave
    15. {
    16. [Serializable]
    17. public struct Data
    18. {
    19. public ZombieType zombieType;
    20. public uint count;
    21. }
    22. public bool isLargeWave;
    23. [Range(0f,1f)]
    24. public float percentage;
    25. public Data[] zombieData;
    26. }
    27. public class GameController : MonoBehaviour
    28. {
    29. public GameObject zombie1;
    30. public GameObject BucketheadZombie;
    31. public GameObject ConeheadZombie;
    32. private GameModel model;
    33. public GameObject progressBar;
    34. public GameObject gameLabel;
    35. public GameObject sunPrefab;
    36. public GameObject cardDialog;
    37. public GameObject sunLabel;
    38. public GameObject shovelBG;
    39. public GameObject btnSubmitObj;
    40. public GameObject btnResetObj;
    41. public string nextStage;
    42. public float readyTime;
    43. public float elapsedTime;
    44. public float playTime;
    45. public float sunInterval;
    46. public AudioClip readySound;
    47. public AudioClip zombieComing;
    48. public AudioClip hugeWaveSound;
    49. public AudioClip finalWaveSound;
    50. public AudioClip loseMusic;
    51. public AudioClip winMusic;
    52. public Wave[] waves;
    53. public int initSun;
    54. private bool isLostGame = false;
    55. void Awake()
    56. {
    57. model = GameModel.GetInstance();
    58. }
    59. void Start ()
    60. {
    61. model.Clear();
    62. model.sun = initSun;
    63. ArrayList flags=new ArrayList();
    64. for (int i = 0; i < waves.Length; i++)
    65. {
    66. if (waves[i].isLargeWave)
    67. {
    68. flags.Add(waves[i].percentage);
    69. }
    70. }
    71. progressBar.GetComponent<ProgressBar>().InitWithFlag((float[])flags.ToArray(typeof(float)));
    72. progressBar.SetActive(false);
    73. cardDialog.SetActive(false);
    74. sunLabel.SetActive(false);
    75. shovelBG.SetActive(false);
    76. btnResetObj.SetActive(false);
    77. btnSubmitObj.SetActive(false);
    78. GetComponent<HandlerForShovel>().enabled = false;
    79. GetComponent<HandlerForPlants>().enabled = false;
    80. StartCoroutine(GameReady());
    81. }
    82. Vector3 origin
    83. {
    84. get
    85. {
    86. return new Vector3(-2f,-2.6f);
    87. }
    88. }
    89. void OnDrawGizmos()
    90. {
    91. // DeBugDrawGrid(origin,0.8f,1f,9,5,Color.blue);
    92. }
    93. void DeBugDrawGrid(Vector3 _orgin,float x,float y,int col,int row,Color color)
    94. {
    95. for (int i = 0; i < col+1; i++)
    96. {
    97. Vector3 startPoint = _orgin + Vector3.right*i*x;
    98. Vector3 endPoint = startPoint + Vector3.up*row*y;
    99. Debug.DrawLine(startPoint,endPoint,color);
    100. }
    101. for (int i = 0; i < row+1; i++)
    102. {
    103. Vector3 startPoint = _orgin + Vector3.up * i * y;
    104. Vector3 endPoint = startPoint + Vector3.right * col * x;
    105. Debug.DrawLine(startPoint, endPoint, color);
    106. }
    107. }
    108. public void AfterSelectCard()
    109. {
    110. btnResetObj.SetActive(false);
    111. btnSubmitObj.SetActive(false);
    112. Destroy(cardDialog);
    113. GetComponent<HandlerForShovel>().enabled = true;
    114. GetComponent<HandlerForPlants>().enabled = true;
    115. Camera.main.transform.position=new Vector3(1.1f,0,-1f);
    116. StartCoroutine(WorkFlow());
    117. InvokeRepeating("ProduceSun", sunInterval, sunInterval);
    118. }
    119. IEnumerator GameReady()
    120. {
    121. yield return new WaitForSeconds(0.5f);
    122. MoveBy move = Camera.main.gameObject.AddComponent<MoveBy>();
    123. move.offset=new Vector3(3.55f,0,0);
    124. move.time = 1f;
    125. move.Begin();
    126. yield return new WaitForSeconds(1.5f);
    127. sunLabel.SetActive(true);
    128. shovelBG.SetActive(true);
    129. cardDialog.SetActive(true);
    130. btnResetObj.SetActive(true);
    131. btnSubmitObj.SetActive(true);
    132. }
    133. void Update()
    134. {
    135. if (Input.GetKeyDown(KeyCode.S))
    136. {
    137. model.sun += 50;
    138. }
    139. if (!isLostGame)
    140. {
    141. for (int row = 0; row < model.zombieList.Length; row++)
    142. {
    143. foreach (GameObject zombie in model.zombieList[row])
    144. {
    145. if (zombie.transform.position.x<(StageMap.GRID_LEFT-0.4f))
    146. {
    147. LoseGame();
    148. isLostGame = true;
    149. return;
    150. }
    151. }
    152. }
    153. }
    154. }
    155. IEnumerator WorkFlow()
    156. {
    157. gameLabel.GetComponent<GameTips>().ShowStartTip();
    158. AudioManager.GetInstance().PlaySound(readySound);
    159. yield return new WaitForSeconds(readyTime);
    160. ShowProgressBar();
    161. AudioManager.GetInstance().PlaySound(zombieComing);
    162. for (int i = 0; i < waves.Length; i++)
    163. {
    164. yield return StartCoroutine(WaitForWavePercentage(waves[i].percentage));
    165. if (waves[i].isLargeWave)
    166. {
    167. StopCoroutine(UpdateProgress());
    168. yield return StartCoroutine(WaitForZombieClear());
    169. yield return new WaitForSeconds(3.0f);
    170. gameLabel.GetComponent<GameTips>().ShowApproachingTip();
    171. AudioManager.GetInstance().PlaySound(hugeWaveSound);
    172. yield return new WaitForSeconds(3.0f);
    173. StartCoroutine(UpdateProgress());
    174. }
    175. if (i+1==waves.Length)
    176. {
    177. gameLabel.GetComponent<GameTips>().ShowFinalTip();
    178. AudioManager.GetInstance().PlaySound(finalWaveSound);
    179. }
    180. yield return StartCoroutine(WaitForZombieClear());
    181. CreatZombies(ref waves[i]);
    182. }
    183. yield return StartCoroutine(WaitForZombieClear());
    184. yield return new WaitForSeconds(2f);
    185. WinGame();
    186. }
    187. IEnumerator WaitForZombieClear()
    188. {
    189. while (true)
    190. {
    191. bool hasZombie = false;
    192. for (int row = 0; row < StageMap.ROW_MAX; row++)
    193. {
    194. if (model.zombieList[row].Count!=0)
    195. {
    196. hasZombie = true;
    197. break;
    198. }
    199. }
    200. if (hasZombie)
    201. {
    202. yield return new WaitForSeconds(0.1f);
    203. }
    204. else
    205. {
    206. break;
    207. }
    208. }
    209. }
    210. IEnumerator WaitForWavePercentage(float percentage)
    211. {
    212. while (true)
    213. {
    214. if ((elapsedTime/playTime)>=percentage)
    215. {
    216. break;
    217. }
    218. else
    219. {
    220. yield return 0;
    221. }
    222. }
    223. }
    224. IEnumerator UpdateProgress()
    225. {
    226. while (true)
    227. {
    228. elapsedTime += Time.deltaTime;
    229. progressBar.GetComponent<ProgressBar>().SetProgress(elapsedTime/playTime);
    230. yield return 0;
    231. }
    232. }
    233. void ShowProgressBar()
    234. {
    235. progressBar.SetActive(true);
    236. StartCoroutine(UpdateProgress());
    237. }
    238. void CreatZombies(ref Wave wave)
    239. {
    240. foreach (Wave.Data data in wave.zombieData)
    241. {
    242. for (int i = 0; i < data.count; i++)
    243. {
    244. CreatOneZombie(data.zombieType);
    245. }
    246. }
    247. }
    248. void CreatOneZombie(ZombieType type)
    249. {
    250. GameObject zombie=null;
    251. switch (type)
    252. {
    253. case ZombieType.Zombie1:
    254. zombie = Instantiate(zombie1);
    255. break;
    256. case ZombieType.ConeHeadZombie:
    257. zombie = Instantiate(ConeheadZombie);
    258. break;
    259. case ZombieType.BucketHeadZombie:
    260. zombie = Instantiate(BucketheadZombie);
    261. break;
    262. }
    263. int row = Random.Range(0, StageMap.ROW_MAX);
    264. zombie.transform.position = StageMap.SetZombiePos(row);
    265. zombie.GetComponent<ZombieMove>().row = row;
    266. zombie.GetComponent<SpriteDisplay>().SetOrderByRow(row);
    267. model.zombieList[row].Add(zombie);
    268. }
    269. void ProduceSun()
    270. {
    271. float x = Random.Range(StageMap.GRID_LEFT, StageMap.GRID_RIGTH);
    272. float y = Random.Range(StageMap.GRID_BOTTOM, StageMap.GRID_TOP);
    273. float startY = StageMap.GRID_TOP + 1.5f;
    274. GameObject sun = Instantiate(sunPrefab);
    275. sun.transform.position=new Vector3(x,startY,0);
    276. MoveBy move = sun.AddComponent<MoveBy>();
    277. move.offset=new Vector3(0,y-startY,0);
    278. move.time = (startY - y)/1.0f;
    279. move.Begin();
    280. }
    281. void LoseGame()
    282. {
    283. gameLabel.GetComponent<GameTips>().ShowLostTip();
    284. GetComponent<HandlerForPlants>().enabled = false;
    285. CancelInvoke("ProduceSun");
    286. AudioManager.GetInstance().PlayMusic(loseMusic,false);
    287. }
    288. void WinGame()
    289. {
    290. CancelInvoke("ProduceSun");
    291. AudioManager.GetInstance().PlayMusic(winMusic, false);
    292. Invoke("GotoNextStage",3.0f);
    293. }
    294. void GotoNextStage()
    295. {
    296. SceneManager.LoadScene(nextStage);
    297. }
    298. }

    下载链接:PlantsVsZombies: 经典游戏:植物大战僵尸

  • 相关阅读:
    互联网大厂ssp面经,数据结构part2
    SpringBoot中常用注解的含义
    Win10无法连接打印机怎么办?不能使用打印机的解决方法
    【秋招面经】微盟二面
    Lesson11——NumPy 位运算
    【开源项目】mysql大表数据迁移
    神经系统ct与mri影像解读,神经系统影像学检查
    为什么电容两端电压不能突变
    WIN11任务栏出现空白,卡任务栏的解决办法
    如何解决swagger-editor在线接口调试时的跨域问题
  • 原文地址:https://blog.csdn.net/my183100521/article/details/139888108