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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

unity实现鼠标打飞碟(Hit UFO)游戏

發布時間:2023/12/3 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 unity实现鼠标打飞碟(Hit UFO)游戏 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

unity實現鼠標打飛碟(Hit UFO)游戲

游戲規則及要求

規則:玩家初始有5條生命,每漏過一個飛碟,生命減一。游戲分數的增加與命中飛碟時的位置有關,越早擊中飛碟分數越高。游戲有四檔難度,隨分數遞增。
要求:

  • 使用帶緩存的工廠模式管理不同飛碟的生產與回收,該工廠必須是場景單實例的!具體實現見參考資源 Singleton 模板類
  • 近可能使用前面 MVC 結構實現人機交互與游戲模型分離

UML類圖

代碼框架

基本沿用了牧師與魔鬼的框架,主要增加了場景單實例和飛碟工廠類。

代碼分析

與牧師與魔鬼2.0版本類似,將所有動作管理類合并成一個C#文件。許多類與之前的代碼類似,主要說明不同的部分。

  • CCMoveToAction(管理飛碟飛行的動作)
public class CCMoveToAction : SSAction {public float Power = 10;//這個代表發射時的速度public float Angle = 45;//發射的角度public float Gravity = -10;//重力加速度private Vector3 MoveSpeed;//初速度private Vector3 GritySpeed = Vector3.zero;//重力的速度向量,t時為0private float dTime;//已經過去的時間private Vector3 currentAngle;public DiskFactory diskfactory;public UserGUI User;public static CCMoveToAction GetSSAction(float Power,float Angle,float Gravity,Vector3 MoveSpeed){CCMoveToAction action = ScriptableObject.CreateInstance<CCMoveToAction>();action.Power = Power;action.Angle = Angle;action.Gravity = Gravity;action.MoveSpeed = MoveSpeed;return action;}public override void Update(){GritySpeed.y = Gravity * (dTime += Time.fixedDeltaTime);transform.position += (MoveSpeed + GritySpeed) * Time.fixedDeltaTime;currentAngle.z = Mathf.Atan((MoveSpeed.y + GritySpeed.y) / MoveSpeed.x) * Mathf.Rad2Deg;transform.eulerAngles = currentAngle;if(this.transform.position.y < -7 || this.transform.position.x > 10){if(this.transform.position.x > 0 && User.HP > 0) User.HP--;diskfactory.FreeDisk(this.gameobject);this.destroy = true;this.callback.SSActionEvent(this);}}public override void Start(){//User = gameObject.AddComponent<UserGUI>() as UserGUI;MoveSpeed = Quaternion.Euler(new Vector3(0, 0, Angle)) * Vector3.right * Power;currentAngle = Vector3.zero;diskfactory = Singleton<DiskFactory>.Instance;User = Singleton<UserGUI>.Instance;} }

按照飛碟的初始速度、所受到的重力、初始角度,控制飛碟飛行動作。當飛碟飛出屏幕時,表示飛碟飛行動作已做完,回收飛碟。

  • MySceneActionManager(飛碟的動作管理類,通過調用該類中的方法使得飛碟飛行)
public class MySceneActionManager : SSActionManager {private CCMoveToAction diskfly;public Controll sceneController;protected new void Start(){sceneController = (Controll)SSDirector.GetInstance().CurrentScenceController;sceneController.actionManager = this;}public void fly_disk(Disk disk){diskfly = CCMoveToAction.GetSSAction(disk.Power,disk.Angle,disk.Gravity,disk.MoveSpeed);this.RunAction(disk.getGameObject(), diskfly, this);} }
  • Singleton(場景單實例,可以為每個 MonoBehaviour子類創建一個對象的實例)
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour {protected static T instance;public static T Instance{get{if (instance == null){instance = (T)FindObjectOfType(typeof(T));if (instance == null){Debug.LogError("An instance of " + typeof(T)+ " is needed in the scene, but there is none.");}}return instance;}} }

場景單實例的使用很簡單,僅需要將 MonoBehaviour 子類對象掛載任何一個游戲對象上即可。然后在任意位置使用代碼 Singleton< YourMonoType >.Instance 獲得該對象。

