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