Unity3D学习之路Homework4—— 飞碟射击游戏
简单打飞碟小游戏
游戏规则与要求
规则
鼠标点击飞碟,即可获得分数,不同飞碟分数不一样,飞碟的初始位置与飞行速度随机,随着分数增加,游戏难度增加。初始时每个玩家都有6条生命,漏打飞碟扣除一条生命,直到生命为0游戏结束。要求:
使用带缓存的工厂模式管理不同飞碟的生产与回收,该工厂必须是场景单实例的!具体实现见参考资源 Singleton 模板类
近可能使用前面 MVC 结构实现人机交互与游戏模型分离
扩展:实现:
第一阶段做的井字棋还是能了解透彻的,Homework2的MVC架构和Homework3里的动作分离管理开始吃力了,说实话,现在对动作分离管理还不怎么理解透,但还是能理解MVC了。所以这次作业我并没有用到动作分离管理,只是用了MVC架构,也只是简单的MVC,所以没有SSDirector类了,当然,还有这周要求的工厂模式也是有的。
之前两次作业看了不少博客,感觉类与类之间的交叉很多,虽然有了MVC和动作管理,但我看得结构不是很清晰(好吧,可能是我能力的问题)。这次我学会了两个很基础但很好用的两个方法(原谅我到了现在才会。。。)——对象gameObject(注意g是小写不是大写)和GetComponent<>(),之前我一直想着用C++里面的方法实现封装,即该方法或动作是属于哪个类的就放在它里面,一个类不要去操作另一个类,可以通过函数调用。讲一下gameObject和GetComponent吧
- GetComponent:先说这个比较好,我们创建每个游戏对象都是用GameObject的了,但不同对象有不同的方法和属性,所以就可以自己写脚本挂到物体上,让它实现你想要的方法。当然,通过这个方法也可以添加其它组件比如Rigibody 。
- gameObject:这是GameObject的实例,但它是ReadOnly即只读,它有什么用呢,当你把一个组件(这里重点指的是脚本),怎么获得该脚本挂的物体呢,其实是有记录的,gameObject就是脚本当前挂的物体。
下面讲下本实验的过程:
成品图:
做的确实不好。。。
玩法:每按一次空格能出来一个飞碟,然后点击鼠标去点它,点中了会消失,或者飞离一定距离也会消失。
代码:
功能少所以代码比较少。
- GameModel类即disk的属性与方法:
using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class GameModel : MonoBehaviour{ static int count = 0; public Color diskColor; private Vector3 emitPosition; private Vector3 emitDirection; private float emitSpeed; private bool is_used; private int diskScale; private int id; public GameModel() { id = 0; count++; } public int getID() { return id; } public void setColor(Color diskColor) { this.GetComponent<MeshRenderer>().material.color = diskColor; } public void setEmitPosition(Vector3 emitPosition_) { emitPosition = emitPosition_; this.transform.position = emitPosition_; } public void setEmitDirection(Vector3 emitDirection_) { emitDirection = emitDirection_; gameObject.GetComponent<Rigidbody>().AddForce(3000 * emitDirection_); } public void setState(bool state) { is_used = state; gameObject.SetActive(is_used); } public bool getState() { return is_used; } public bool is_outOfEdge() { if(transform.position.z>150 || transform.position.z<-150 || transform.position.x < -50 || transform.position.x >50 || transform.position.y>10 || transform.position.y < -20) { return true; } else { return false; } }
}
- DiskFactory类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DiskFactory{private static DiskFactory _instance;private static List<GameObject> unusedDiskList = new List<GameObject>();private static List<GameObject> usedDiskList = new List<GameObject>();public GameObject diskTemplate;public static DiskFactory getInstance(){if(_instance == null){_instance = new DiskFactory();}return _instance;}private DiskFactory() { }public GameObject getDiskObject(){GameObject disk1;if (unusedDiskList.Count == 0){disk1 = GameObject.Instantiate(diskTemplate) as GameObject;usedDiskList.Add(disk1);}else{disk1 = unusedDiskList[0];unusedDiskList.RemoveAt(0);usedDiskList.Add(disk1);}disk1.GetComponent<GameModel>().setState(true);return disk1;}public void removeDiskObject(GameObject obj){if (usedDiskList.Count > 0){GameObject disk1 = obj;disk1.GetComponent<Rigidbody>().velocity = Vector3.zero;disk1.GetComponent<GameModel>().setState(false);usedDiskList.Remove(obj); unusedDiskList.Add(disk1);}}//返回出界的disk的数目public int updateList(){int count = 0;for(int i = 0; i < usedDiskList.Count; i++){if(usedDiskList[i].GetComponent<GameModel>().is_outOfEdge()){removeDiskObject(usedDiskList[i]);count++;}}return count;}public void clear(){usedDiskList.Clear();unusedDiskList.Clear();}
}public class DiskFactoryBC : MonoBehaviour
{public GameObject disk;private void Awake(){DiskFactory.getInstance().diskTemplate = disk;}
}
- 记分员类scoreRecorder:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ScoreRecorder {private int score;public ScoreRecorder(){score = 0;}public void addScore(int add){score+=add;}public void subScore(int sub){score=score-sub;}public int getScore(){return score;}public void resetScore(){score = 0;}
}
- SceneController类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum GameState { BEFORESTART,ROUND1,ROUND2,END};
public class SceneController : MonoBehaviour{private static SceneController _instance;private DiskFactory diskFactory= DiskFactory.getInstance();private GameObject disk;private GameState gamestate = GameState.BEFORESTART;private ScoreRecorder scoreRecorder = new ScoreRecorder();private int cout=0;private float time = 0;public static SceneController getInstance(){if(_instance == null){_instance = new SceneController();}return _instance;}void Awake () {_instance = this;_instance.gamestate = GameState.END;}// Update is called once per framevoid Update () {int count =diskFactory.updateList();scoreRecorder.subScore(count);}public void emitDisk(){if (gamestate == GameState.BEFORESTART){}else if (gamestate == GameState.ROUND1){disk = diskFactory.getDiskObject();float x = Random.Range(0.1f, 1);float y = Random.Range(-1, 1)/10;float z = Random.Range(0.1f, 1);disk.GetComponent<GameModel>().setColor(selectColor());disk.GetComponent<GameModel>().setEmitPosition(new Vector3(-8, 0, 5));disk.GetComponent<GameModel>().setEmitDirection(new Vector3(x, y, z));}else if(gamestate == GameState.ROUND2){disk = diskFactory.getDiskObject();float x = Random.Range(-0.8f, 1);float y = Random.Range(-1, 1) / 10;float z = Random.Range(0.1f, 1);disk.GetComponent<GameModel>().setColor(selectColor());disk.GetComponent<GameModel>().setEmitPosition(new Vector3(-8, 0, 5));disk.GetComponent<GameModel>().setEmitDirection(new Vector3(x, y, z));}else if (gamestate == GameState.END){diskFactory.clear();scoreRecorder.resetScore();//print(cout);}}public void destroyDisk(GameObject obj){if(gamestate == GameState.ROUND1){diskFactory.removeDiskObject(obj);scoreRecorder.addScore(1);} }public void setGameState(GameState state){gamestate = state;}public GameState getGameState(){return gamestate;}public int getScore(){return scoreRecorder.getScore();}private Color selectColor(){int randomNumber = Random.Range(0, 5);Color color=Color.green;switch (randomNumber){case 0:color = Color.red;break;case 1:color = Color.blue;break;case 2: color = Color.green;break;case 3: color = Color.yellow;break;case 4: color = Color.grey;break;}return color;}public int getRound(){int round=0;switch (gamestate){case GameState.ROUND1:round = 1;break;case GameState.ROUND2:round = 2;break;}return round;}}
- UI类:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class UI : MonoBehaviour {private SceneController sceneController = SceneController.getInstance();// Use this for initializationvoid Start () {}private void Update(){if (Input.GetKeyDown("space")){sceneController.emitDisk();}if (Input.GetMouseButtonDown(0)){Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hit;if(Physics.Raycast(ray,out hit)){if(hit.transform.tag == "Disk"){sceneController.destroyDisk(hit.collider.gameObject);}}}}private void OnGUI(){GUIStyle fontStyle = new GUIStyle();fontStyle.fontSize = 25;fontStyle.normal.textColor = new Color(0, 0, 0);if (GUI.Button(new Rect(0, 0, 100, 40), "Round1")){sceneController.setGameState(GameState.ROUND1);}else if(GUI.Button(new Rect(0, 42, 100, 40), "Round2")){sceneController.setGameState(GameState.ROUND2);}else if(GUI.Button(new Rect(0, 84, 100, 40), "End")){sceneController.setGameState(GameState.END);}GUI.Label(new Rect(Screen.width / 3, 0, 100, 50), "Round: " + sceneController.getRound(), fontStyle);GUI.Label(new Rect(Screen.width/3+150 , 0, 100, 50), "Score: " + sceneController.getScore(), fontStyle);if (sceneController.getGameState() == GameState.END){if(GUI.Button(new Rect(Screen.width / 3, Screen.height / 3, 150, 80), "GameOver!\nEnter")){sceneController.setGameState(GameState.BEFORESTART);}}}
}
小结:
- 我只是将自己学到的一点东西分享一下,可参考度不高,如果要参考建议还是看大神写的博客,我还有很多很多要改要学习要改进的地方,希望自己后面能学得更好
(实训+3d+现操+计组已经够忙的了,每天都能看到深夜的月亮。。。)
Unity3D学习之路Homework4—— 飞碟射击游戏相关推荐
- Unity3d学习之路-牧师与魔鬼
Unity3d学习之路-牧师与魔鬼 游戏基本介绍 游戏规则: Priests and Devils is a puzzle game in which you will help the Priest ...
- Unity3D学习笔记(6)—— 飞碟射击游戏
游戏规则: 游戏分多个回合,每个回合有N个飞碟,玩家按空格后,321倒数3秒,飞碟飞出,点击鼠标,子弹飞出.飞碟落地或被击中,则准备下一次射击.每回合飞碟的大小.颜色.发射位置.发射角度.每次发射的数 ...
- Unity3D学习之路——AI小坦克
Unity3D学习之路--AI小坦克 作业要求: 坦克对战游戏 AI 设计 从商店下载游戏:"Kawaii" Tank 或 其他坦克模型,构建 AI 对战坦克.具体要求 使用&qu ...
- 视频教程-Unity3D实战入门之第三人称射击游戏(TPS)-Unity3D
Unity3D实战入门之第三人称射击游戏(TPS) 6年程序开发经验,精通C/C++/C#编程. 曾担任过Unity3d游戏开发主程和Unity3d游戏开发讲师,熟悉Unity3d的UI系统.物理引擎 ...
- Unity3D实战入门之第三人称射击游戏(TPS)-伍晓波-专题视频课程
Unity3D实战入门之第三人称射击游戏(TPS)-327人已学习 课程介绍 这是一套第三人称射击游戏开发的入门基础课程. 本课程以一款小型的第三人称射击游戏为案例,手把手教你如何搭建 ...
- Unity3D FPS Game:第一人称射击游戏(一)
耗时一周制作的第一人称射击游戏,希望能帮助到大家! 由于代码较多,分为三篇展示,感兴趣的朋友们可以点击查看! Unity3D FPS Game:第一人称射击游戏(一) Unity3D FPS Game ...
- Unity3D FPS Game:第一人称射击游戏(二)
耗时一周制作的第一人称射击游戏,希望能帮助到大家! 由于代码较多,分为三篇展示,感兴趣的朋友们可以点击查看! Unity3D FPS Game:第一人称射击游戏(一) Unity3D FPS Game ...
- Unity3D FPS Game:第一人称射击游戏(三)
耗时一周制作的第一人称射击游戏,希望能帮助到大家! 由于代码较多,分为三篇展示,感兴趣的朋友们可以点击查看! Unity3D FPS Game:第一人称射击游戏(一) Unity3D FPS Game ...
- 【181018】基于MFC文档方式制作的飞碟射击游戏
一款使用MFC文档方式编写的飞碟射击游戏,如上面截图所示,源码VC 6.0下编译通过. 源码下载地址:点击下载 备用下载地址:点击下载
最新文章
- 判断两个list集合里的对象某个属性值是否一样_第七章 集合框架
- linux 批量部署 pdf,Linux服务之批量部署篇
- JavaOne 2012:调查JVM水晶球
- Python中的字符串方法
- hibernate一级缓存_Hibernate缓存–一级缓存
- Vert.x 之 HelloWorld
- c#WPF 扫雷游戏
- 从二进制格雷码到任意进制格雷码(1)
- 用计算机制作一张家庭年收支表,简洁明了的家庭收支记账表格
- 内存(主存)(一般指电脑内存条)包含RAM(SRAM,DRAM),ROM,高速缓存(CACHE),SDRAM,DDRRAM
- Linux查看公网IP和私网(内网)IP的方法
- WP-2021绿盟杯-藏宝图
- 关系型数据库设计原则
- Scapy3.0 Documentation ( Advanced usage )
- peewee的使用与异步peewee-async在tornado中的使用总结
- 按键,触摸屏流程分析
- 解决右键点击文件反应很慢 (可解决文件夹,以及各种exe,快捷方式,图片,txt等文件) 【亲测有效】
- php exec pdfbox 方块,Windows explorer hangs up FTP connection after PASV command
- tomcat是什么?简单解释
- chrome浏览器主页被劫持
热门文章
- cod12正版链接在线服务器6,cod6盗版服务器管理命令(Cod6 pirated server management commands).doc...
- 覆盖常见四大应用场景,华为云CDN能够更好满足企业业务加速需求
- 机器学习——EM和GMM(基于李航老师的推导)
- 李航《统计学习方法》第二版 实战(mnist为例)
- 植物大战僵尸经典android,植物大战僵尸经典版
- 大根堆、小根堆(数组模拟操作)
- POJ 2395 Out of Hay 最小生成树(prime算法)
- 采购申请、采购订单、供应商
- multiset upper_bound() 与 lower_bound()
- android 查看设备 x86,有了它 x86安卓设备就能用Windows软件了