  • DiskFactory
    飛碟工廠類,控制飛碟的產生和回收,當場景控制器需要飛碟時,
    飛碟工廠從空閑飛碟列表中尋找飛碟傳遞給場景控制器,若空閑列表中無飛碟,則飛碟工廠需要產生一個新的飛碟。當飛碟飛出屏幕或被打擊后,會調用飛碟工廠回收飛碟的方法。通過工廠類,可以管理不同飛碟的發送和回收
using System.Collections; using System.Collections.Generic; using UnityEngine;public class DiskFactory : MonoBehaviour {//public Disk disk_prefab = null; //飛碟預制體public List<Disk> used = new List<Disk>(); //正在被使用的飛碟列表public List<Disk> free = new List<Disk>(); //空閑的飛碟列表public Disk GetDisk(){Disk disk_prefab = null;int rand = Random.Range(0, 99);if (free.Count > 10){disk_prefab = free[0];disk_prefab.getGameObject().SetActive(true);//disk_prefab.getGameObject().transform.position = new Vector3(-10,0,0);free.Remove(free[0]);}else {if (rand % 4 == 0){disk_prefab = new Disk("disk1");}else if(rand % 4 == 1){disk_prefab = new Disk("disk2");}else if(rand % 4 == 2){disk_prefab = new Disk("disk3");}else{disk_prefab = new Disk("disk4");}}used.Add(disk_prefab);return disk_prefab;}//回收飛碟public void ResetDisk(Disk disk){disk.Power = 0;disk.Angle = 0;disk.Gravity = 0;}public void FreeDisk(GameObject disk){for(int i = 0;i < used.Count; i++){if (disk.GetInstanceID() == used[i].getGameObject().GetInstanceID()){ResetDisk(used[i]);used[i].getGameObject().SetActive(false);free.Add(used[i]);used.Remove(used[i]);break;}}} }
  • Disk(飛碟類)
    定義了飛碟所擁有的各項屬性,包括受到的力度、飛行角度、所受重力和移動速度。
public class Disk{public GameObject disk; //射擊此飛碟得分public float Power = 3;public float Angle = 15;public float Gravity = -0.5f;public Vector3 MoveSpeed;public Disk(string name){if(name == "disk1"){disk = Object.Instantiate(Resources.Load("disk1", typeof(GameObject)), new Vector3(-10,0,0), Quaternion.Euler(0, -90, 0)) as GameObject;}else if(name == "disk2"){disk = Object.Instantiate(Resources.Load("disk2", typeof(GameObject)), new Vector3(-10,0,0), Quaternion.Euler(0, -90, 0)) as GameObject;}else if(name == "disk3"){disk = Object.Instantiate(Resources.Load("disk3", typeof(GameObject)), new Vector3(-10,0,0), Quaternion.Euler(0, -90, 0)) as GameObject;}else if(name == "disk4"){disk = Object.Instantiate(Resources.Load("disk4", typeof(GameObject)), new Vector3(-10,0,0), Quaternion.Euler(0, -90, 0)) as GameObject;}}public GameObject getGameObject() { return disk; }}
  • Controll 場景控制器
    場景控制器通過設置游戲狀態和游戲所進行的輪數從而控制飛碟的發送頻率、一次發送所發送飛碟的個數和飛碟的屬性。游戲每達到10分難度就會提升一檔,總共有四檔難度,飛碟的發送頻率、速度、角度的變化幅度、發送位置的變化幅度都會隨著難度的提升而提升。當游戲進入第四檔時,則會一次發送兩個飛碟。
    通過射線來判斷飛碟是否被擊中,若擊中飛碟,則得分增加,否則若飛碟飛出屏幕,則生命會減少。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Controll : MonoBehaviour,ISceneController,IUserAction {private int gamestate = 0; // 0 游戲未開始,1 游戲進行 ,2 游戲開始private int round = 1;private int score = 0;private float time = 2f;private float i = 0;public UserGUI User;public MySceneActionManager actionManager;//public Disk disk;public DiskFactory diskfactory;void Start(){SSDirector director = SSDirector.GetInstance();director.CurrentScenceController = this;User = gameObject.AddComponent<UserGUI>() as UserGUI;diskfactory = Singleton<DiskFactory>.Instance;actionManager = gameObject.AddComponent<MySceneActionManager>() as MySceneActionManager;//LoadResources();}void Update(){if (gamestate == 2){gamestate = 1;}if (gamestate == 1){if (i >= time){ if (score > 10 && round == 1){time -= 0.3f;round = 2;}else if(score > 20 && round == 2){time -= 0.5f;round = 3;}else if(score > 30 && round == 3){time += 0.3f;round = 4;}SendDisk();i = 0;}i += Time.deltaTime;}}public void LoadResources(){}public void SendDisk(){Disk disk = diskfactory.GetDisk();if (round == 1){disk.Power = Random.Range(2.5f, 3.5f);disk.Angle = Random.Range(10f, 30f);disk.Gravity = Random.Range(-0.5f, -0.8f);disk.disk.transform.position = new Vector3(-10,Random.Range(-3f, 2f),0);}else if (round == 2){disk.Power = Random.Range(3.5f, 5f);disk.Angle = Random.Range(5f, 35f);disk.Gravity = Random.Range(-0.6f, -1f);disk.disk.transform.position = new Vector3(-10,Random.Range(-4f, 1f),0);}else if (round == 3){disk.Power = Random.Range(5.5f, 8f);disk.Angle = Random.Range(5f, 35f);disk.Gravity = Random.Range(-1f, -1.5f);disk.disk.transform.position = new Vector3(-10,Random.Range(-5f, 3f),0);}else if (round == 4){disk.Power = Random.Range(7f, 10f);disk.Angle = Random.Range(5f, 35f);disk.Gravity = Random.Range(-2f, -2.5f);disk.disk.transform.position = new Vector3(-10,Random.Range(-5f, 2f),0);Disk disk2 = diskfactory.GetDisk();disk2.Power = Random.Range(6f, 8f);disk2.Angle = Random.Range(5f, 35f);disk2.Gravity = Random.Range(-1f, -3f);disk2.disk.transform.position = new Vector3(-10,Random.Range(-4.5f, 1f),0);actionManager.fly_disk(disk2);}actionManager.fly_disk(disk);}public void Restart(){score = 0;gamestate = 2;}public void Stopgame(){gamestate = 0;round = 1;time = 2f;}public void Startgame(){gamestate = 2;}public bool Hit(){Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hit;if (Physics.Raycast(ray, out hit)) {if(hit.collider.gameObject.transform.position.x < 3 && gamestate > 0)score+=2;else if(hit.collider.gameObject.transform.position.x >= 3 && gamestate > 0) score+=1;hit.collider.gameObject.transform.position = new Vector3(-10, -11, 0);diskfactory.FreeDisk(hit.collider.gameObject);return true;}return false;}public int Getscore(){return score;} }
  • UserGui (用戶界面)
using System.Collections; using System.Collections.Generic; using UnityEngine;public class UserGUI : MonoBehaviour {private IUserAction action;private bool gamestart = false;public int HP = 5;void Start(){action = SSDirector.GetInstance().CurrentScenceController as IUserAction;}void OnGUI(){ GUIStyle fontStyle2 = new GUIStyle();fontStyle2.fontSize = 20;fontStyle2.normal.textColor= new Color(1, 1, 1);GUIStyle fontStyle1 = new GUIStyle();fontStyle1.fontSize = 20;if(GUI.Button (new Rect (Screen.width-100, Screen.height-100, 65, 65), "Exit")){Application.Quit();}if(gamestart == false){GUI.Label(new Rect(Screen.width / 2 - 300, 100, 420, 50), "游戲目標:盡可能的射擊多的飛碟", fontStyle2);GUI.Label(new Rect(Screen.width / 2 - 300, 150, 420, 50), "游戲難度會逐漸提升,祝君好運!", fontStyle2);if (GUI.Button(new Rect(Screen.width / 2 - 40, Screen.height-200, 70, 40), "start")){action.Startgame();gamestart = true;}}else{GUI.Label(new Rect(Screen.width / 2 - 300, 10, 420, 50), "分數:", fontStyle1);GUI.Label(new Rect(Screen.width / 2 - 250, 10, 420, 50), action.Getscore().ToString(), fontStyle1);GUI.Label(new Rect(Screen.width / 2 - 300, 40, 420, 50), "剩余血量:", fontStyle1);GUI.Label(new Rect(Screen.width / 2 - 210, 40, 420, 50), HP.ToString(), fontStyle1);}if (Input.GetButtonDown("Fire1")) {action.Hit();}if (HP <= 0){GUI.Label(new Rect(Screen.width / 2 - 50, 150, 60, 40), "Game Over!", fontStyle1);action.Stopgame();if (GUI.Button(new Rect(Screen.width / 2 - 40, Screen.height-200, 70, 40), "Restart")){action.Restart();HP = 5;}} } }

游戲截圖



視頻鏈接
項目代碼

總結

以上是生活随笔為你收集整理的unity实现鼠标打飞碟(Hit UFO)游戏的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。