Unity: 打飞碟简单版

游戏规则

  • 一共有三个回合,随着回合增加,单位时间出现的飞碟数合飞碟的速度都会增加
  • 分数由玩家点击的飞碟颜色决定,黑色3分,红色2分,黄色1分
  • 每个回合有20个飞碟
  • 没有失败的条件,最后看分数多少

游戏场景

代码组织结构

代码结构

在老师给的框架下做一些扩展即可

代码

Disk.cs 飞碟的属性脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Disk : MonoBehaviour {//初始化的位置public Vector3 StartPoint { get { return gameObject.transform.position; } set { gameObject.transform.position = value; } }public Color color { get { return gameObject.GetComponent<Renderer>().material.color; } set { gameObject.GetComponent<Renderer>().material.color = value; } }//初始速度public float speed { get;set; }//方向public Vector3 Direction { get { return Direction; } set { gameObject.transform.Rotate(value); } }public int score;   //后面没用到
}

DiskFactory.cs 飞碟工厂,管理飞碟的产生、销毁

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DiskFactory { public GameObject diskPrefab;public static DiskFactory DF = new DiskFactory();private Dictionary<int, Disk> used = new Dictionary<int, Disk>();//used是用来保存正在使用的飞碟 private List<Disk> free = new List<Disk>();//free是用来保存未激活的飞碟 private DiskFactory(){diskPrefab = GameObject.Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/disk"));//获取预制的游戏对象diskPrefab.AddComponent<Disk>();diskPrefab.SetActive(false);}//更新used和free列表里的飞碟public void FreeDisk(){foreach (Disk x in used.Values){if (!x.gameObject.activeSelf){free.Add(x);used.Remove(x.GetInstanceID());return;}}}//获取一个free的飞碟public Disk GetDisk(int round)  {FreeDisk();GameObject newDisk = null;Disk disk;if (free.Count > 0){//从之前生产的Disk中拿出可用的newDisk = free[0].gameObject;free.Remove(free[0]);}else{//克隆预制对象,生产新DisknewDisk = GameObject.Instantiate<GameObject>(diskPrefab, Vector3.zero, Quaternion.identity);}newDisk.SetActive(true);disk = newDisk.AddComponent<Disk>();    //添加属性脚本int initCase;initCase = Random.Range(0, 5);/** * 根据回合数来生成相应的飞碟,难度逐渐增加。*/float initSpeed;if (round == 1){initSpeed = Random.Range(40, 60);}else if (round == 2){initSpeed = Random.Range(60, 90);}else {initSpeed = Random.Range(90, 120);} //根据initCase的不同设计飞碟的颜色、初速度、初始化位置等switch (initCase)  {  case 0:  {  disk.color = Color.yellow;  disk.speed = initSpeed;  float RanX = UnityEngine.Random.Range(-1f, 1f) < 0 ? -1 : 1;  disk.Direction = new Vector3(RanX, 1, 0);disk.StartPoint = new Vector3(Random.Range(-130, -110), Random.Range(30,90), Random.Range(110,140));break;  }  case 1:  {  disk.color = Color.red;  disk.speed = initSpeed + 10;  float RanX = UnityEngine.Random.Range(-1f, 1f) < 0 ? -1 : 1;  disk.Direction = new Vector3(RanX, 1, 0);disk.StartPoint = new Vector3(Random.Range(-130, -110), Random.Range(30, 80), Random.Range(110, 130));break;  }  case 2:  {  disk.color = Color.black;  disk.speed = initSpeed + 15;  float RanX = UnityEngine.Random.Range(-1f, 1f) < 0 ? -1 : 1;  disk.Direction = new Vector3(RanX, 1, 0);disk.StartPoint = new Vector3(Random.Range(-130,-110), Random.Range(30, 70), Random.Range(90, 120));break;  }case 3:{disk.color = Color.yellow;disk.speed = -initSpeed;float RanX = UnityEngine.Random.Range(-1f, 1f) < 0 ? -1 : 1;disk.Direction = new Vector3(RanX, 1, 0);disk.StartPoint = new Vector3(Random.Range(130, 110), Random.Range(30, 90), Random.Range(110, 140));break;}case 4:{disk.color = Color.red;disk.speed = -initSpeed - 10;float RanX = UnityEngine.Random.Range(-1f, 1f) < 0 ? -1 : 1;disk.Direction = new Vector3(RanX, 1, 0);disk.StartPoint = new Vector3(Random.Range(130, 110), Random.Range(30, 80), Random.Range(110, 130));break;}case 5:{disk.color = Color.black;disk.speed = -initSpeed - 15;float RanX = UnityEngine.Random.Range(-1f, 1f) < 0 ? -1 : 1;disk.Direction = new Vector3(RanX, 1, 0);disk.StartPoint = new Vector3(Random.Range(130, 110), Random.Range(30, 70), Random.Range(90, 120));break;}}if (disk.color == Color.black) disk.score = 3;else if (disk.color == Color.red) disk.score = 2;else disk.score = 1;used.Add(disk.GetInstanceID(), disk); //添加到使用队列里disk.name = disk.GetInstanceID().ToString();return disk;  }
}

