4.3. 編程實現
在編寫捕魚遊戲之前,原書是先創建一個 pyglet.sprite.Sprite 類的派生類SpritePlus,實現了一套角色運動控制指令。不過julia中沒有類(Class)的概念,也不支持實體繼承,雖然julia這樣設計有一定的道理,但是卻給我們出了難題,因爲我們不可能從Actor派生新的“類”。
打開原書資源中實現SpritePlus類的文件prite_plus.py,可以看出,SpritePlus類主要拓展了Sprite的屬性(成員變量),並實現了一些函數。對於擴展屬性,Actor實現了動態添加屬性,所以可以在定義Actor具體對象時動態創建屬性。對於函數,julia本質上是以行爲優先的,而類型僅僅是用來派發行爲的一種標籤,而行爲多半是用函數來實現的,因此我們只需要將SpritePlus類中的函數,用julia實現就可以了。
我們創建一個actor_plus.jl文件,實現以下幾個函數:
(1) 創建 Point()方法,用於實現讓精靈面向指定的座標(x,y)。
我們先來看Python代碼:
1 def point(self, x, y): 2 '''讓角色面向指定的座標''' 3 #界限角,在座標軸的角度 4 if x == self.x: 5 a = 0 if y > self.y else 180 6 elif y == self.y: 7 a = 90 if x > self.x else 270 8 else: 9 #象限角 10 R = degrees(atan(abs(x - self.x) / abs(y - self.y))) 11 #測量學上的方位角 12 if x > self.x and y > self.y: 13 a = R 14 elif x > self.x and y < self.y: 15 a = 180 - R 16 elif x < self.x and y < self.y: 17 a = 180 + R 18 elif x < self.x and y > self.y: 19 a = 360 - R 20 21 #數學上的方位角 22 self.rotation = a – 90
如果理解了上節的編程思路,我們可以發現,這個函數只要稍作修改就能移植到julia代碼。
1 function point(actor::Actor, x, y) 2 #'''讓角色面向指定的座標''' 3 #界限角,在座標軸的角度 4 if x == actor.x 5 a = (y > actor.y ? 180 : 0) 6 elseif y == actor.y 7 a = (x > actor.x ? 270 : 90) 8 else 9 #象限角 10 R = rad2deg(atan(abs(x - actor.x) / abs(y - actor.y))) 11 12 #測量學上的方位角 13 if x > actor.x && y > actor.y 14 a = R 15 elseif x > actor.x && y < actor.y 16 a = 180 - R 17 elseif x < actor.x && y < actor.y 18 a = 180 + R 19 elseif x < actor.x && y > actor.y 20 a = 360 - R 21 end 22 end 23 #println(a) 24 #數學上的方位角 25 actor.angle = -(a -90) 26 end
(2) 創建 left()和 right()方法,實現讓角色向左或向右旋轉指定的角度。
function left(actor::Actor, rotation) #'''左轉一個角度''' actor.angle -=rotation end function right(actor::Actor, rotation) #'''右轉一個角度''' actor.angle += rotation end
(3) 創建move()方法,用於讓角色沿着某個方向往前移動指定的距離。其算法請參照“編程思路”中的介紹。
function move(actor::Actor, distance) #'''移動一個距離''' #println(actor.angle) actor.x+= distance * cosd(actor.angle) actor.y+= distance * sind(actor.angle) end
注意在julia中,sin()和cos()的參數單位是弧度,sind()和cosd的參數的單位是度。
下面我們編寫一個小程序來測試一下actor_plus。
1 game_include("actor_plus.jl") 2 # Height of the game window 3 HEIGHT = 668 4 # Width of the game window 5 WIDTH = 1024 6 7 fish=Actor("fish1_01.png",pos=(300,300)) 8 fish.angl=0 9 10 function draw(g::Game) 11 draw(fish) 12 end 13 14 function on_mouse_down(g::Game, pos, button) 15 if button==MouseButtons.LEFT 16 #面向鼠標指針移動10個像素 17 x,y=pos 18 point(fish,x, y) 19 move(fish,10) 20 end 21 end
請回顧“編程思路”中 的內容來理解以上的源代碼,或者是運行測試程序來理解其實現。
下載測試代碼:https://files.cnblogs.com/files/zjzkiss/testActorPlus.zip