日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

游戏开发之Unity学习(五)——鼠标打飞碟(Hit UFO)

發(fā)布時(shí)間:2023/12/3 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 游戏开发之Unity学习(五)——鼠标打飞碟(Hit UFO) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、游戲內(nèi)容要求:

  • 游戲有 n 個(gè) round,每個(gè) round 都包括10 次 trial;
  • 每個(gè) trial 的飛碟的色彩、大小、發(fā)射位置、速度、角度、同時(shí)出現(xiàn)的個(gè)數(shù)都可能不同。它們由該 round 的 ruler 控制;
  • 每個(gè) trial 的飛碟有隨機(jī)性,總體難度隨 round 上升;
  • 鼠標(biāo)點(diǎn)中得分,得分規(guī)則按色彩、大小、速度不同計(jì)算,規(guī)則可自由設(shè)定。

二、游戲的要求:

  • 使用帶緩存的工廠模式管理不同飛碟的生產(chǎn)與回收,該工廠必須是場(chǎng)景單實(shí)例的!
  • 使用 MVC 結(jié)構(gòu)實(shí)現(xiàn)人機(jī)交互與游戲模型分離

三、游戲的實(shí)現(xiàn)


之前的幾個(gè)博客已經(jīng)構(gòu)建好了一個(gè)較為完整的MVC框架,這里可以套用之前的框架。看上面的UML圖就能了解到
游戲結(jié)構(gòu)和上一個(gè)游戲基本沒有不同,僅僅添加了一個(gè)飛碟工廠!!!
其實(shí)不加這個(gè)也可以實(shí)現(xiàn)這一個(gè)游戲,但是為什么要加上這個(gè)飛碟工廠呢?
這是因?yàn)榧由蠈?duì)象的構(gòu)建和銷毀都是很耗資源的,這個(gè)工廠能夠讓我們有效的利用已經(jīng)構(gòu)造好的游戲?qū)ο髞韺?shí)現(xiàn)資源的重利用,從而減少資源開銷
那么,先看看這個(gè)工廠是如何實(shí)現(xiàn)的:

