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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

HW5-打飞碟

發布時間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HW5-打飞碟 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、游戲說明

飛碟游戲
游戲內容:

  • 游戲有 n 個 round,每個 round 都包括10 次 trial;
  • 每個 trial 的飛碟的色彩,大小;發射位置,速度,角 度,受該 round 的 ruler 控制;
  • 每個 trial 的飛碟有隨機性,總體難度隨 round 上升;
  • 鼠標點中得分,得分規則按色彩、大小、速度不同計算,規則可自由設定。
  • 游戲涉及的知識點:

  • 世界與屏幕坐標、射線與碰撞、動態修改shader;
  • 支持mono的單實例、游戲對象工廠、擴展游戲對象屬 性與行為的方法。
  • 二、相關知識

    1.為什么需要工廠對象

    • 游戲對象的創建與銷毀高成本,必須減少銷毀次數。如游戲中子彈
    • 屏蔽創建與銷毀的業務邏輯,使程序易于擴展

    2.diskFactory的設計

    • 前面游戲,由導演、場記、運動管理師、演員構成。
    • 新游戲中,場記請了記分員、飛碟管理員
    • 其中記分員按飛碟的數據計分,記分員擁有計分規則
    • 場記只需要管理出飛碟規則與管理碰撞就可以了

    3.帶緩存工廠模式的實現

    • getDisk(ruler) 偽代碼
      IF (free list has disk) THEN
      a_disk = remove one from list ELSE
      a_disk = clone from Prefabs
      ENDIF
      Set DiskData of a_disk with the ruler Add a_disk to used list
      Return a_disk
    • FreeDisk(disk)
      Find disk in used list
      IF (not found) THEN THROW exception Move disk from used to free list

    三、關鍵實現分析

    1.首先是飛碟信息的存儲類
    掛在飛碟上制作為預制

    //射擊當前飛碟得分public int score = 1;//飛碟顏色設置 public Color color = Color.white;//飛碟初始的位置 public Vector3 direction;//飛碟大小 public Vector3 scale = new Vector3( 1 ,0.5f, 1);

    2.飛碟工廠類
    主要有的功能為:飛碟預制的生產、飛碟的選擇、未使用飛碟的回收

    生產:

    //在空閑的飛碟列表中嘗試找到符合tag的飛碟for(int i=0;i<free.Count;i++){if(free[i].tag == tag){disk_prefab = free[i].gameObject;free.Remove(free[i]);break;}} //如果空閑列表中沒有所需求的預制飛碟,則需要生產預制飛碟if(disk_prefab == null){if (tag == "disk1"){disk_prefab = Instantiate(Resources.Load<GameObject>("Prefabs/disk1"), new Vector3(0, start_y, 0), Quaternion.identity);}else if (tag == "disk2"){disk_prefab = Instantiate(Resources.Load<GameObject>("Prefabs/disk2"), new Vector3(0, start_y, 0), Quaternion.identity);}else{disk_prefab = Instantiate(Resources.Load<GameObject>("Prefabs/disk3"), new Vector3(0, start_y, 0), Quaternion.identity);} //設定顏色、位置等屬性float ran_x = Random.Range(-1f, 1f) < 0 ? -1 : 1;disk_prefab.GetComponent<Renderer>().material.color = disk_prefab.GetComponent<DiskData>().color;disk_prefab.GetComponent<DiskData>().direction = new Vector3(ran_x, start_y, 0);disk_prefab.transform.localScale = disk_prefab.GetComponent<DiskData>().scale;} //添加到使用的列表中used.Add(disk_prefab.GetComponent<DiskData>());

    飛碟的選擇:
    不同的回合對應不同的飛碟

    if (round == 1){choice = Random.Range(0, scope1);}else if(round == 2){choice = Random.Range(0, scope2);}else{choice = Random.Range(0, scope3);}

    飛碟回收:
    未被擊中的飛碟,將其回收至空閑列表中,并將其移出正在使用的飛碟列表

    for(int i = 0;i < used.Count; i++){if (disk.GetInstanceID() == used[i].gameObject.GetInstanceID()){used[i].gameObject.SetActive(false);free.Add(used[i]);used.Remove(used[i]);break;}}

    3.場景控制FirstSceneControl類
    負責游戲場景中的各種事件的處理,以及游戲規則如游戲開始結束等的執行。
    發送飛碟的處理:

    void Update (){if(game_start){//游戲結束時取消發送飛碟if (game_over){CancelInvoke("LoadResources");}//游戲開始的判定if (!playing_game){InvokeRepeating("LoadResources", 1f, speed);playing_game = true;}SendDisk();//難度加大的配置if (score_recorder.score >= score_round2 && round == 1){round = 2;speed = speed - 0.6f;CancelInvoke("LoadResources");playing_game = false;}else if (score_recorder.score >= score_round3 && round == 2){round = 3;speed = speed - 0.5f;CancelInvoke("LoadResources");playing_game = false;}}}

    擊中飛碟的相關判斷:

    public void Hit(Vector3 pos){Ray ray = Camera.main.ScreenPointToRay(pos);RaycastHit[] hits;hits = Physics.RaycastAll(ray);bool not_hit = false;for (int i = 0; i < hits.Length; i++){RaycastHit hit = hits[i];if (hit.collider.gameObject.GetComponent<DiskData>() != null){for (int j = 0; j < disk_notshot.Count; j++){if (hit.collider.gameObject.GetInstanceID() == disk_notshot[j].gameObject.GetInstanceID()){not_hit = true;}}if(!not_hit){return;}disk_notshot.Remove(hit.collider.gameObject);score_recorder.Record(hit.collider.gameObject);Transform explode = hit.collider.gameObject.transform.GetChild(0);explode.GetComponent<ParticleSystem>().Play();StartCoroutine(WaitingParticle(0.08f, hit, disk_factory, hit.collider.gameObject));break;}}}

    回收飛碟

    IEnumerator WaitingParticle(float wait_time, RaycastHit hit, DiskFactory disk_factory, GameObject obj){yield return new WaitForSeconds(wait_time);hit.collider.gameObject.transform.position = new Vector3(0, -9, 0);disk_factory.FreeDisk(obj);}

    4.飛碟飛行動作

    public static diskFlyAction GetSSAction(Vector3 direction, float angle, float power){diskFlyAction action = CreateInstance<diskFlyAction>();if (direction.x == -1){action.start_vector = Quaternion.Euler(new Vector3(0, 0, -angle)) * Vector3.left * power;}else{action.start_vector = Quaternion.Euler(new Vector3(0, 0, angle)) * Vector3.right * power;}return action;}

    5.GUI界面渲染

    void OnGUI (){bold_style.normal.textColor = new Color(1, 0, 0);bold_style.fontSize = 16;text_style.normal.textColor = new Color(0,0,0, 1);text_style.fontSize = 16;score_style.normal.textColor = new Color(1,0,1,1);score_style.fontSize = 16;over_style.normal.textColor = new Color(1, 0, 0);over_style.fontSize = 25;if (game_start){if (Input.GetButtonDown("Fire1")){Vector3 pos = Input.mousePosition;action.Hit(pos);}GUI.Label(new Rect(10, 5, 200, 50), "分數:", text_style);GUI.Label(new Rect(55, 5, 200, 50), action.GetScore().ToString(), score_style);GUI.Label(new Rect(Screen.width - 120, 5, 50, 50), "血量:", text_style);//顯示血量for (int i = 0; i < life; i++){GUI.Label(new Rect(Screen.width - 75 + 10 * i, 5, 50, 50), "+", bold_style);}if (life == 0){high_score = high_score > action.GetScore() ? high_score : action.GetScore();GUI.Label(new Rect(Screen.width / 2 - 20, Screen.width / 2 - 250, 100, 100), "游戲結束", over_style);GUI.Label(new Rect(Screen.width / 2 - 10, Screen.width / 2 - 200, 50, 50), "你獲得的分數:", text_style);GUI.Label(new Rect(Screen.width / 2 + 50, Screen.width / 2 - 200, 50, 50), high_score.ToString(), text_style);if (GUI.Button(new Rect(Screen.width / 2 - 20, Screen.width / 2 - 150, 100, 50), "重新開始")){life = 6;action.ReStart();return;}action.GameOver();}}else{if (GUI.Button(new Rect(Screen.width / 2 - 20, Screen.width / 2-290, 100, 50), "開始游戲")){game_start = true;action.BeginGame();}}}

    四、成品


    視頻
    最后感謝師兄的博客給了很大的幫助!不然真的很難實現。

    總結

    以上是生活随笔為你收集整理的HW5-打飞碟的全部內容,希望文章能夠幫你解決所遇到的問題。

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