对比python学julia(第三章:游戏编程)--(第四节)捕鱼达人(2)

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

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