当前位置: 首页 > news >正文

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

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

游戏画面

项目结构目录

部分核心代码

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using Random = UnityEngine.Random;public enum ZombieType
{Zombie1,   ConeHeadZombie,BucketHeadZombie,
}[Serializable]
public struct Wave
{[Serializable]public struct Data{public ZombieType zombieType;public uint count;}public bool isLargeWave;[Range(0f,1f)]public float percentage;public Data[] zombieData;
}public class GameController : MonoBehaviour
{public GameObject zombie1;public GameObject BucketheadZombie;public GameObject ConeheadZombie;private GameModel model;public GameObject progressBar;public GameObject gameLabel;public GameObject sunPrefab;public GameObject cardDialog;public GameObject sunLabel;public GameObject shovelBG;public GameObject btnSubmitObj;public GameObject btnResetObj;public string nextStage;public float readyTime;public float elapsedTime;public float playTime;public float sunInterval;public AudioClip readySound;public AudioClip zombieComing;public AudioClip hugeWaveSound;public AudioClip finalWaveSound;public AudioClip loseMusic;public AudioClip winMusic;public Wave[] waves;public int initSun;private bool isLostGame = false;void Awake(){model = GameModel.GetInstance();}void Start (){model.Clear();model.sun = initSun;ArrayList flags=new ArrayList();for (int i = 0; i < waves.Length; i++){if (waves[i].isLargeWave){flags.Add(waves[i].percentage);}}progressBar.GetComponent<ProgressBar>().InitWithFlag((float[])flags.ToArray(typeof(float)));progressBar.SetActive(false);cardDialog.SetActive(false);sunLabel.SetActive(false);shovelBG.SetActive(false);btnResetObj.SetActive(false);btnSubmitObj.SetActive(false);GetComponent<HandlerForShovel>().enabled = false;GetComponent<HandlerForPlants>().enabled = false;StartCoroutine(GameReady());}Vector3 origin{get{return new Vector3(-2f,-2.6f);}}void OnDrawGizmos(){// DeBugDrawGrid(origin,0.8f,1f,9,5,Color.blue);}void DeBugDrawGrid(Vector3 _orgin,float x,float y,int col,int row,Color color){for (int i = 0; i < col+1; i++){Vector3 startPoint = _orgin + Vector3.right*i*x;Vector3 endPoint = startPoint + Vector3.up*row*y;Debug.DrawLine(startPoint,endPoint,color);}for (int i = 0; i < row+1; i++){Vector3 startPoint = _orgin + Vector3.up * i * y;Vector3 endPoint = startPoint + Vector3.right * col * x;Debug.DrawLine(startPoint, endPoint, color);}}public void AfterSelectCard(){btnResetObj.SetActive(false);btnSubmitObj.SetActive(false);Destroy(cardDialog);GetComponent<HandlerForShovel>().enabled = true;GetComponent<HandlerForPlants>().enabled = true;Camera.main.transform.position=new Vector3(1.1f,0,-1f);StartCoroutine(WorkFlow());InvokeRepeating("ProduceSun", sunInterval, sunInterval);}IEnumerator GameReady(){yield return new WaitForSeconds(0.5f);MoveBy move = Camera.main.gameObject.AddComponent<MoveBy>();move.offset=new Vector3(3.55f,0,0);move.time = 1f;move.Begin();yield return  new WaitForSeconds(1.5f);sunLabel.SetActive(true);shovelBG.SetActive(true);cardDialog.SetActive(true);btnResetObj.SetActive(true);btnSubmitObj.SetActive(true);}void Update(){if (Input.GetKeyDown(KeyCode.S)){model.sun += 50;}if (!isLostGame){for (int row = 0; row < model.zombieList.Length; row++){foreach (GameObject zombie in model.zombieList[row]){if (zombie.transform.position.x<(StageMap.GRID_LEFT-0.4f)){LoseGame();isLostGame = true;return;}}}  }}IEnumerator WorkFlow(){gameLabel.GetComponent<GameTips>().ShowStartTip();AudioManager.GetInstance().PlaySound(readySound);yield return new WaitForSeconds(readyTime);ShowProgressBar();AudioManager.GetInstance().PlaySound(zombieComing);for (int i = 0; i < waves.Length; i++){yield return StartCoroutine(WaitForWavePercentage(waves[i].percentage));if (waves[i].isLargeWave){StopCoroutine(UpdateProgress());yield return StartCoroutine(WaitForZombieClear());yield return new WaitForSeconds(3.0f);gameLabel.GetComponent<GameTips>().ShowApproachingTip();AudioManager.GetInstance().PlaySound(hugeWaveSound);yield return new WaitForSeconds(3.0f);StartCoroutine(UpdateProgress());}if (i+1==waves.Length){gameLabel.GetComponent<GameTips>().ShowFinalTip();AudioManager.GetInstance().PlaySound(finalWaveSound);}yield return StartCoroutine(WaitForZombieClear());CreatZombies(ref waves[i]);}yield return StartCoroutine(WaitForZombieClear());yield return new WaitForSeconds(2f);WinGame();}IEnumerator WaitForZombieClear(){while (true){bool hasZombie = false;for (int row = 0; row < StageMap.ROW_MAX; row++){if (model.zombieList[row].Count!=0){hasZombie = true;break;}}if (hasZombie){yield return new WaitForSeconds(0.1f);}else{break;}}}IEnumerator WaitForWavePercentage(float percentage){while (true){if ((elapsedTime/playTime)>=percentage){break;}else{yield return 0;}}}IEnumerator UpdateProgress(){while (true){elapsedTime += Time.deltaTime;  progressBar.GetComponent<ProgressBar>().SetProgress(elapsedTime/playTime);          yield return 0;}}void ShowProgressBar(){progressBar.SetActive(true);StartCoroutine(UpdateProgress());}void CreatZombies(ref Wave wave){foreach (Wave.Data data in wave.zombieData){for (int i = 0; i < data.count; i++){CreatOneZombie(data.zombieType);}}}void CreatOneZombie(ZombieType type){GameObject zombie=null;switch (type){case ZombieType.Zombie1:zombie = Instantiate(zombie1);break;            case ZombieType.ConeHeadZombie:zombie = Instantiate(ConeheadZombie);break;case ZombieType.BucketHeadZombie:zombie = Instantiate(BucketheadZombie);break;               }int row = Random.Range(0, StageMap.ROW_MAX);      zombie.transform.position = StageMap.SetZombiePos(row);zombie.GetComponent<ZombieMove>().row = row;zombie.GetComponent<SpriteDisplay>().SetOrderByRow(row);model.zombieList[row].Add(zombie);}void ProduceSun(){float x = Random.Range(StageMap.GRID_LEFT, StageMap.GRID_RIGTH);float y = Random.Range(StageMap.GRID_BOTTOM, StageMap.GRID_TOP);float startY = StageMap.GRID_TOP + 1.5f;GameObject sun = Instantiate(sunPrefab);sun.transform.position=new Vector3(x,startY,0);MoveBy move = sun.AddComponent<MoveBy>();move.offset=new Vector3(0,y-startY,0);move.time = (startY - y)/1.0f;move.Begin();}void LoseGame(){gameLabel.GetComponent<GameTips>().ShowLostTip();GetComponent<HandlerForPlants>().enabled = false;CancelInvoke("ProduceSun");AudioManager.GetInstance().PlayMusic(loseMusic,false);}void WinGame(){CancelInvoke("ProduceSun");AudioManager.GetInstance().PlayMusic(winMusic, false);Invoke("GotoNextStage",3.0f);}void GotoNextStage(){       SceneManager.LoadScene(nextStage);}
}

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

相关文章:

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

学习目标&#xff1a;植物大战僵尸核心玩法实现 游戏画面 项目结构目录 部分核心代码 using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using Random UnityEngine.Random;public enum Z…...

Go 与 Java 字符编码选择:UTF-8 与 UTF-16 的较量

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...

vscode+picgo+gitee实现Markdown图床

vscode中编辑Markdown文件&#xff0c;复制的图片默认是保存在本地的。当文档上传csdn时&#xff0c;会提示图片无法识别 可以在gitee上创建图床仓库&#xff0c;使用picgo工具上传图片&#xff0c;在Markdown中插入gitee链接的方式来解决该问题。 一、 安装picgo工具 1.1 v…...

【thinkphp问题栏】tp5.0分页技巧

一、调用内置方法paginate thinkphp内置了一个paginate方法支持分页功能 该方法位于library\think\db\Query.php内 /*** 分页查询* param int|array $listRows 每页数量 数组表示配置参数* param int|bool $simple 是否简洁模式或者总记录数* param array $config 配…...

获取时间戳是使用System.currentTimeMillis()还是使用new Date().getTime()(阿里开发规范)?

1.阿里规范 在阿里的Java开发手册中强制要求使用System.currentTimeMillis() 2.为什么(源码详解) new Date().getTime()它实际上也是调用的System.currentTimeMillis()&#xff0c;源码分析。 这个fastTime是它的成员变量&#xff0c;在new Date()的时候就被赋值了。 扩展一…...

仿饿了么加入购物车旋转控件 - 自带闪转腾挪动画 的按钮

, mWidth - mCircleWidth, mHeight - mCircleWidth); canvas.drawRoundRect(rectF, mHintBgRoundValue, mHintBgRoundValue, mHintPaint); //前景文字 mHintPaint.setColor(mHintFgColor); // 计算Baseline绘制的起点X轴坐标 int baseX (int) (mWidth / 2 - mHintPaint.m…...

Docker部署nacos集群

docker拉取nacos镜像&#xff0c;本文使用nacos2.0.3 三台服务器都要执行以下命令 docker pull nacos/nacos-server:v2.2.0准备挂载的日志目录和配置文件目录 日志&#xff1a;mkdir /usr/local/software/nacos/logs 配置文件&#xff1a;/usr/local/software/nacos/conf在配…...

centos查找文件 及 操作写入的进程

du -sh * 查看目录空间占用、发现大文件&#xff0c;确定进程&#xff0c;结束 yum install lsof 安装lsof 查看文件写入的 进程 2. lsof /root/.influxdbv2/engine/data/bab49411e5f7cbce/autogen/1/000000036-000000002.tsm COMMAND PID USER FD TYPE …...

构建高可用Java微服务架构的秘籍

构建高可用Java微服务架构的秘籍 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 随着云计算和分布式系统的快速发展&#xff0c;微服务架构已成为构建大型应用…...

VBA学习(18):VBA制作任意工作表均可使用的聚光灯

在需要制作聚光的工作簿&#xff0c;按<ALTF11>组合键&#xff0c;打开VBE编辑器。在右侧[工程资源管理器窗格]选中ThisWorkbook模块&#xff0c;将以下代码复制粘贴到该模块的代码窗口。 Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target …...

【STM32-启动文件 startup_stm32f103xe.s】

STM32-启动文件 startup_stm32f103xe.s ■ STM32-启动文件■ STM32-启动文件主要做了以下工作&#xff1a;■ STM32-启动文件指令■ STM32-启动文件代码详解■ 栈空间的开辟■ 栈空间大小 Stack_Size■ .map 文件的详细介绍■ 打开map文件 ■ 堆空间■ PRESERVE8 和 THUMB 指令…...

51学习记录(一)——51介绍及震动感应灯

文章目录 前言一、STC89C522.内部结构及引脚 二、继电器原理及震动传感器原理三、项目搭建及实现 前言 一个学习嵌入式的小白~ 有问题评论区或私信指出 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、STC89C52 1.简介 所属系列&#xff1a;51单…...

2024GLEE生活暨教育(上海)博览会,8月20-22日,国家会展中心(上海)

2024GLEE生活暨教育(上海)博览会将于8月20-22日在中国国家会展中心&#xff08;上海&#xff09;举行&#xff0c;博览会总面积近万平方米&#xff0c;设有美好生活和教育产品两大主力展区&#xff0c;全面覆盖婴幼儿、学龄前、小学、初中、高中、大学、中年、老年各个年龄段的…...

debug调试高级功能 断点、布局 及Android Studio常用快捷按键使用详情

文章目录 debug断点篇&#xff1a;打临时断点&#xff08;只用一次&#xff09;&#xff1a;alt断点条件断点&#xff1a;在断点上&#xff0c;点击右键&#xff0c;在Condition那里&#xff0c;设置我们需要的值&#xff0c;循环就会自动停到我们设置的那个值那里依赖断点&…...

51单片机STC89C52RC——6.1 中断系统

一&#xff0c;文字层面理解 反正我看下面的几段文字时脑壳没有正常运转。一个头几个大 中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。 当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求&#xff0c;要求CPU暂停当前的工作&#xff0c;转而去处理这…...

Redis源码学习:高性能Hash表的设计与实现

哈希表&#xff08;Hash&#xff09;是Redis数据库的数据类型之一&#xff0c;理解哈希表的实现对于掌握Redis非常重要。这篇文章&#xff0c;从哈希冲突和哈希扩展这两个角度&#xff0c;来一步步讲解Redis哈希表的工作原理。 什么是哈希表&#xff1f; 哈希表是一种通过哈希…...

如何防范常见的数据库安全问题

随着数据量的增加和系统的复杂性提高,数据库可能面临多种安全威胁,包括未授权访问、数据泄露、注入攻击等。 1. 未授权访问 未授权访问是指,未经授权的用户对数据库的内容进行访问。这会导致数据泄露、数据篡改或其他安全事故。 针对未授权访问的防范措施如下。 (1)强化…...

[Day 19] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

區塊鏈的數據透明性 區塊鏈技術作為一種分布式賬本技術&#xff0c;因其去中心化、不可篡改和高度透明的特性&#xff0c;已經在各行各業中得到了廣泛應用。在本文中&#xff0c;我們將深入探討區塊鏈的數據透明性&#xff0c;包括其原理、實現方法及相關代碼示例&#xff0c;…...

【Hadoop学习笔记】认识Hadoop

认识Hadoop 从网上找的课程做的笔记&#xff0c;有些图是自己理解画的&#xff0c;可能不正确&#xff0c;可以作为参考&#xff0c;有疑问的地方请直接指出&#xff0c;共同交流。 Hadoop是由Apache基金会开发的一个分布式系统基础架构&#xff0c;主要解决海量数据的存储和海…...

CISP-PTE综合靶机-WinServer2003

1.收集网站的地址和开放的端口,完成前期信息收集。10分 2.访问站点,找出站点的敏感文件,利用返回数据找到相关敏感信 息,完成网站结构的信息收集。10分 3.利用文件包含漏洞读取敏感文件,找出数据库连接凭证,利用此 凭证连接数据库。10分 4.网站后台提权:找出后台管理员登…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...