CCFlyAction.cs 具体的飞行动作

using System.Collections;
using System.Collections.Generic;
using UnityEngine;//飞行的动作,由上个游戏的CCMoveToAction改动过来的
public class CCFlyAction : SSAction
{//速度分解为x和y方向,y方向初始为0public float speedx;public float speedy = 0;private CCFlyAction() { }//单例模式,给定初始的x方向速度public static CCFlyAction getAction(float speedx){CCFlyAction action = CreateInstance<CCFlyAction>();action.speedx = speedx;return action;}//运动public override void Update(){// dx = vtfloat deltax = speedx * Time.deltaTime;// dy = yt + 0.5at^2float deltay = -speedy * Time.deltaTime + (float)-0.5 * 10 * Time.deltaTime * Time.deltaTime;this.transform.position += new Vector3(deltax, deltay,0);// y' = y + atspeedy += 10*Time.deltaTime;//当飞碟的位置的y坐标小于阈值,认为消失在用户视野中,执行销毁if (transform.position.y <= 1){destroy = true;CallBack.SSActionCallback(this);}}public override void Start(){}
}

Interfaces.cs:接口定义,主要修改UserAction接口

using System.Collections;
using System.Collections.Generic;
using UnityEngine;namespace Interfaces
{public interface ISceneController{void LoadResources();}public interface UserAction{void Hit(Vector3 pos);      //鼠标点击void Restart();             //开始和重新开始都一样int GetScore();             bool RoundStop();           //最后的回合结束int GetRound();             }   public enum SSActionEventType : int { Started, Completed }public interface SSActionCallback{void SSActionCallback(SSAction source);}
}

FirstSceneController.cs:挂在空项目上的脚本,场景控制器

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Interfaces;public class FirstSceneController : MonoBehaviour, ISceneController, UserAction
{int score = 0;      //分数int round = 1;      //回合,设置了3个int producedDiskNum = 0;    //每回合已经产生的飞碟数目bool start = false;CCActionManager Manager;DiskFactory DF;void Awake(){SSDirector director = SSDirector.getInstance();director.currentScenceController = this;DF = DiskFactory.DF;Manager = GetComponent<CCActionManager>();}// Use this for initializationvoid Start () {}// Update is called once per frameint count = 0;void Update () {//val帧产生一个飞碟int val;switch (round){case 1:val = Random.Range(60, 80);break;case 2:val = Random.Range(45, 60);break;default:val = 40;break;}if(start){count++;if (count >= val)    //val帧一个飞碟{count = 0;if(DF == null){Debug.LogWarning("DF is NUll!");return;}producedDiskNum++;Disk d = DF.GetDisk(round);Manager.MoveDisk(d);if (producedDiskNum == 15) //15个飞碟进入下一个回合{round++;producedDiskNum = 0;}}}}public void LoadResources(){}public void Hit(Vector3 pos){Ray ray = Camera.main.ScreenPointToRay(pos);RaycastHit[] hits;hits = Physics.RaycastAll(ray);for (int i = 0; i < hits.Length; i++){RaycastHit hit = hits[i];//根据颜色加分if (hit.collider.gameObject.GetComponent<Disk>() != null){Color c = hit.collider.gameObject.GetComponent<Renderer>().material.color;if (c == Color.yellow) score += 1;if (c == Color.red) score += 2;if (c == Color.black) score += 3;hit.collider.gameObject.transform.position = new Vector3(0, -5, 0);}}}public int GetScore(){return score;}//初始化各变量public void Restart(){score = 0;round = 1;start = true;}//到了第三回合要判断是否结束public bool RoundStop(){if (round > 3){start = false;return Manager.IsAllFinished();//是否还有飞碟留在used列表里}else return false;}public int GetRound(){return round;}
}

InterfaceGUI.cs:挂在相机的脚本,负责管理与玩家的界面管理

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Interfaces;
using UnityEngine.UI;//挂在相机的脚本
public class InterfaceGUI : MonoBehaviour {UserAction userAction;bool isPlaying = false;float S;int round = 1;// Use this for initializationvoid Start () {userAction = SSDirector.getInstance().currentScenceController as UserAction;S = Time.time;}private void OnGUI(){if(!isPlaying) S = Time.time;//分数、时间、回合string text = "分数: " + userAction.GetScore().ToString() + "  时间:  " + ((int)(Time.time - S)).ToString() + "  回合:  " + round;GUI.Label(new Rect(10, 10, Screen.width, 50),text);if (!isPlaying && GUI.Button(new Rect(Screen.width / 2 - 75, Screen.height / 2 - 25, 150, 50), "开始游戏")){S = Time.time;isPlaying = true;userAction.Restart();   //点击开始游戏,FirstSceneController开始游戏}if (isPlaying){round = userAction.GetRound();if (Input.GetButtonDown("Fire1")){//把鼠标点击的位置传给FirstScenceController,处理点击事件Vector3 pos = Input.mousePosition;userAction.Hit(pos);}if (round > 3)  //round>3要等待飞碟都用完了{round = 3;if (userAction.RoundStop()){isPlaying = false;}}}}

其他类基本没有变化


总结

本次代码因为规则的设计比较简单而简单,其实可以加上生命之之类的功能。

Github传送门

Unity: 打飞碟简单版相关推荐

  1. 高端游戏开发工具:Unity Pro 2019 Mac版

    Unity Pro 2019 for Mac是专业的游戏开发工具,unity pro 2019 mac版具备最先进的游戏引擎之一,新版本提供了模块化组件系统.着色器可视化编程工具.可视乎开发环境.渲染 ...

  2. Unity游戏优化[第二版]学习记录6

    以下内容是根据Unity 2020.1.01f版本进行编写的 Unity游戏优化[第二版]学习记录6 第6章 动态图形 一.管线渲染 1.GPU前端 2.GPU后端 3.光照和阴影 4.多线程渲染 5 ...

  3. Unity 2017.1正式版内容介绍

    Unity 2017.1正式版现已发布,这也标志着Unity 2017产品周期的开始,将全球最受欢迎的游戏引擎变成不断壮大的游戏与实时互动娱乐内容创作平台,专注于帮助各型团队改善工作流程并获得成功. ...

  4. Unity 2017.1正式版发布

    Unity 2017.1正式版现已发布,这也标志着Unity 2017产品周期的开始,将全球最受欢迎的游戏引擎变成不断壮大的游戏与实时互动娱乐内容创作平台,专注于帮助各型团队改善工作流程并获得成功. ...

  5. Unity游戏优化[第二版]学习记录4

    Unity游戏优化[第二版]学习记录4 第4章 着手处理艺术资源 一.音频 1.导入音频文件 2.加载音频文件 3.编码格式与品质级别 4. 音频性能增强 二.纹理文件 1.纹理压缩格式 2.纹理性能 ...

  6. LeetCode 11. Container With Most Water--Java 解法--困雨水简单版

    LeetCode 11. Container With Most Water–Java 解法 此文首发于我的个人博客:LeetCode 11. Container With Most Water–Ja ...

  7. luogu P3808 【模板】AC自动机(简单版)

    二次联通门 : luogu P3808 [模板]AC自动机(简单版) /*luogu P3808 [模板]AC自动机(简单版)手速越来越快了10分钟一个AC自动机一遍过编译 + 一边AC感觉不错我也就 ...

  8. 008 数据结构逆向—数组(简单版)

    文章目录 前言 逆向背包数组 一维背包数组 二维背包数组 数组结构分析 总结 前言 对于游戏逆向来说,核心需求其实就只有两个 追踪游戏数据 定位游戏功能call 对于追踪游戏数据来说,单纯从一个寄存器 ...

  9. 【模板】AC自动机(简单版)

    题目背景 通过套取数据而直接"打表"过题者,是作弊行为,发现即棕名. 这是一道简单的AC自动机模板题. 用于检测正确性以及算法常数. 为了防止卡OJ,在保证正确的基础上只有两组数据 ...

  10. P3808,P3796-[模板]AC自动机(简单版/加强版)

    简单版 题目链接: https://www.luogu.org/problem/P3808 题目大意 nnn个模式串,一个文本串,求有多少个模式串出现在文本串里. 解题思路 普通ACACAC自动机不解 ...

最新文章

  1. 消息机制(GUI线程讲解)
  2. 幕课网产品总监:教你从0到1打造600W下载量的爆款APP
  3. Sklearn参数详解—SVM
  4. CCNP-第十篇-BGP(二)
  5. 白领夫妇白手起家 6年赚得两房两车
  6. Java ResourceBundle getLocale()方法与示例
  7. cent os 7 mysql_centos – 百胜:Cent OS 7中没有包mysql-server
  8. 小白重装系统教程_小白重装系统使用教程
  9. 公司招聘asp.net 工程师
  10. rk3399_android7.1关于看门狗驱动的实现原理说明
  11. [做一个幸福的记号 忘了琐碎的烦恼]西兰花猪柳
  12. Linux内核基础--事件通知链(notifier chain)
  13. Win7系统做路由器
  14. linux java解压文件怎么打开,java linux 解压zip文件怎么
  15. 解决AndroidStudio报错问题:Missing essential plugin
  16. 毕业实习感想—软件测试
  17. 常见的设计模式和应用场景
  18. ios 画线平滑_ios-iPhone平滑草图绘制算法
  19. python系列tkinter之pack布局、place布局和grid布局
  20. 关闭删库跑路的后门,打造高可用的MySQL

热门文章

  1. cass转换jpg_怎么把CAD图转换成清晰的JPG等其他格式图形文件
  2. linux上c语言贪吃蛇,在linux下用C语言编写贪吃蛇小游戏-Go语言中文社区
  3. 【数据库】E-R图相关知识、绘制方法及工具推荐
  4. Oracle中索引的原理
  5. Microchip PIC系列8位单片机入门教程(六)ADC
  6. FusionChartsFree的用法
  7. limesurvey_LimeSurvey简介:一个开源,功能丰富的轮询平台
  8. DJ4 组合逻辑电路与138译码器
  9. 数据挖掘的9大成熟技术和应用
  10. JavaWeb 简单实现客户信息管理系统