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

4.1.    游戏介绍

  这是一款以深海狩猎为题材的休闲射击游戏一捕鱼达人。如下图所示,在游戏窗口中游动着各种色彩鲜艳的鱼儿,一门大炮位于窗口正下方;玩家移动 鼠标指针,大炮随之转动;瞄准鱼儿,轻点鼠标,就能发射炮弹;当炮弹击中鱼儿时,就会变成一张渔网,将鱼儿收人网中并兑换成得分。

  这个游戏轻松而简单,可以让玩家享受深海捕鱼的乐趣。如果要退出游戏程序,可以单击窗口右上角的“关闭”按钮。

  在编写这个游戏之前,可以先进行试玩,以便更好地了解这个游戏需要实现的各个功能。

  源码下载链接:https://files.cnblogs.com/files/zjzkiss/bydr.zip

  提示:这是初步的代码,后续分步骤实现的时候,可能会有所修改。

4.2.    编程思路

  与前面课程中介绍的两个小游戏相比,这个捕鱼游戏要略为复杂一些。这个游戏需要实现的主要功能有:在游戏中大炮会随时面向鼠标指针转动,各种鱼会随机地游来游去,当炮弹击中鱼时会显示渔网,以及产生一枚硬币飞到得分栏中的效果。接下来,将介绍实现这个捕鱼游戏涉及的一些主要算法。

  1. 实现高级运动控制功

  对初学者来说,在Pyglet中想要实现类似大炮跟随鼠标指针转动的效果,将是一件比较困难的事情。 到目前为止,Pyglet的精灵类(pyglet.sprite. Sprite)并没有提供让精灵面向鼠标指针的功能.同样,Julia的GameZero也没有提供此功能。

  原书是在 Pyglet的精灵类的基础上实现一个 Sprite 派生类,让精灵(Sprite)能够面向某个座标和沿某个方向移动指定距离的算法。但是Julia是没有类(class)的,也不允许实体继承的,因此不能从Actor派生新的对象。只能通过函数调用来实现。

  1)   让角色面向某个座标

  在游戏中,有时需要让一个角色面向另一个角色,其实质就是确定两个精灵的座标点连成的直线的方向。专业的说法称为直线定向,即确定直线与标准方向之间的角度。在测量学中,使用方位角和象限角表示直线的方向。

  方位角的定义:以座标纵轴北端为标准方向,沿顺时针方向量到某条直线的夹角,称为该直线的座标方位角,简称方位角;其角值为0°~360°,正北为 0°,正东为90°,正南为180°,正西为270°。如原书图 31-3 所示。

  象限角的定义:从座标纵轴的北端或南端起,沿顺时针或逆时针方向量至某条直线的锐角,称为该直线的座标象限角,简称象限角;其角值为0°~90°,为了表示直线的方向,应分别注明北东、北西或南东、南西,如北东60°、南西 55°等。 如原书图 31-4 所示。

  直线的方位角和象限角之间存在换算关系。象限角用R 表示,座标方位角用α表示,两者之间的换算关系见原书表 31-1。

 

  注意: 座标象限在数学中按逆时针方向编号,而在测量学中按顺时针方向编号。

  如原书图31-5 所示,已知A点(xA,yA )和B 点( xB,yB)的座标,先利用反正切函数求得象限角RAB的值,再根据B点位于A 点的右上方判定象限角RAB位于第一象限,由此可得直线AB的方位角αAB =RAB 。同理,也可以计算出其他象限中某条直线的座标方位角。

 

  由于Pyglet 座标系的0°位于正东方向,与测量学中位于正北的标准方向相差90°,因而将上述所求得的方位角减去90°,就能得到 Pyglet 中使用的方位角。不过GameZero的座标原点是在左上角的,与Pyglet正好成镜像,如Pyglet的90°在GameZero里是-90°。 使用所求得的方位角来设置角色的旋转角度,即可实现让一个角色面向鼠标指针或其他角色所在座标。

  2)   让精灵沿某个方向移动指定

  在游戏中,经常需要让角色以随机方式运动,以获得自然逼真的运动效果。这需要控制角色运动的方向和距离这两个参数来实现。通过增加或减少角色的旋转角度,就能实现让角色向左旋转或向右旋转的功能。在方向确定之后,让精灵沿着该方向往前移动指定的距离,移动后的座标可以由方位角和距离这两个参数计算出来。

  如原书图31-6所示,已知A点(xA,yA )沿着 方向移动一段距离D之后到达B点( xB,yB)。那么,利用 sin 和 cos 函数就可以求得 B 点座标。

  由于 Pyglet 的方位角与测量学中的方位角相差90°因此,在计算时将方位角 加上90°再用三角函数求出B点的座标。不过由于GameZero的座标原点在左上角,因此B点座标的计算略有差别,如下图所示:

  这样一来,使用方向和距离这两个参数就能让角色实现自然逼真的随机运动,使游戏具有更好的体验。

  3)   检测角色之间是否碰撞

  在这个捕鱼游戏中,如果要判断移动中的炮弹是否命中游动的鱼,就需要检测炮弹和鱼这两个角色之间是否产生碰撞。GameZero有专用的碰撞检测函数,比较简单。

  2.鱼群生成策略和鱼的游动策略

  捕鱼游戏的主要特色就是展示了多种栩栩如生的海洋鱼类自由自在游动的逼真效果。这需要设计一个鱼群生成策略,用来控制每种鱼的总数和活跃数雾还需要设计一个鱼的游动算法,让不同的鱼采用不同的速度和路线以随机方式游。

  1)   鱼的参数配置表

  在捕鱼游戏中,鱼的种类多达 12 种。编程时,需要用到每种鱼的总数、游动速度、生命值、得分等多种叁数,如原书表 31-2 所示。把这些参数存放在字典(dict)类型的变量中(julia和python的字典类型基本相同),能够极大地简化编程工作。

  提示:除文件名和动画行数外,其他参数可以根据个人喜好进行调整。

  2)  鱼群的生成策略

  在游戏中,使用表 31-2 中给出的每种鱼的总数目参数来控制其数量上限,避免鱼群数量过多在屏幕上造成拥挤,从而影响游戏视觉效果。以下是这个捕鱼游戏中采用的鱼群生成策略.

  策略1: 在游戏开始时,每种鱼生成其总数的 1/2;之后,如果每种鱼的数量小于其上限的 1/3 时,则把剩佘的数量补齐。

  策略2:在游戏进行中,每隔 300s或 480s 出现一只蓝鲨或金鲨。因两种 鲨鱼体积过大且得分最高,在游戏中使其总数量分别保持在 1 条即可。

  3)  鱼的游动策略

  在游戏中,采用随机方式控制鱼的游动速度和方向,从而创造出变化无穷的游动路线。下是这个捕鱼游戏中采用的鱼的游动策略。

  策略1:随机设定鱼的起点。条新生的鱼,设定其起点位于游戏窗口可视区域的两侧。在 1~10 随机生成一个数,如果该数大于 5,则让鱼出现在左侧;否则在右侧。这个游戏窗口尺寸设定为 1024 x668。在左侧时,鱼的x座标在-1024~-512 随机指定;在右侧时,鱼的x座标在 1536~2048 随机指定。同时,将鱼的 y 座标在 0~768 随机指定,将鱼的游动方向设定为面向游窗口的中心位置(512,384)。

  策略 2: 随机改变鱼的游动方向和速度。在游戏中,每条鱼每隔 3s有一次改变游动路线的机会。如果鱼在随机活动区域内,且鱼被允许转变方向,则会随机改变鱼的游动方向和速度。 这时,鱼的旋转角度在-100~100随机指定,鱼的加速度在-10到鱼的正常速度的 l/2 之间随机指定。

  在游戏中,鱼的随机活动区域限定平方向为-5l2~1536,垂直方向为一384~1152。

  使用表 31-2 中的“游动速度”和“是否转向”这两个参数来设定鱼的正常游动速度和在游动中是否允许转变方向。

  策略 3:当鱼游出给定活动区域时就消失。

  在游戏中,鱼的活动区域限定:水平方向为-1024~2048,垂直方向为-768~1536。当鱼游出这个区域,就会被从内存中删除。

  3.射击捕鱼的算法

  在游戏中,玩家操控位于游戏窗口正下方的一门大炮来捕鱼。对于发射出去的每一枚炮弹,都要与生命值大于 0 的鱼逐一进行碰撞捡测。当炮弹击中了鱼时,将鱼的生命值减 1,并在其座标处抛出一张渔网。

  当鱼的生命值为 0 时,将会把鱼的造型切换为扭动身体的动画图像,表示鱼披捕获。在鱼挣扎 1s 之后,将从屏幕上字消失,并从该种类型的鱼的存活数中减去 1。另外,在鱼的座标处释放出一枚硬币,根据鱼的得分值显示为一枚银币或金币。硬币将从鱼的座标处飞向位于游戏窗口左下角的硬币盒处,同时累计玩家的得分。

  4.动画的制作

  原书鱼的游动等动画图像,是通过序列帧大图生成的,但是GameZero不支持通过序列帧大图生成动画 ,只能将原书资源中的序列帧大图提取出单张图像,通过循环切换Actor的图片文件来模拟动画。

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