using System.Collections.Generic; using UnityEngine;public class DiskFactory : MonoBehaviour {public List<GameObject> used = new List<GameObject>();public List<GameObject> free = new List<GameObject>();// Use this for initializationvoid Start () { }public void GenDisk(){GameObject disk;if(free.Count == 0){disk = Instantiate<GameObject>(Resources.Load<GameObject>("Prefabs/Disk"), Vector3.zero, Quaternion.identity);}else{disk = free[0];free.RemoveAt(0);}float x = Random.Range(-10.0f, 10.0f);disk.transform.position = new Vector3(x, 0, 0);disk.transform.Rotate(new Vector3(x < 0? -x*9 : x*9, 0, 0));float r = Random.Range(0f, 1f);float g = Random.Range(0f, 1f);float b = Random.Range(0f, 1f);Color color = new Color(r, g, b);disk.transform.GetComponent<Renderer>().material.color = color;used.Add(disk);}public void RecycleDisk(GameObject obj){obj.transform.position = Vector3.zero;free.Add(obj);} }

這里的used和free分別表示已經(jīng)在使用的和未被利用的飛碟對(duì)象,如果free的列表為空,而我們有需要它,這時(shí)才創(chuàng)建新的對(duì)象,不然,就用之前的。好了,這就是飛碟工廠,然后我們看場(chǎng)景控制器如何利用這個(gè)工廠。

using UnityEngine; using UnityEngine.SceneManagement;public class FirstSceneController : MonoBehaviour, IUserAction, ISceneController{public CCActionManager actionManager;public GameObject disk;protected DiskFactory df;public int flag = 0;private float interval = 3;public int score = 0;public static int times = 0;private void Awake(){SSDirector director = SSDirector.getInstance();director.setFPS(60);director.currentSceneController = this;this.gameObject.AddComponent<DiskFactory>();this.gameObject.AddComponent<CCActionManager>();this.gameObject.AddComponent<UserGUI>();df = Singleton<DiskFactory>.Instance;//director.currentSceneController.GenGameObjects();}private void Start(){}public void GenGameObjects (){}public void Restart(){SceneManager.LoadScene("1");}public void Pause (){actionManager.Pause();}public void Update(){if (times < 30 && flag == 0){if (interval <= 0){interval = Random.Range(3, 5);times++;df.GenDisk();}interval -= Time.deltaTime;}} }

場(chǎng)景控制器是需要重寫的一個(gè)類,因?yàn)樗怯螒驅(qū)ο笊傻?#xff0c;顯然之前的場(chǎng)景控制器在這里完全用不上當(dāng)然由于之前MVC架構(gòu)的分離作用,這里也僅需要改Awake,Update,GenGameObject這三個(gè)函數(shù)和各種變量。
然后動(dòng)作管理器是需要重寫動(dòng)作的,而動(dòng)作在這里需要的改動(dòng)較小,只需要改MoveToAction就行了,不過為了更好的控制飛碟,這里的動(dòng)作將變成一個(gè)列表,這是為了能夠同時(shí)控制多個(gè)飛碟在游戲中飛行。

using System.Collections; using System.Collections.Generic; using UnityEngine;public class CCActionManager : SSActionManager, ISSActionCallback {public FirstSceneController sceneController;public List<CCMoveToAction> seq = new List<CCMoveToAction>();public UserClickAction userClickAction;public DiskFactory disks;protected new void Start(){sceneController = (FirstSceneController)SSDirector.getInstance().currentSceneController;sceneController.actionManager = this;disks = Singleton<DiskFactory>.Instance;}protected new void Update(){if(disks.used.Count > 0){GameObject disk = disks.used[0];float x = Random.Range(-10, 10);CCMoveToAction moveToAction = CCMoveToAction.GetSSAction(new Vector3(x, 12, 0), 3 * (Mathf.CeilToInt(FirstSceneController.times / 10) + 1) * Time.deltaTime);seq.Add(moveToAction);this.RunAction(disk, moveToAction, this);disks.used.RemoveAt(0);}if (Input.GetMouseButtonDown(0) && sceneController.flag == 0){Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hitGameObject;if (Physics.Raycast(ray, out hitGameObject)){GameObject gameObject = hitGameObject.collider.gameObject;if (gameObject.tag == "disk"){foreach(var k in seq){if (k.gameObject == gameObject)k.transform.position = k.target;}userClickAction = UserClickAction.GetSSAction();this.RunAction(gameObject, userClickAction, this);}}}base.Update();}public void SSActionEvent(SSAction source, SSActionEventType events = SSActionEventType.Completed, int intParam = 0, string strParam = null, Object objParam = null){disks.RecycleDisk(source.gameObject);seq.Remove(source as CCMoveToAction);source.destory = true;if (FirstSceneController.times >= 30)sceneController.flag = 1;}public void CheckEvent(SSAction source, SSActionEventType events = SSActionEventType.Completed, int intParam = 0, string strParam = null, Object objParam = null){}public void Pause(){if(sceneController.flag == 0){foreach (var k in seq){k.enable = false;}sceneController.flag = 2;}else if(sceneController.flag == 2){foreach (var k in seq){k.enable = true;}sceneController.flag = 0;}} }

這里需要改動(dòng)的也只有那幾個(gè)函數(shù):Update,SSActionEvent,Pause函數(shù),另外幾個(gè)類的改動(dòng)更小,基本就改了一兩行代碼,在這里就不說了。如果對(duì)那些改動(dòng)感興趣的話,可以去文章末尾的鏈接看看。
下面說說用戶GUI:

using UnityEngine;public class UserGUI : MonoBehaviour {private FirstSceneController action;private GUIStyle fontstyle1 = new GUIStyle();// Use this for initializationvoid Start () {action = SSDirector.getInstance().currentSceneController as FirstSceneController;fontstyle1.fontSize = 50;}// Update is called once per frameprivate void OnGUI(){if (GUI.Button(new Rect(0, 80, 80, 60), "RESTART")){action.Restart();}if (GUI.Button(new Rect(0, 160, 80, 60), "Pause")){action.Pause();}if (action.flag == 0){fontstyle1.normal.textColor = Color.green;GUI.Label(new Rect(Screen.width / 2 - 150, 0, 300, 100), "Score: " +action.score + ", Round: " + (Mathf.CeilToInt(FirstSceneController.times / 10) + 1), fontstyle1);}else if (action.flag == 1){fontstyle1.normal.textColor = Color.red;GUI.Label(new Rect(Screen.width / 2 - 150, 0, 300, 100), "Your score is : " + action.score, fontstyle1);}else{fontstyle1.normal.textColor = Color.green;GUI.Label(new Rect(Screen.width / 2 - 150, 0, 300, 100), "Score: " +action.score + ", Round: " + (Mathf.CeilToInt(FirstSceneController.times / 10) + 1), fontstyle1);fontstyle1.normal.textColor = Color.red;GUI.Label(new Rect(Screen.width / 2 - 150, Screen.height/2-50, 300, 100), "Pause!", fontstyle1);}} }

這本身就是一個(gè)很簡(jiǎn)單的類,應(yīng)該不難看懂,因此僅貼上代碼。游戲效果圖如下(沒下什么資源,所以界面有點(diǎn)難看)

更多更詳細(xì)的內(nèi)容請(qǐng)戳:github

總結(jié)

以上是生活随笔為你收集整理的游戏开发之Unity学习(五)——鼠标打飞碟(Hit UFO)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。