java 3d游戏_不放一行代码分享一下java实现3D游戏逻辑
這篇日記是對最近幾周Java大作業寫的一個3D打怪挖礦游戲進行記錄和總結。另一個目的也是因為我發現身邊很多朋友對3D游戲邏輯很有興趣。所以寫這篇日記可以介紹一下一個3D游戲是如何實現基礎功能的。即使沒有Java或者編程基礎的人,我相信也可以通過這篇文章了解到if和for的有趣。
我們Java課的游戲要求是寫一個2D物語小游戲,有打怪和挖礦石的情節,因為遇到一個獅子座組長,提出我們可以做一個3D游戲。
我的分工是寫游戲邏輯,因為組員和自己對自己邏輯思維的謎之自信,我就上路了。在學習的過程中,我們發現3D游戲用java寫的帖子很少,也只有一個簡單的教程,基本實現的功能就是小球砸墻。
我寫的是simple application格式,接入我們整個的游戲是要換成appstate格式,我就用simple application格式介紹了。
這個游戲主邏輯可以看成兩部分,一個是初始化(init),一個是更新(update)。
初始化可以理解成在游戲一開始就加載到場景中的東西。光照、場景、天、水我就不多解釋。玩家我們使用的是膠囊體沒有使用人物模型,因為膠囊體比較方便做碰撞檢測。碰撞檢測就是檢測兩個物體是否碰撞了。我們用的是第一視角,還有一種是第三視角。實現的差別就是,第一人稱鏡頭位置就是玩家位置,你可以理解成,玩家是一個竹竿,上面有一個鏡頭。而第三視角人物是在鏡頭前面,人移動,再去控制鏡頭相同位置移動,顯然,第一視角更好實現。我們實現的就是第一視角。
按鍵初始化可以理解成把鍵盤上的一個按鍵或者鼠標按鍵和程序中的一個變量聯系起來,當這個鍵按下,那對應的程序里的那個變量就變成True.(具體實現是把一個按鍵觸發器和inputManager建立映射,再將映射注冊到監聽器中,最后在監聽器中實現監聽)。
怪獸初始化,你可以這么理解,我們得先創建一個spatial(空間),加載一個怪獸模型給這個空間,然后給這個spatial增加材質(material and texture)。給這個怪物一些物理性質,比如給它加質量加重力加速度。然后再把這個怪物放到物理引擎下,再放到這個場景中。放到場景中是附加(attach),對應,讓這個消失,就把這個怪物從場景中detach。舉個例子,就是一個面團上有一些豆子,你把新的豆子按上去,和把一個豆子取下來。
初始化的時候還可以給怪獸加動畫,但是動畫是原地加的,如果想要這個怪物四處走動,你需要先設置好一個路徑,讓怪物沿著這個路徑走動不斷循環。寫路徑要首先定好點的位置,把點連起來就是路徑,最簡單的就是在兩點之間連上直線了。
下面這張圖是當時我調試的時候截的圖,不清楚,但是可以看到那個紅點和藍色連線。
有一個有趣的問題是,因為路徑固定下來,怪物就在一個平面上走,而地圖是高低不平的,所以你看到怪物可能在水面上走,在天上走,在地里走(地面不平,穿模),所以,配一個合適的高度很重要。但是如果沒有路徑,怪獸不走動,原地做動畫。怪物會從一個較高高度自由落體到地面,不會穿模。但是看起來會是一個瞄準射擊游戲,而不是一個打怪游戲了。
另一大塊是update部分,這一部分,系統會每隔一幀的時間去檢查有沒有變化,對應變化更新界面。
首先是時間。這個時間指總的時間,因為我們游戲寫了四個地圖,而我此處只是介紹一個地圖,所以我需要一個時間在這個地圖之外。我是通過系統時間實現的,游戲開始時記錄當時的系統時間,等到游戲過程中,需要這個時刻是檢查是白天還是夜晚了,再去調當時的系統時間減去初始系統時間,換算當時的白天黑夜。
人物移動和前面說的監聽器相關,監聽到按鍵按下,就改變一個變量值,比如“left”就由負變正了。然后再把這個信息傳給玩家的走動功能代碼,玩家就實現了走動。
相同的道理有按一個鍵,背包、地圖界面就跳出來。按一個鍵,就觸發玩家發射一個小球。為了攻擊怪物,就是給這個小球(幾何體)一個初速度、重力還有發射方向(鏡頭方向)。發出去就像人往前拋球的視角,去撞擊怪物。
小球撞擊到怪物就要做一個碰撞檢測,檢測到有碰撞發生,怪物就掉血。但是因為不知道是哪個小球撞擊了那個怪物,所以要建一個雙重循環,循環所有的小球和所有怪物,找到碰撞檢測結果為正的那個小球和怪物,撞擊之后,把那個小球消失(detach掉),怪物掉血完了之后,就同樣把這個怪物detach掉。在怪物死掉的地方還會生成兩個礦石,一個礦石等級是玩家攻擊力等級,一個礦石等級是怪獸等級。
怪物攻擊人會有點麻煩,一個是根據游戲設定,怪物得在一定范圍內對玩家攻擊,所以建一個循環,檢測玩家和所有的怪物距離,一旦有怪物小于一個值,怪物就往玩家投小球,但是另一個麻煩之處是,小球方向不再是調用鏡頭方向那么簡單,要算人和怪物位置連線的向量。人收到攻擊,建一個循環,檢驗所有小球和玩家的碰撞檢測,檢驗到有正值,玩家掉血。
挖礦的實現就是先做一個距離檢測,然后再計數,等在update里的時間變量加載到一個值,就把礦石detach。
因為生成的小球會在地面滾動,沒有消失,如果這個小球不消失,再碰到怪物不用你攻擊,怪物也會死。所以設置當小球的高度低于一個值,就把detach掉。
因為不能說剛開始加載的怪物打完了或者礦石撿完了,就退出地圖,一定是在游戲進行過程中繼續生成的。但是,因為不同等級的怪物和礦石生成概率不同,我處理的方式是生成隨機值,再根據隨機數區間控制生成的概率。比如0-100隨機數,如果區間劃分成0-10,10-100,那生成概率就是1:9.
上面就是實現一個游戲的基本動作啦。但是還有隱含的一塊是數據的處理。這部分可能會更枯燥一點,有一些java基礎的理解起來會更輕松,所以我把寫在了后面。
一個部分是對怪物的管理,因為我們怪物有9種,不同地圖中出現的怪物還不同,不同怪物加載的模型、貼圖、等級、位置不同。很容易想到,把怪物建一個類,然后就可以創建對象了。但是因為在這里生成怪物的spatial是和simpleApplication這個類聯系在一起的,而且最后要加載到場景中,所以不能寫出去。所以我的處理辦法是,把不能拿出去的模型留在simpleApplication 里,把和模型相關的數據拿出去重新建一個類MonsterData,最后一個怪物生成,同時生成一個spatial和一個管理數據的類。放在容器里,兩個容器的元素在存儲序號上一一對應,也就實現了spatial和數據的綁定。
還要解決的另一個問題是不同怪物加載,模型、貼圖要加載不一樣的,所以,我就把它們的存放路徑處理成字符串,用swich 和case 方法,根據等級取用模型貼圖路徑。效果就是最后四個地圖在怪物生成這個部分差別就是幾行代碼的傳入數據,實現了代碼很大的精簡。每個地圖的代碼量就控制到了650行左右。還是很有成就感的。
另一部分就是,我們數據分了幾塊,一塊是Parameter,這個類存放礦石、斧子、彈弓、怪物的變量,返回礦石、斧子、彈弓、怪物的等級,就可以返回相應的游戲變量設定。一個是Data,存儲的是這個玩家裝備的信息。一個是inGameData,存放的是玩家血和精力值信息。還有CreateMonsterData, 前面提到是怪物模型和貼圖路徑字符串信息。還有怪物數據,前面提到了,在MonsterData里存儲。
上面就是我想分享的一些經驗和設計思路了。我就不貼代碼了。如果想看代碼的,可以私戳我。
總結
以上是生活随笔為你收集整理的java 3d游戏_不放一行代码分享一下java实现3D游戏逻辑的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 戴森电动车6月进行测试 并于2021年
- 下一篇: java类似goto_原来java中也有