2.公主精灵的控制

  在第2阶段,将创建一个公主角色,支持玩家使用键盘上的左、右方向键控制公主角色的左、右移动。在“sdgz”项目目中 ,把 version1.jl复制一份并命名为version2.jl,在第1个版本的基础上编写第2 个版本的代码,具体步骤如下:

  (1) 用图像Actor创建一个公主角色,将其定位在窗口底部居中位置。

  princess = Actor(princess_img)

  princess.pos=(400, 305)

  (2) 在窗口的draw()方法中,调用draw()方法将公主精灵的图绘制到窗口中。在游戏处于进行状态才会显示公主精灵,即在 game_state 等于 1 时才绘制公主角色的外观。

  

elseif game_state == 1
   …
   draw(princess)

  提示:“…”号表示省略掉的部分代码,下同。

  (3) 控制公主角色左、右移动。这里没有使用键盘事件,而是通过检测键盘按键状态来判断是否按下左 、右方向键。因此需要在窗口的事件循环update()方法中检测左、右方向键的按键状态,并控制公主角色左、右移动。在update()方法中添加如下代码:

  function update(g::Game,dt)

      princess_control(g,dt)

  end

   princess_control是公主角色控制函数,update事件中每帧切换会调用这个函数。princess_control()函数的代码如下:

#控制公主左右移动
function princess_control(g::Game,dt)
    global game_state
    if game_state != 1
        return
    end

    if g.keyboard.LEFT
        princess.x -= 400 * dt
        if princess.left < 0
            princess.left = -princess.left
        end
    elseif g.keyboard.RIGHT
        princess.x += 400 * dt
        if princess.right > WIDTH
            princess.right += -(2 * (princess.right - WIDTH))
        end
    end
end

  对上面代码的说明如下。

  ①在游戏处于进行状态时才能控制公主精灵移动,即如果 game_state 不等于1,就退出这个函数。

  ②函数 princess_control ()被调用时,自上次被调用以来经过的时间(单位= S)就会被传递给参数 dt。假设公主精灵的移动速度为400 像素/S,那么它在 princess_control () 函数披调用时的移动速度则为 400*dt。在向左移动时,princess.x 的值将减去400*dt;在向右移动时 ,princess.x 的值将增加 400*dt。

  ③公主角色在窗口中移动应该显示完整的外形。因此princess.left最小值为0,princess.right最大值是800 。

至此,第 2 个版本的程序编写完成. 运行程序,就可以用键盘上的左、右方向键控制公主角色左右移动了。

  3.下落物体角色的控制

  在第3个阶段,将实现从天空中随机落下雪花、礼物或剪刀。从面向对象的角度看,雪花、礼物和剪刀都可以归结为一类物体,即“下落物体类”,原书的做法是从Pyglet的Sprite 类中派生一个下落物体类 FallingObject,并运用该类的实例实现雪花、礼物或剪刀的互相切换。

  但是Julia不是传统意义上的面向对象语言,Julia里没有class,没有类的继承(inheritance),勉强与class能对应上的是struct,且不能派生和继承,除构造函数外,struct内不能定义其它函数。

  1)   创建FallingObject对象

  原书中,作者定义了一个名为 FallingObject的类,继承自Sprite 类,在类中添加一个属性 type 和一个用于切换雪花、礼物和剪刀的 change()方法。转换到Julia,可以写成如下结构的代码:

 1 mutable struct FallingObject
 2     act::Actor
 3     type::Int
 4 
 5     function FallingObject()
 6         act=Actor(snowflake_img)
 7         type=1
 8         new(obj,type)
 9     end
