Python AngryBirds完整代码+讲解
python AngryBirds
目录
- python AngryBirds
- 游戏简介
- Pymunk库简介
- 基础
- 为你的物理对象建模
- 对象形状
- 质量、重量和单位
- 对游戏的分析
- 游戏内物体类
- Bird
- Pig
- Polygon
- 主要模块介绍
- 猪鸟碰撞
- 发射小鸟
- 完整代码
游戏简介
简介:
本游戏是基于2D引擎库pymunk的pygame小项目,将github的项目下载下来调通后做了些优化完成的。
图片音乐等资源来源于愤怒小鸟的游戏的资源文件。该游戏可以在论坛https://tieba.baidu.com/p/6492186070下载。
Pymunk库简介
pymunk官网
Pymunk官网简介
(以下源于谷歌翻译的Pymunk简介)
基础
您将在 Pymunk 中使用 4 个基本类。
刚体(
pymunk.Body
)刚体具有物体的物理特性。(质量、位置、旋转、速度等)它本身没有形状。如果您之前使用过粒子物理学,那么刚体的主要区别在于它们能够旋转。刚体通常与游戏中的精灵具有 1:1 的相关性。您应该构建您的游戏,以便使用刚体的位置和旋转来绘制精灵。
碰撞形状(
pymunk.Circle
,pymunk.Segment
和pymunk.Poly
)通过将形状附加到实体,您可以定义实体的形状。您可以将多个形状附加到单个实体以定义复杂的形状,或者如果不需要形状,则不附加任何形状。
约束/接头(
pymunk.constraint.PinJoint
,pymunk.constraint.SimpleMotor
以及其他许多)您可以在两个实体之间附加约束以约束它们的行为,例如保持两个实体之间的固定距离。
空间(
pymunk.Space
)空间是 Pymunk 中的基本模拟单元。您向空间添加实体、形状和约束,然后整体更新空间。它们控制所有刚体、形状和约束如何相互作用。
实际模拟由空间完成。将应该模拟的对象添加到时空后,该pymunk.Space.step()
功能会以小步向前移动 。
为你的物理对象建模
对象形状
您在屏幕上看到的不一定与实际物理对象的形状完全相同。通常用于碰撞检测(和其他物理模拟)的形状是屏幕上绘制内容的简化版本。即使是高端 AAA 游戏也将碰撞形状与屏幕上绘制的形状分开。
有很多原因可以解释为什么将碰撞形状和绘制的内容分开是好的。
- 使用更简单的碰撞形状会更快。因此,如果您有一个非常复杂的对象,例如一棵松树,为了性能,将其碰撞形状简化为三角形可能是有意义的。
- 使用更简单的碰撞形状可以使模拟更好。假设你有一个石头做的地板,中间有一个小裂缝。如果你在这个地板上拖一个盒子,它会卡在裂缝上。但是,如果您将地板简化为平面,您就不必担心东西会卡在裂缝中。
- 使碰撞形状比实际对象更小(或更大)会使游戏玩法更好。假设您在射击类游戏中拥有一艘玩家控制的飞船。很多时候,如果您将碰撞形状与基于它的外观相比应该更小一点,那么玩起来会感觉更有趣。
您可以在Pymunk 中包含的using_sprites.py示例中看到这样的示例。那里的物理形状是一个三角形,但绘制的是金字塔中的 3 个盒子,顶部有一条蛇。另一个示例是 platformer.py示例,其中玩家被绘制为红灰色女孩。然而,物理形状只是相互叠加的几个圆形。
质量、重量和单位
有时,Pymunk 的用户可能会对所有东西的定义单位感到困惑。例如,物体的质量是克还是千克?Pymunk 是无单位的,不关心您使用哪个单位。如果您将秒传递给期望时间的函数,那么您的时间单位是秒。如果您将像素传递给需要距离的函数,那么您的距离单位就是像素。
那么派生单位只是上述的组合。因此,在秒和像素的情况下,速度单位将是像素/秒。
(这与其他一些物理引擎相反,它们可以具有您应该使用的固定单位)
对游戏的分析
接下来步入正题,怎么去调用Pymunk去完成这个小project?
首先要对这个游戏进行简单的分析:
然后对游戏中的流程进行简单分析
通过对流程分析后大概可以知道有这么一些模块
没有代码空谈这些是耍流氓的!!!
下面进入代码部分hhh
游戏内物体类
Bird
class Bird:def __init__(self, distance, angle, x, y, space):self.life = 20 # 生命值20mass = 5 # 质量 5radius = 12 # 刚力小圆圈的半径 12inertia = pm.moment_for_circle(mass, 0, radius, (0, 0)) # 转动惯量body = pm.Body(mass, inertia) # 初始化刚体body.position = x, y # 鸟的位置power = distance * 53 # 放大距离,优化参数增强游戏体验impulse = power * Vec2d(1, 0) # 冲力angle = -anglebody.apply_impulse_at_local_point(impulse.rotated(angle)) # rotated 旋转向量 apply_impulse_at_local_point 在局部点施加脉冲shape = pm.Circle(body, radius, (0, 0)) # 碰撞类型圆形好计算shape.elasticity = 0.95 # 弹性shape.friction = 0.9 # 摩擦力shape.collision_type = 0 # 碰撞类型space.add(body, shape) # 加到2维平面self.body = bodyself.shape = shape
Pig
class Pig:def __init__(self, x, y, space):self.life = 20mass = 5radius = 14inertia = pm.moment_for_circle(mass, 0, radius, (0, 0))body = pm.Body(mass, inertia)body.position = x, yshape = pm.Circle(body, radius, (0, 0))shape.elasticity = 0.95shape.friction = 0.9shape.collision_type = 1space.add(body, shape)self.body = bodyself.shape = shape
Polygon
class Polygon:def __init__(self, pos, length, height, space, mass=5.0):moment = 1000body = pm.Body(mass, moment)body.position = Vec2d(pos)shape = pm.Poly.create_box(body, (length, height))shape.color = (0, 0, 255)shape.friction = 0.5shape.collision_type = 2space.add(body, shape)self.body = bodyself.shape = shapewood = pygame.image.load("E:/py/AngryBirds/images/wood.png").convert_alpha()wood2 = pygame.image.load("E:/py/AngryBirds/images/wood2.png").convert_alpha()rect = pygame.Rect(251, 357, 86, 22)self.beam_image = wood.subsurface(rect).copy()rect = pygame.Rect(16, 252, 22, 84)self.column_image = wood2.subsurface(rect).copy()def to_pygame(self, p):"""Convert pymunk to pygame coordinates"""# pygame右边x轴,下边y轴return int(p.x), int(-p.y+600)def draw_poly(self, element, screen):"""Draw beams and columns"""# 梁横 柱竖poly = self.shapeps = poly.get_vertices()ps.append(ps[0])ps = map(self.to_pygame, ps)ps = list(ps)color = (255, 0, 0)pygame.draw.lines(screen, color, False, ps)if element == 'beams':p = poly.body.positionp = Vec2d(self.to_pygame(p))angle_degrees = math.degrees(poly.body.angle) + 180rotated_logo_img = pygame.transform.rotate(self.beam_image,angle_degrees)offset = Vec2d(rotated_logo_img.get_size()) / 2.p = p - offsetnp = pscreen.blit(rotated_logo_img, (np.x, np.y))if element == 'columns':p = poly.body.positionp = Vec2d(self.to_pygame(p))angle_degrees = math.degrees(poly.body.angle) + 180rotated_logo_img = pygame.transform.rotate(self.column_image,angle_degrees)offset = Vec2d(rotated_logo_img.get_size()) / 2.p = p - offsetnp = pscreen.blit(rotated_logo_img, (np.x, np.y))
Tips:
注意,pygame和pymunk的坐标系不一样!!!
下图为pygame的坐标图(懒的自己画图了,体谅一下)
pymunk的y轴是向上的。
主要模块介绍
猪鸟碰撞
def post_solve_bird_pig(arbiter, space, _):"""Collision between bird and pig"""surface = screena, b = arbiter.shapesbird_body = a.bodypig_body = b.bodyp = to_pygame(bird_body.position)p2 = to_pygame(pig_body.position)r = 30pygame.draw.circle(surface, BLACK, p, r, 4)pygame.draw.circle(surface, RED, p2, r, 4)pigs_to_remove = []for pig in pigs:if pig_body == pig.body:pig.life -= 20pigs_to_remove.append(pig)global scorescore += 10000for pig in pigs_to_remove:space.remove(pig.shape, pig.shape.body)pigs.remove(pig)
发射小鸟
if (event.type == pygame.MOUSEBUTTONUP andevent.button == 1 and mouse_pressed):# Release new birdmouse_pressed = Falseif level.number_of_birds > 0:song_fly = 'E:/py/AngryBirds/music/bird 01 flying.wav'pygame.mixer.music.load(song_fly)pygame.mixer.music.play(0)level.number_of_birds -= 1t1 = time.time() * 1000xo = 154yo = 156if mouse_distance > rope_length:mouse_distance = rope_lengthif x_mouse < sling_x + 5:bird = Bird(mouse_distance, angle, xo, yo, space)birds.append(bird)else:bird = Bird(-mouse_distance, angle, xo, yo, space)birds.append(bird)if level.number_of_birds == 0:t2 = time.time()
其余部分在代码中看(主要还是写的有点乱,粘出来不好看,滑稽)
完整代码
完整代码
Python AngryBirds完整代码+讲解相关推荐
- 【OCR炼丹】解析CASIA数据集OLHWDB部分Python版完整代码
上一篇记录了HIT-OR3C联机数据的解析代码,由于OLHWDB不同于HIT-OR3C,其在采集联机手写体数据时就没有按照固定size去采集(HIT-OR3C保存的坐标是转换后相对128*128大小画 ...
- python画图完整代码-Python科学画图代码分享
Python画图主要用到matplotlib这个库.Matplotlib 是一个 Python 的 2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形. 具体来说是pylab和p ...
- python爬虫完整代码下载页
由于上一个连接有些网址被和谐,所以这里贴出完整的代码 运行是修改path路径为你自己保存图片的位置. # -*- coding: utf-8 -*- # 作者: 废人一枚 # 出自: 北京 # 创建时 ...
- 国密算法 SM4 对称加密 分组密码 python实现完整代码
目前,python实现的国密算法库主要是python-gmssl库和snowland-smx(pysmx)库,二者都对SM2(仅公钥加解密和数字签名).SM3.SM4进行了细致而优雅的实现. GMSS ...
- Spearman 相关性分析法,以及python的完整代码应用
Spearman 相关性分析法 简介 Spearman 相关性分析法是一种针对两个变量之间非线性关系的相关性计算方法,同时,它不对数据的分布进行假设.该方法的基本思想是将两个(也可以多个)变量的值进行 ...
- Python爬虫完整代码拿走不谢
对于新手做Python爬虫来说是有点难处的,前期练习的时候可以直接套用模板,这样省时省力还很方便. 使用Python爬取某网站的相关数据,并保存到同目录下Excel. 直接上代码: import re ...
- 如何用python画爱心代码_用 python 画爱心代码讲解
学计算机的男生发这个给我看是什么意思?www.zhihu.com 原理其实挺简单的. 代码网上也有. 最难的部分前人都告诉我们了, 心形可画. 要自己推导通过泰勒各种扭也可以. 通过肉眼扭我感觉也不 ...
- C语言实现扫雷完整代码讲解
扫雷是一款初学者能用C语言实现的益智小游戏,只需要用二维数组操作雷区即可. 算法详讲 : 游戏思路如下:点击雷区中的任一格子,如果该格子有雷,则游戏结束:如果该格子周围9个格子都不是雷,那么直接展开其 ...
- python 石头剪刀布,Python石头剪刀布完整代码
print("游戏介绍:\n" "数字1代表石头\n" "数字2代表剪刀\n" "数字3代表布") 游戏次数 playn ...
- python自动读取邮件_Python自动化读取邮件基础代码讲解
大家好,在之前的文章中我们已经了解如何对自己的邮箱做一些代码操作前的基础配置,也学会了通过 yagmail 发送邮件.这篇文章将分别介绍两个很实用的收取及读取邮件的库:imbox 和 poplib,主 ...
最新文章
- ProxyError: Conda cannot proceed due to an error in your proxy configuration
- leetcode算法题--二分查找
- SQL数据导入导出问题总结
- 【密码学】CSP的概念
- Vue导入非模块化的第三方插件功能无效解决方案
- 超级简便的容器化部署工具(使用 ASP.NET Core 演示)
- 如果我已经开始重新设置基准,如何将两个提交合并为一个?
- excel 日期格式 mysql_EXCEL和MySQL日期格式之间的转换
- 国内外机器视觉软件功能对比
- C语言-打印菱形三角形等图形
- 【LeetCode】275. H指数 II
- 喝杯水都能泄露指纹?屏下指纹识别设备被攻破
- 中国AI的“底线思维”与安全锁
- ASP.NET 中验证的自定义返回和统一社会信用代码的内置验证实现
- 12864液晶显示出十进制数据
- java将古诗竖排_古诗词竖排格式
- Pytorch中shuffle=True的作用
- svn 代码迁移到git
- C语言:一个5位数,判断它是不是回文数。即12321是回文数,个位与万位相同,十位与千位相同。
- 三菱PLC FX5U 伺服机器人程序 包括三菱FX5U程序,威纶通触摸屏程序
热门文章
- 数据基础设施创新如火如荼,主要方向有哪些(下)
- JUC:6_1集合类并发问题、集合类并发不安全解决方案1:list
- 【软件project】 文档 - 银行业务管理 - 需求分析
- 发现ULC(UltraLightClient)
- 设置Win10防火墙规则,使得局域网能访问此电脑的Tomcat服务器
- 皮皮虾如何引流?皮皮虾运营如何变现?皮皮虾APP怎么引流?
- html文本只显示一行,如何让div中的文字只显示一行,多余的文字隐藏并加上省略号(超链接形式)...
- 解决webView无法播放视频的问题
- 5月末跟大家讲讲webpack(生日篇)
- C++生成0到1之间的随机数