• 对比python学julia(第三章:游戏编程)(第二节)公主迎圣诞(3)


      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

  • 相关阅读:
    null和undefined的区别
    【面试】前端面试题总结一(css)
    【js基础类】火狐的滚动事件
    【Vue】provide和inject
    React学习:react-router-dom-主要组件
    React学习:组合VS继承
    React学习:状态提升
    React学习:form表单
    unity+ARKit 捕捉表情录制动画 表情动画与人形骨骼动画融合
    Unity导入模型材质球无法编辑属性解决方法
  • 原文地址:https://www.cnblogs.com/zjzkiss/p/16514739.html
Copyright © 2020-2023  润新知