总览

这是有关使用Python 3和Pygame制作游戏的五部分系列教程的第四部分。 在第三部分中,我们深入探讨Breakout的核心,学习了如何处理事件,遇到了Breakout主班,并了解了如何移动不同的游戏对象。

在这一部分中,我们将看到如何检测碰撞以及当球撞击桨,砖块,墙壁,天花板和地板等各种物体时发生的情况。 最后,我们将回顾游戏UI的重要主题,尤其是如何使用我们自己的自定义按钮创建菜单。

碰撞检测

在游戏中,事物相互碰撞。 突破没有什么不同。 通常是碰到东西的球。 handle_ball_collisions()方法具有一个称为intersect()的嵌套函数,该函数用于测试球是否击中了对象以及它在何处击中了对象。 如果球没有击中对象,则返回“ left”,“ right”,“ top”,“ bottom”或“ None”。

def handle_ball_collisions(self):def intersect(obj, ball):edges = dict(left=Rect(obj.left, obj.top, 1, obj.height),right=Rect(obj.right, obj.top, 1, obj.height),top=Rect(obj.left, obj.top, obj.width, 1),bottom=Rect(obj.left, obj.bottom, obj.width, 1))collisions = set(edge for edge, rect in edges.items() ifball.bounds.colliderect(rect))if not collisions:return Noneif len(collisions) == 1:return list(collisions)[0]if 'top' in collisions:if ball.centery >= obj.top:return 'top'if ball.centerx < obj.left:return 'left'else:return 'right'if 'bottom' in collisions:if ball.centery >= obj.bottom:return 'bottom'if ball.centerx < obj.left:return 'left'else:return 'right'

用球拍击球

当球击中桨时,球反弹。 如果它碰到了桨的顶部,它将回弹,但保持相同的水平速度分量。

但是,如果它碰到了桨的侧面,它将弹向相反的一侧(向左或向右)并继续向下运动,直到碰到地板。 该代码使用相交的function()。

# Hit paddle
s = self.ball.speed
edge = intersect(self.paddle, self.ball)
if edge is not None:self.sound_effects['paddle_hit'].play()
if edge == 'top':speed_x = s[0]speed_y = -s[1]if self.paddle.moving_left:speed_x -= 1elif self.paddle.moving_left:speed_x += 1self.ball.speed = speed_x, speed_y
elif edge in ('left', 'right'):self.ball.speed = (-s[0], s[1])

打地板

当桨在下降途中未击中球时(或如果球在侧面击中桨),则球将继续下落并最终击中地面。 在这一点上,玩家丧命,并且重新制作了球,因此游戏可以继续进行。 当玩家的生命耗尽时,游戏结束。

# Hit floor
if self.ball.top > c.screen_height:self.lives -= 1if self.lives == 0:self.game_over = Trueelse:self.create_ball()

击中天花板和墙壁

当球碰到墙壁或天花板时,它会弹回来。

# Hit ceiling
if self.ball.top < 0:self.ball.speed = (s[0], -s[1])# Hit wall
if self.ball.left < 0 or self.ball.right > c.screen_width:self.ball.speed = (-s[0], s[1])

打砖

当球碰到一块砖头时,这是Breakout中的重要事件-砖头消失,玩家得到一个点,球反弹回来,并且发生了其他一些事情(声音效果,也可能是特殊效果),我将讨论后来。

为了确定是否击中了砖块,代码检查一下是否有任何砖块与球相交:

# Hit brick
for brick in self.bricks:edge = intersect(brick, self.ball)if not edge:continueself.bricks.remove(brick)self.objects.remove(brick)self.score += self.points_per_brickif edge in ('top', 'bottom'):self.ball.speed = (s[0], -s[1])else:self.ball.speed = (-s[0], s[1])

编程游戏菜单

大多数游戏都有一些UI。 Breakout有一个简单的菜单,其中包含两个按钮,分别为“ PLAY”和“ QUIT”。 菜单在游戏开始时显示,并在玩家单击“ PLAY”时消失。 让我们看看如何实现按钮和菜单以及它们如何与游戏集成。

制作按钮

Pygame没有内置的UI库。 有第三方扩展,但是我决定为菜单构建自己的按钮。 按钮是具有三种状态的游戏对象:正常,悬停和按下。 正常状态是鼠标悬停在按钮上方时,悬停状态是鼠标悬停在按钮上方但未按下鼠标左键时。 按下状态是当鼠标悬停在按钮上方且播放器按下鼠标左键时。