10 end
11 
12 function change(fo::FallingObject)
13     #随机切换掉落物体的造型
14     n = rand(1:10)
15     if 1 <= n <= 5
16         fo.type = 1
17         fo.act.image = snowflake_img
18     elseif 6 <= n <= 8
19         fo.type = 2
20         fo.act.image = gift_img
21     else
22         fo.type = 3
23         fo.act.image = clipper_img
24     end
25     #将物体定位到窗口上方随机位置
26     x=rand(100:700)
27     fo.act.pos =x , -100    
28 end

  笔者原打算按此思路实现下落物体的控制,但是通过研究GameZero的源码,发现源码作者对Actor增加了赋予其自定义属性的能力。由于下落物体本质上是一个Actor,所以我们可以直接这样定义:

  falling_obj =Actor(snowflake_img;pos=(rand(100:700),-100),type=1)

  上面代码中参数snowflake_img是雪花的图片,pos是位置,其x轴坐标为100-700间的随机值,第三个参数type就是自定属性。

  这样一来,代码将简洁很多。至于Julia的面向对象编程,笔者将新开贴专题论述。

  

  2)   控制 FallingObject对象

  将version2.jl录复制一份并命名为version3.jl,在第 2 个版本的基础上编写第 3 个版本的代码。

  (1) 在窗口的draw()方法中,绘制出 falling_0bj 对象的外观。与公主精灵一样 ,都是在游戏处于进行状态时才会显示下落物体.

elseif game_state == 1
	…
   draw(falling_obj)

  (2) 在窗口的 on_key_down()方法中添加切换下落物体造型的代码。当在游戏重新开始时,就调用 Change()方法切换下落物体的造型。

function on_key_down(g, k)
    global game_state
    #println(k)
    if k ==Keys.RETURN  #13
        if game_state != 1
            game_state = 1
            change(falling_obj)
        end
    end

end

  另外,事先将Change()方法稍加修改,添加到version3.jl中:

 1 function change(fo::Actor)
 2     #随机切换掉落物体的造型
 3     n = rand(1:10)
 4     if 1 <= n <= 5
 5         fo.type = 1
 6         fo.image = snowflake_img
 7     elseif 6 <= n <= 8
 8         fo.type = 2
 9         fo.image = gift_img
10     else
11         fo.type = 3
12         fo.image = clipper_img
13     end
14     #将物体定位到窗口上方随机位置
15     x=rand(100:700)
16 fo.pos =x , -100  
17 end  

  上面的代码使用随机数生成掉落物体的造型 ,并将其随机定位在窗口上方。随机生成下落物体的算法在本节的编程思路中已经作过介绍。

  (1) 控制下落物体向下移动 。在update()方法中添加如下代码:

function update(g::Game,dt)
    falling_control(dt)
end

  函数falling_control()的代码如下:

 1 function falling_control(dt)
 2     #礼物精灵的控制'''
 3     global game_state
 4     if game_state != 1
 5         return
 6     end
 7 
 8     #控制礼物的落下速度和旋转速度
 9     falling_obj.angle += 60 * dt
10     falling_obj.y += 200 * dt
11     if falling_obj.y >HEIGHT
12         #println("ddd")
13         change(falling_obj)
14     end
15 end

  对上面代码的说明如下。

  ①在游戏处于进行状态时才能控制下落物体的移动,即如果 game_state 不等于 l,就退出这个函数。

  ②旋转速度和向下移动速度跟时间有关。下落物体在降落过程中是旋转的,假设每秒旋转 60,就使用 60 *dt 算出 faning_0bj.angle每次的增加量;假设每秒向下移动200 像素,就使用 200 *dt 算出 fa]ling_Obj.y 每次减少的距离。

  ③当下落物体移动到窗口底部外面的区域时,就将其重新放到窗口的顶部,并随机切换新的造型,调用 change()方法来实现。

  至此,第 3 个版本的程序编写完成。运行程序,就可以看到在游戏时会从天空中随机掉下雪花、礼物或者剪刀。

  代码下载地址:https://files.cnblogs.com/files/zjzkiss/sdgz_v2.rar

posted on 2022-07-24 16:32  语风  阅读(93)  评论(0编辑  收藏  举报