title: c# GameDesigner2 description: published: true date: 2022-10-05T12:14:46.146Z tags: editor: markdown dateCreated: 2022-10-05T07:57:15.455Z # 地址 ...
--- title: c# GameDesigner2 description: published: true date: 2022-10-05T12:14:46.146Z tags: editor: markdown dateCreated: 2022-10-05T07:57:15.455Z --- # 地址 [GitHub地址:https://github.com/AlbertGarcia0219/GameDesigner2](https://github.com/AlbertGarcia0219/GameDesigner2) [Gitee地址:https://gitee.com/KiwiSenpaii/game-designer2](https://gitee.com/KiwiSenpaii/game-designer2) # 目的 我是前端菜鳥,嘗試學習後端的繼承,線程等思想。 # 設計 一個線程負責設計,一個線程負責模擬運行。 1. 模仿Unity游戲引擎,游戲引擎有兩個生命周期鉤子,`Start()`和`Update()`,其中`Start()`只在視窗打開時執行執行一次,`Update()`的執行次數要看CPU的能力了。根據`Unity.testFPS()`的測試,在沒有線程休眠的情況下,極限是每秒58幀。 2. 儘量將邏輯分開,窗體邏輯作為主線程,接收鍵鼠事件。`GameMainThread`是游戲的線程,負責模擬游戲的運行。 3. `Form1`只負責窗體的邏輯,不負責游戲的邏輯,例如打開彈出框,選擇材料等。`Unity`是游戲的引擎,把所有與游戲相關的邏輯放在`Unity`中,例如創建敵人,摧毀牆等。這樣在Coding的時候邏輯更清晰,擴展性更好,利於代碼維護。
# 代碼 ## 繼承 左側是類,右側是線程 ![](./img1.jpg) 游戲主要使用到的類 1. `GameObject`抽象類 > 坐標,寬高,圖片,幀函數,碰撞演算法,繪製自身 2. `Stationary` > 實現父類抽象方法`GetImg`,設置寬高,並無子類,圖中子類不過是換了圖片和游戲數據。 3. `Active` > 新增方向,速度,移動和碰撞檢測函數 4. `Active`子類 > 重寫父類幀函數,重寫碰撞檢測等等
## 游戲數據和List的關係 List存儲了實際的游戲對象,用來遍歷。 GameData是對游戲當前數據的映射,1是wall(牆),2是wall2(不可破壞的牆)等等,參考`Unity`的游戲設計模塊。
**繼承雖然可以很好地復用代碼,但是同時會破壞封裝。假設子類的某個函數使用到了父類的某個函數或者屬性,一旦父類修改代碼,子類幾乎是必定要修改代碼,破壞了封裝反而會增加維護成本。最好的辦法是用介面+組合** ## 碰撞檢測 這次採用了比屏保泡泡更好的碰撞檢測,用`Active`運動的下一幀的位置,也就是未來的位置來判斷是否碰撞,省去了屏保泡泡碰撞之後將兩個泡泡分開的步驟。 ## 游戲數據 用二維數組做一個映射,並不根據二維數組渲染頁面,用List存儲實際的對象。 ## MoveCheck 其實更應當作為一個抽象方法。 ## 線程鎖 因為多線程會出現兩個線程同時操作同一資源的情況,需要上鎖。 # 補充 1. 不能在遍歷的一個`List`的同時去刪除`List`中的元素。 # 缺陷 1. 游戲聲音無法重合,無論 new 多少個`SoundPlayer`都只能同時播放一個音頻。 > 嘗試使用多線程播放多個音頻,失敗。 2. 後期邏輯不清晰。Unity引擎同時負責了模擬游戲和設計游戲,耦合性太強,沒有用泛型,復用性差。