该按钮实现为矩形,上面带有背景颜色和文本。 该按钮还接收一个on_click函数(默认为noop lambda函数),该函数在单击按钮时被调用。

import pygamefrom game_object import GameObject
from text_object import TextObject
import config as cclass Button(GameObject):def __init__(self, x, y, w, h, text, on_click=lambda x: None, padding=0):super().__init__(x, y, w, h)self.state = 'normal'self.on_click = on_clickself.text = TextObject(x + padding, y + padding, lambda: text, c.button_text_color, c.font_name, c.font_size)def draw(self, surface):pygame.draw.rect(surface, self.back_color, self.bounds)self.text.draw(surface)

该按钮处理自己的鼠标事件,并根据这些事件更改其内部状态。 当按钮处于按下状态并收到MOUSEBUTTONUP事件时,意味着玩家单击了按钮,并调用了on_click()函数。

def handle_mouse_event(self, type, pos):if type == pygame.MOUSEMOTION:self.handle_mouse_move(pos)elif type == pygame.MOUSEBUTTONDOWN:self.handle_mouse_down(pos)elif type == pygame.MOUSEBUTTONUP:self.handle_mouse_up(pos)def handle_mouse_move(self, pos):if self.bounds.collidepoint(pos):if self.state != 'pressed':self.state = 'hover'else:self.state = 'normal'def handle_mouse_down(self, pos):if self.bounds.collidepoint(pos):self.state = 'pressed'def handle_mouse_up(self, pos):if self.state == 'pressed':self.on_click(self)self.state = 'hover'

用于绘制背景矩形的back_color属性始终返回与按钮当前状态匹配的颜色,因此玩家可以清楚按钮处于活动状态:

@property
def back_color(self):return dict(normal=c.button_normal_back_color,hover=c.button_hover_back_color,pressed=c.button_pressed_back_color)[self.state]

创建菜单

create_menu()函数创建一个带有两个按钮的菜单,其中包含文本“ PLAY”和“ QUIT”。 它具有两个嵌套函数,分别提供给相应的按钮on_play()on_quit() 。 每个按钮都添加到objects列表(要绘制)中,也添加到menu_buttons字段中。

def create_menu(self):for i, (text, handler) in enumerate((('PLAY', on_play), ('QUIT', on_quit))):b = Button(c.menu_offset_x,c.menu_offset_y + (c.menu_button_h + 5) * i,c.menu_button_w,c.menu_button_h,text,handler,padding=5)self.objects.append(b)self.menu_buttons.append(b)self.mouse_handlers.append(b.handle_mouse_event)

单击“播放”按钮时,将调用on_play(),这会将按钮从objects列表中删除,因此不再绘制它们。 同样,触发游戏开始的布尔值字段is_game_runningstart_level设置为True。

单击“退出”按钮时, is_game_running设置为False (有效地暂停游戏),而game_over设置为True,触发结束游戏序列。

def on_play(button):for b in self.menu_buttons:self.objects.remove(b)self.is_game_running = Trueself.start_level = Truedef on_quit(button):self.game_over = Trueself.is_game_running = False

显示和隐藏游戏菜单

显示和隐藏菜单是隐式的。 当按钮在objects列表中时,菜单可见。 当它们被删除时,它是隐藏的。 就如此容易。

可以使用其自己的表面创建一个嵌套菜单,以呈现诸如按钮等之类的子组件,然后只需添加/删除该菜单组件,但是此简单菜单不需要它。

结论

在这一部分中,我们介绍了碰撞检测以及当球撞击桨,砖块,墙壁,天花板和地板等各种物体时发生的情况。 此外,我们还创建了带有自定义按钮的菜单,这些按钮可在命令中隐藏和显示。

在本系列的最后一部分,我们将研究最终游戏,密切关注乐谱,生活,音效和音乐。

然后,我们将开发一个复杂的特殊效果系统,为游戏增添趣味。 最后,我们将讨论未来的方向和潜在的改进。

翻译自: https://code.tutsplus.com/tutorials/building-games-with-python-3-and-pygame-part-4--cms-30084

