對比python學julia(第三章:遊戲編程)--(第四節)捕魚達人(1)

4.1.    遊戲介紹

  這是一款以深海狩獵爲題材的休閒射擊遊戲一捕魚達人。如下圖所示,在遊戲窗口中游動着各種色彩鮮豔的魚兒,一門大炮位於窗口正下方;玩家移動 鼠標指針,大炮隨之轉動;瞄準魚兒,輕點鼠標,就能發射炮彈;當炮彈擊中魚兒時,就會變成一張漁網,將魚兒收人網中並兌換成得分。

  這個遊戲輕鬆而簡單,可以讓玩家享受深海捕魚的樂趣。如果要退出遊戲程序,可以單擊窗口右上角的“關閉”按鈕。

  在編寫這個遊戲之前,可以先進行試玩,以便更好地瞭解這個遊戲需要實現的各個功能。

  源碼下載鏈接:https://files.cnblogs.com/files/zjzkiss/bydr.zip

  提示:這是初步的代碼,後續分步驟實現的時候,可能會有所修改。

4.2.    編程思路

  與前面課程中介紹的兩個小遊戲相比,這個捕魚遊戲要略爲複雜一些。這個遊戲需要實現的主要功能有:在遊戲中大炮會隨時面向鼠標指針轉動,各種魚會隨機地游來游去,當炮彈擊中魚時會顯示漁網,以及產生一枚硬幣飛到得分欄中的效果。接下來,將介紹實現這個捕魚遊戲涉及的一些主要算法。

  1. 實現高級運動控制功

  對初學者來說,在Pyglet中想要實現類似大炮跟隨鼠標指針轉動的效果,將是一件比較困難的事情。 到目前爲止,Pyglet的精靈類(pyglet.sprite. Sprite)並沒有提供讓精靈面向鼠標指針的功能.同樣,Julia的GameZero也沒有提供此功能。

  原書是在 Pyglet的精靈類的基礎上實現一個 Sprite 派生類,讓精靈(Sprite)能夠面向某個座標和沿某個方向移動指定距離的算法。但是Julia是沒有類(class)的,也不允許實體繼承的,因此不能從Actor派生新的對象。只能通過函數調用來實現。

  1)   讓角色面向某個座標

  在遊戲中,有時需要讓一個角色面向另一個角色,其實質就是確定兩個精靈的座標點連成的直線的方向。專業的說法稱爲直線定向,即確定直線與標準方向之間的角度。在測量學中,使用方位角和象限角表示直線的方向。

  方位角的定義:以座標縱軸北端爲標準方向,沿順時針方向量到某條直線的夾角,稱爲該直線的座標方位角,簡稱方位角;其角值爲0°~360°,正北爲 0°,正東爲90°,正南爲180°,正西爲270°。如原書圖 31-3 所示。

  象限角的定義:從座標縱軸的北端或南端起,沿順時針或逆時針方向量至某條直線的銳角,稱爲該直線的座標象限角,簡稱象限角;其角值爲0°~90°,爲了表示直線的方向,應分別註明北東、北西或南東、南西,如北東60°、南西 55°等。 如原書圖 31-4 所示。

  直線的方位角和象限角之間存在換算關係。象限角用R 表示,座標方位角用α表示,兩者之間的換算關係見原書表 31-1。

 

  注意: 座標象限在數學中按逆時針方向編號,而在測量學中按順時針方向編號。

  如原書圖31-5 所示,已知A點(xA,yA )和B 點( xB,yB)的座標,先利用反正切函數求得象限角RAB的值,再根據B點位於A 點的右上方判定象限角RAB位於第一象限,由此可得直線AB的方位角αAB =RAB 。同理,也可以計算出其他象限中某條直線的座標方位角。

 

  由於Pyglet 座標系的0°位於正東方向,與測量學中位於正北的標準方向相差90°,因而將上述所求得的方位角減去90°,就能得到 Pyglet 中使用的方位角。不過GameZero的座標原點是在左上角的,與Pyglet正好成鏡像,如Pyglet的90°在GameZero裏是-90°。 使用所求得的方位角來設置角色的旋轉角度,即可實現讓一個角色面向鼠標指針或其他角色所在座標。

  2)   讓精靈沿某個方向移動指定

  在遊戲中,經常需要讓角色以隨機方式運動,以獲得自然逼真的運動效果。這需要控制角色運動的方向和距離這兩個參數來實現。通過增加或減少角色的旋轉角度,就能實現讓角色向左旋轉或向右旋轉的功能。在方向確定之後,讓精靈沿着該方向往前移動指定的距離,移動後的座標可以由方位角和距離這兩個參數計算出來。

  如原書圖31-6所示,已知A點(xA,yA )沿着 方向移動一段距離D之後到達B點( xB,yB)。那麼,利用 sin 和 cos 函數就可以求得 B 點座標。

  由於 Pyglet 的方位角與測量學中的方位角相差90°因此,在計算時將方位角 加上90°再用三角函數求出B點的座標。不過由於GameZero的座標原點在左上角,因此B點座標的計算略有差別,如下圖所示:

  這樣一來,使用方向和距離這兩個參數就能讓角色實現自然逼真的隨機運動,使遊戲具有更好的體驗。

  3)   檢測角色之間是否碰撞

  在這個捕魚遊戲中,如果要判斷移動中的炮彈是否命中游動的魚,就需要檢測炮彈和魚這兩個角色之間是否產生碰撞。GameZero有專用的碰撞檢測函數,比較簡單。

  2.魚羣生成策略和魚的遊動策略

  捕魚遊戲的主要特色就是展示了多種栩栩如生的海洋魚類自由自在遊動的逼真效果。這需要設計一個魚羣生成策略,用來控制每種魚的總數和活躍數霧還需要設計一個魚的遊動算法,讓不同的魚採用不同的速度和路線以隨機方式遊。

  1)   魚的參數配置表

  在捕魚遊戲中,魚的種類多達 12 種。編程時,需要用到每種魚的總數、遊動速度、生命值、得分等多種叄數,如原書表 31-2 所示。把這些參數存放在字典(dict)類型的變量中(julia和python的字典類型基本相同),能夠極大地簡化編程工作。

  提示:除文件名和動畫行數外,其他參數可以根據個人喜好進行調整。

  2)  魚羣的生成策略

  在遊戲中,使用表 31-2 中給出的每種魚的總數目參數來控制其數量上限,避免魚羣數量過多在屏幕上造成擁擠,從而影響遊戲視覺效果。以下是這個捕魚遊戲中採用的魚羣生成策略.

  策略1: 在遊戲開始時,每種魚生成其總數的 1/2;之後,如果每種魚的數量小於其上限的 1/3 時,則把剩佘的數量補齊。

  策略2:在遊戲進行中,每隔 300s或 480s 出現一隻藍鯊或金鯊。因兩種 鯊魚體積過大且得分最高,在遊戲中使其總數量分別保持在 1 條即可。

  3)  魚的遊動策略

  在遊戲中,採用隨機方式控制魚的遊動速度和方向,從而創造出變化無窮的遊動路線。下是這個捕魚遊戲中採用的魚的遊動策略。

  策略1:隨機設定魚的起點。條新生的魚,設定其起點位於遊戲窗口可視區域的兩側。在 1~10 隨機生成一個數,如果該數大於 5,則讓魚出現在左側;否則在右側。這個遊戲窗口尺寸設定爲 1024 x668。在左側時,魚的x座標在-1024~-512 隨機指定;在右側時,魚的x座標在 1536~2048 隨機指定。同時,將魚的 y 座標在 0~768 隨機指定,將魚的遊動方向設定爲面向遊窗口的中心位置(512,384)。

  策略 2: 隨機改變魚的遊動方向和速度。在遊戲中,每條魚每隔 3s有一次改變遊動路線的機會。如果魚在隨機活動區域內,且魚被允許轉變方向,則會隨機改變魚的遊動方向和速度。 這時,魚的旋轉角度在-100~100隨機指定,魚的加速度在-10到魚的正常速度的 l/2 之間隨機指定。

  在遊戲中,魚的隨機活動區域限定平方向爲-5l2~1536,垂直方向爲一384~1152。

  使用表 31-2 中的“遊動速度”和“是否轉向”這兩個參數來設定魚的正常遊動速度和在遊動中是否允許轉變方向。

  策略 3:當魚游出給定活動區域時就消失。

  在遊戲中,魚的活動區域限定:水平方向爲-1024~2048,垂直方向爲-768~1536。當魚游出這個區域,就會被從內存中刪除。

  3.射擊捕魚的算法

  在遊戲中,玩家操控位於遊戲窗口正下方的一門大炮來捕魚。對於發射出去的每一枚炮彈,都要與生命值大於 0 的魚逐一進行碰撞撿測。當炮彈擊中了魚時,將魚的生命值減 1,並在其座標處拋出一張漁網。

  當魚的生命值爲 0 時,將會把魚的造型切換爲扭動身體的動畫圖像,表示魚披捕獲。在魚掙扎 1s 之後,將從屏幕上字消失,並從該種類型的魚的存活數中減去 1。另外,在魚的座標處釋放出一枚硬幣,根據魚的得分值顯示爲一枚銀幣或金幣。硬幣將從魚的座標處飛向位於遊戲窗口左下角的硬幣盒處,同時累計玩家的得分。

  4.動畫的製作

  原書魚的遊動等動畫圖像,是通過序列幀大圖生成的,但是GameZero不支持通過序列幀大圖生成動畫 ,只能將原書資源中的序列幀大圖提取出單張圖像,通過循環切換Actor的圖片文件來模擬動畫。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章