我们好,欢迎来到 Crossin的编程教室 !

最近有个小伙儿由于在比赛中冲进场所拥抱梅西而出名了。

这种行为当然不可取,他也为此付出了价值。但要说我没有一丁点羡慕和佩服那是不可能的。

所以,我也尬蹭一下这个热点,用Python写了一个「拥抱梅西」的小游戏

游戏作用是这样的:

游戏规则很简单:

  1. 不要被阻拦的工作人员追上

  2. 抱到梅西(触摸必定时长)

  3. 定时会添加阻拦的工作人员

  4. 能够反复拥抱

  5. 被追上后游戏结束,显示坚持的时间和拥抱的次数

代码已上传,获取请拜访:python666.cn/c/9

运转说明

代码使用了游戏结构 pygame-zero 进行开发。之前咱们也有发过依据这个结构的游戏:

羊了个羊,但是Python简(li)单(pu)版

假如你关于此结构还不熟悉,能够看下这篇介绍:

PONG – 100行代码写一个弹球游戏

因而运转代码前需先装置模块:

pip install pgzero

用此结构代码看起来与一般代码稍有不同,它更像一个装备脚本,其中会呈现很多未定义的办法和变量,因而在很多编辑器里会提示有错,但其实是能够运转的,无需手动添加 import。这也是为什么你会看到我视频里的代码截图有大量的下划线。

pgzero有两种办法运转,一种是经过命令行的 pgzrun 命令;另一种是直接在编辑器中运转。参见官方文档:

pygame-zero.readthedocs.io/zh\_CN/late…

本代码用的是第二种直接运转的办法(需新版pgzero),可直接在IDE中履行。

有部分读者反馈此代码在spyder等一些编辑器中无法运转,类似情况能够测验第一种传统办法,即把最终一行代码 pgzrun.go() 去掉,然后直接在命令行该目录下运转:

pgzrun iMessi.py

代码简介

假如你对代码的中心逻辑其实比较容易了解。

  • 关于「玩家」来说,便是依据上下左右按键,变换方位坐标;

  • 关于「工作人员」来说,便是依据自身和玩家的相对方位算出移动的方向,不断靠近,假如碰上了就游戏结束

  • 关于「梅西」来说,便是判别是否与玩家碰上,并记载碰上的持续时间

判别是否“碰上”很简单,便是核算一下两个坐标的间隔是否小于必定值。

至于人物的移动,粗略的做法是,核算出x轴方向和y轴方向上的速度,然后在update函数中,将原坐标方位加上速度值,得到新的坐标方位。

但在我这次的代码中,为了让跑动更“丝滑”,没有选择直接改变速度,而是依据玩家的按键核算出加速度,然后在update函数中,将原速度值加上加速度值,得到新的速度,再用新的速度去核算新的坐标方位。

# 加速
self.speedx += self.fx * self.acc
self.speedy += self.fy * self.acc
# 限制最高速度
d = (self.speedx**2 + self.speedy**2)**0.5 / self.speed_max
if d > 1:
    self.speedx /= d
    self.speedy /= d
# 更新坐标
self.x += self.speedx
self.y += self.speedy

有了这样的设定之后,还有个优点便是能够添加游戏的可玩性,比如你能够设定一种最高速度比玩家快,但是加速度比较小的「工作人员」,玩家就需要经过不停地变换方历来脱节。

代码中另一个比较复杂的地方是“转向”的细节处理。同样为了更加丝滑,我没有选择直接依据核算出的方历来改变人物贴图方向,而是将核算出的方向作为“方针方向”,然后依据人物当时实际方向与方针方向的偏差,决定是向顺时针还是逆时针方向旋转,直到两个方向小于必定阈值。

# 跑动方向
if keyboard.left:
    self.fx = -1
elif keyboard.right:
    self.fx = 1
else:
    self.fx = 0
if keyboard.up:
    self.fy = -1
elif keyboard.down:
    self.fy = 1
else:
    self.fy = 0
# 核算方针方向视点
directs = ((135, 180, -135), (90, None, -90), (45, 0, -45))
direct = directs[self.fx + 1][self.fy + 1]
if direct is None:
    self.angle_dest = self.angle
else:
    self.angle_dest = direct        
# 贴图旋转
if abs(self.angle - self.angle_dest) < 5 or abs(self.angle - self.angle_dest) > 355:
    self.angle = self.angle_dest
else:
    if (0 < self.angle - self.angle_dest < 180) or (
        self.angle - self.angle_dest < -180):
        self.angle -= 500 * dt
    else:
        self.angle += 500 * dt

这段会牵扯一点初中几何的知识,想要理清的话建议在纸上画一画。

最终,是关于这个游戏的一个小视频,给我们图一乐:

我用python抱梅西

欢迎我们关注+三连~