使用Python 3和Pygame构建游戏:第4部分相关推荐

  1. 使用Python 3和Pygame构建游戏:第1部分

    总览 许多开发人员进入软件开发是因为他们想开发游戏. 并非每个人都可以成为专业的游戏开发人员,但是每个人都可以出于娱乐目的甚至可能自己的利益而制作自己的游戏. 在这个由五部分组成的系列文章中,我将向您 ...

  2. python中的pygame弹球游戏代码_pygame弹球游戏

    pygame弹球游戏 写的很简陋 pip install pygame 安装pygame模块 代码,复制运行即可 import pygame import random pygame.init() w ...

  3. python中的pygame弹球游戏代码_pygame实现弹球游戏

    本文实例为大家分享了pygame实现弹球游戏的具体代码,供大家参考,具体内容如下 pygame弹球游戏 写的很简陋 pip install pygame 安装pygame模块 代码,复制运行即可 im ...

  4. python中的pygame弹球游戏代码_python pygame实现挡板弹球游戏

    学了一天pygame,用python和pygame写一个简单的挡板弹球游戏 GitHub: # -*- coding:utf-8 -*- from sys import exit import pyg ...

  5. python中的pygame弹球游戏代码_【pygame系列 第三课 弹球游戏-上 】

    python我们可以做文字版的游戏,比如猜数字游戏,21点游戏.那python可以做图形界面的游戏吗?偷偷告诉你,用pygame库就可以实现了.pygame是python中专门用来编写游戏的一个引擎库 ...

  6. python中的pygame弹球游戏代码_使用python和pygame制作挡板弹球游戏

    python是个很有趣的语言,可以在cmd命令窗口运行,还有很多的功能强大的模块. 学了一天pygame,用python和pygame写一个简单的挡板弹球游戏. 2018年6月21日 00:15:21 ...

  7. Python学习模块 Pygame写游戏三(太空大战)

    3.导入 飞船图片, def run_game():ai_settings=Settings()screen = pygame.display.set_mode((ai_settings.screen ...

  8. 使用 Python 和 Pygame 构建小行星游戏

    原文地址:https://realpython.com/asteroids-game-python/ 教程的电子文档:下载 模块pygame的官方网址:https://www.pygame.org/d ...

  9. 使用 Pygame 构建和可视化数独游戏

    使用 Pygame 构建和可视化数独游戏 原文地址 数独是一个基于逻辑的组合数字放置谜题.目标是用数字填充 9×9 网格,以便每一列.每一行和组成网格的九个 3×3 子网格中的每一个都包含从 1 到 ...

最新文章

  1. 企业网络推广专员浅析如何完善网站维护企业网络推广吸引用户浏览
  2. 3.4 改进集束搜索-深度学习第五课《序列模型》-Stanford吴恩达教授
  3. 机器学习和计算机视觉有关的数学
  4. 网络摄像头3 cmos ov9650,plugins/input_s3c2410/
  5. 让S3c2410里拥有HIVE注册表的 全部步骤
  6. MySQL—赋权(grant)和回收权限(revoke)
  7. 多线程的概念及实现方式
  8. python sqlalchemy orm
  9. java 方法调用表达式_java lambda怎么表达式判断被调用接口名称和接口中方法
  10. YouTube架构学习
  11. triz矛盾矩阵_怎样利用项目TRIZ矛盾定义法,突破产品“创
  12. VS2013的下载与安装
  13. 玩转华为ENSP模拟器系列 | 配置OSPF ABR路由聚合示例
  14. oracle am时间,oracle里to_date()如何转换am、pm时间
  15. 2022081班李亚楠20220901
  16. 《Unity3d实战就业路线》
  17. Error:Module ‘javase‘ production: java.lang.ClassCastException:
  18. 苹果新品发布会:几张图片告诉你苹果发布会新品亮点
  19. 【大数据平台】基于Spark的美国新冠肺炎疫情数据分析及预测
  20. evo_rpe 指令介绍及使用

热门文章

  1. 浅谈0欧姆电阻在电路中的作用
  2. 表 62623266 的索引 ID 1 中找不到索引条目。指示的索引已损坏,或当前的更新计划有问题。。
  3. python实现十大经典算法
  4. 全球与中国无人机数据分析市场深度研究分析报告
  5. 《Mysql必知必会》笔记(一)
  6. Camera开发—如何使用系统相机
  7. python自带哪些包_python各个包的用途
  8. 自然语言处理学习笔记7:特征选择方法
  9. AI 诗人:一首关于爱情的诗
  10. php 5.2.16,windows中PHP5.2.14以及apache2.2.16安装配置示例