基于Pygame的壁球游戏的设计与开发
2018-05-08杜兰陈琳琳祎神静
杜兰 陈琳琳 祎神静
摘要 本文通过开发经典的壁球游戏展示了基于Pygame开发壁球的基本过程,重点介绍了壁球游戏的需求分析、核心算法和性能调优。
【关键词】Pygame 飞机射击 游戏开发
1 概述
游戏正逐渐成为人们日常娱乐方式,游戏开发也成为软件开发领域的重要分支。Pygame是Python的一个第三方库,搭载了基于OpenGL的图形库和优质的音频库,可以快速上手制作2D游戏的原型。Pygame的API比较偏底层,开发人员在编程时具有很大的自由度,同时具有了很强的可定制性。
2 需求分析
(1)游戏窗口内分为两个区域:游戏区域和计分板。
(2)在游戏区域里有一个深红色的小球在运动,小球撞击到游戏区域左、右两侧的边界时回弹,如果击中上边界则会向下回弹,玩家和AI轮流进行击球,开局由玩家发球。
(3)玩家通过鼠标来左右移动球拍,并且在小球靠近时按下鼠标左键,进行击球,成功击球之后小球会向上回弹,而AI则会自动跟随小球,进行击球。游戏中设置AI击球失败的概率。如果向下运动的过程中小球的高度低于某个阈值时,则本局游戏结束,如果是玩家击球失败则AI得分,否则,玩家得分。
(4)率先赢取3分的选手即为整场比赛的获胜者。单局胜利累计分数,全局结束显示“You Win”或者“You Lose”的字样表示输赢结果。
(5)游戏内设有背景音乐以及击球音效。
3 壁球游戏设计核心算法
3.1 小球的运动
用centerX表示圆心横坐标,centerY表示圆心纵坐标,radius表示半径。用velocityX来表示小球水平方向的速度,用velocityY来表示小球在垂直方向的速度。小球碰撞检测的方法是检测圆心的centerX到左侧边界的距离,如果这个距离小于小球的半径,则说明发生了碰撞,同时这里需要做一个修正,重置centerX的值,使得小球与游戏区域的左侧边界相切,从而避免了视觉上的穿越。同理,当centerX到右侧边界的距离小于等于小球半径时,则说明小球与右侧的边界发生了碰撞,此时更新velocityX并且重置centerX的值。对于上侧边界的检测也是同理,不过这里处理的是y方向,如果centerY到上侧边界的距离小于等于小球的半径则说明小球与上侧边界发生了碰撞,更新velocityY并且重置centerY的值。部分代码如下所示:
小球运动部分代码如下所示:
ifself.centerX - selfradius<-0:
self.centerX - self.radius
self.velocityX= -self.velocityX
elifself.centerX+self.radius>-gameArea[2]: self.centerX - gameArea[2] - self.radius self.velocityX= -self.velocityX ifself.centerY - self.radius<-O: self.centerY - selfradius self.velocityY= -self.velocityY
3.2 玩家的击球操作
本文把小球在击球区域里等价于小球的圆心在击球区域里。因为击球区域是一个矩形,因此这个问题可以被建模成判断一个点是否在一个矩形区域里的问题。如图1所示,在Pygame中,用(startX,startY, width,height)的4元组来表示一个矩形的位置与大小的信息,因此矩形的左上角的坐标即为(startX,startY),矩形的右下角的坐标即为(startX+width,startY+ height),要判断一个点是否在这个矩形区域里,就可以转换成下面的判断。
startX≤pointX≤startX+width
startY≤pointY≤startY+height
其中(pointX,pointY)为需要判断的点的坐标。当这个不等式组成立时,可以判断该点在矩形区域内,否则该点在矩形区域外侧。
为了使游戏具有可玩性,击球后需要更改的不只是小球的velocityY,还需要改变小球的velocityX。如果不加以改变的话,则小球只会不断的按照顺时针或者逆时针的方向进行运动,这样的设计会使得游戏的可玩性大大降低。因此,需要有一种策略来决定击球之后velocityX的符号。通过描述击球区域的元组,可以计算出中心点的横坐标middleX,如果小球的centerX小于middleX,则将velocityX的符号设置为负号,否则设置为正号。这样,玩家在击球之后可以有一定的概率改变小球的运动方向,并且从而使得小球的运动轨迹具有多样性,下一次击球时合适的击球区域也会随之变化,这就增加了游戏的不确定性,进一步增强了玩家与游戏之间的互动和游戏本身的可玩性。部分代码如下:
部分代码如下:
ifselfcenterX
self.velocityX= -abs(self.velocityX)
else:
self.velociWX - abs(self.velocityX)
3.3 AI的击球操作
本文采用了一个简单的思想:AI控制的球拍的横向位置与小球保持同步,这样每当小球下落到AI的球拍的高度的时候,小球总能够出现在AI的击球区域里。这样会产生一个问题:AI必然可以l00%的击中小球,则玩家永远不可能赢过AI!因此需要对这个简单的策略做出一些改进:设置一个(0,1)之间的阈值missRate,比如说0.1,表示AI击球失败的概率,也就是说每次击球时AI都会有missRate的概率无法打中球,这样玩家就会有机会赢过AI,最终获胜。
部分代码如下:
miss- random.random()
print(miss)
if miss >OpponentMissRate:
selfhitSound play()
pyganle tlme wait(lOO)
selfba11.hit(selfopponemHitArea)
direction=random.randomn
if direction<0 5:
selfbalI.velocityX=-selfball.velocityX
4 性能调优
一款游戏要推广的一个前提是在目标机上能够流畅运行。因此在实现基本功能之后,要针对游戏本身的性能进行一些优化,在考虑到变量在内存中的排列以及Python的GC机制的基础上,要合理的管理游戏对象和变量。经过了少许的性能调优之后,软件可以流畅的在绝大多数的学生笔记本电脑上以60FPS的帧频运行。
5 结束语
Pyganle可以大大的加快游戏开发者的开发速度,同时也避免了由于平台不兼容而影响游戏开发的进程。本文重点讨论了基于pygame的飞机射击游戏的的核心算法以及游戏的性能调优。
参考文献
[1] SWEIGART A.Making Games with Pvthon&Pygame [M]. charles ton: CreateSpaceIndependent Publishing Platform, 2012.
[2]王攀拓.基于Python的Pygame框架研究[D].齊齐哈尔:齐齐哈尔大学,2015.
[3]刘班.用Python语言开发弹跳球游戏[J].电脑编程技巧与维护,2014 (07):79-84.