使用Pygame制作“打砖块”游戏
1. 前言
打砖块(Breakout / Arkanoid) 是一款经典街机游戏,玩家控制一个可左右移动的挡板,接住并反弹球,击碎屏幕上方的砖块。随着砖块被击碎,不仅能获得分数,还可以体验到不断加速或复杂的反弹乐趣。 在本篇文章里,我们将使用 Python 3.x + Pygame 库,手把手实现一个简易版本的打砖块游戏,包含最核心的移动、碰撞和得分功能。
2. 开发环境与准备
- Python 3.x
- Pygame:若尚未安装,可通过命令
pip install pygame进行安装。 - 桌面系统:Windows、macOS 或绝大多数 Linux 桌面环境都能正常使用 Pygame。
安装完成后,使用 import pygame 测试是否成功即可。
3. 游戏思路
要完成一个打砖块游戏,需要实现以下几个关键模块:
-
挡板(Paddle)
- 位于屏幕底部,可左右移动。
- 通过键盘或鼠标控制位置。
-
球(Ball)
- 从挡板上方出发,向上运动;
- 在碰到墙壁时发生反弹;
- 在碰到挡板或砖块时,需要计算反弹方向,并可能击碎砖块、加分。
-
砖块(Bricks)
- 通常在屏幕上方排列成若干行;
- 一旦被球击中,会被击碎并增加分数;
- 也可以设定一些特殊砖块,击中后会产生道具等(此处仅做简易实现)。
-
游戏结束
- 若球掉出屏幕底部则表示丢失一条命,或者直接游戏结束;
- 如果所有砖块都被击碎,则玩家胜利。
4. 完整示例代码
将以下示例保存为 breakout_game.py 并运行,即可体验一个最基本的打砖块游戏。你也可以根据需求自由添加更多功能或美化界面。
import pygame
import sys
import random# 初始化 Pygame
pygame.init()# ----------------------
# 全局配置
# ----------------------
WIDTH, HEIGHT = 600, 600 # 游戏窗口大小
FPS = 60 # 帧率# 颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (100, 100, 100)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)# 游戏窗口
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("打砖块 - Pygame 示例")
clock = pygame.time.Clock()# 字体
font = pygame.font.SysFont("arial", 24)# ----------------------
# 挡板类
# ----------------------
class Paddle:def __init__(self):self.width = 100self.height = 15self.x = (WIDTH - self.width) // 2self.y = HEIGHT - 50self.speed = 8def draw(self, surface):pygame.draw.rect(surface, BLUE, (self.x, self.y, self.width, self.height))def move_left(self):self.x -= self.speedif self.x < 0:self.x = 0def move_right(self):self.x += self.speedif self.x + self.width > WIDTH:self.x = WIDTH - self.width# ----------------------
# 球类
# ----------------------
class Ball:def __init__(self, paddle):self.radius = 8self.x = paddle.x + paddle.width // 2self.y = paddle.y - 10# 球初始速度self.speed_x = random.choice([-4, 4])self.speed_y = -4def draw(self, surface):pygame.draw.circle(surface, RED, (int(self.x), int(self.y)), self.radius)def update(self, paddle, bricks):"""更新球的位置、检查墙体碰撞、挡板碰撞和砖块碰撞"""self.x += self.speed_xself.y += self.speed_y# 碰撞左右墙if self.x - self.radius < 0:self.x = self.radiusself.speed_x = -self.speed_xelif self.x + self.radius > WIDTH:self.x = WIDTH - self.radiusself.speed_x = -self.speed_x# 碰撞上墙if self.y - self.radius < 0:self.y = self.radiusself.speed_y = -self.speed_y# 掉到底部 -> 游戏结束的处理可在主循环中判断# if self.y + self.radius > HEIGHT:# pass# 碰撞挡板if (self.x > paddle.x and self.x < paddle.x + paddle.widthand self.y + self.radius > paddle.yand self.y - self.radius < paddle.y + paddle.height):self.speed_y = -self.speed_y# 球可能根据撞击位置微调水平速度(可选)# self.speed_x += random.choice([-1, 0, 1])# 碰撞砖块for brick in bricks[:]:if (self.x + self.radius > brick.xand self.x - self.radius < brick.x + brick.widthand self.y + self.radius > brick.yand self.y - self.radius < brick.y + brick.height):bricks.remove(brick)self.speed_y = -self.speed_y # 简化反弹,只改变垂直方向return 10 # 得分10return 0# ----------------------
# 砖块类
# ----------------------
class Brick:def __init__(self, x, y, width, height, color=GREEN):self.x = xself.y = yself.width = widthself.height = heightself.color = colordef draw(self, surface):pygame.draw.rect(surface, self.color, (self.x, self.y, self.width, self.height))pygame.draw.rect(surface, BLACK, (self.x, self.y, self.width, self.height), 1) # 边框def create_bricks(rows=5, cols=8):"""创建指定行列的砖块,返回列表"""bricks = []brick_width = (WIDTH - 40) // colsbrick_height = 20x_offset = 20y_offset = 40for row in range(rows):for col in range(cols):x = x_offset + col * brick_widthy = y_offset + row * brick_heightcolor = random.choice([GREEN, YELLOW, GRAY, BLUE])brick = Brick(x, y, brick_width, brick_height, color)bricks.append(brick)return bricks# ----------------------
# 主函数
# ----------------------
def main():paddle = Paddle()ball = Ball(paddle)bricks = create_bricks(rows=5, cols=8)score = 0running = Truewhile running:clock.tick(FPS)for event in pygame.event.get():if event.type == pygame.QUIT:running = False# 键盘输入keys = pygame.key.get_pressed()if keys[pygame.K_LEFT]:paddle.move_left()if keys[pygame.K_RIGHT]:paddle.move_right()# 更新球的位置gained_score = ball.update(paddle, bricks)score += gained_score# 判断游戏结束:如果球掉到底部 or 砖块全部消失if ball.y - ball.radius > HEIGHT:# 球掉出底部running = Falseif len(bricks) == 0:# 所有砖块被击破running = False# 绘制screen.fill(BLACK)# 画砖块for brick in bricks:brick.draw(screen)# 画挡板和球paddle.draw(screen)ball.draw(screen)# 显示分数text_surface = font.render(f"Score: {score}", True, WHITE)screen.blit(text_surface, (10, 10))pygame.display.flip()# 游戏结束后显示结果game_over(score)def game_over(score):"""游戏结束界面"""screen.fill(GRAY)msg = f"Game Over! Your Score: {score}"label = font.render(msg, True, BLACK)# 居中显示rect = label.get_rect(center=(WIDTH // 2, HEIGHT // 2))screen.blit(label, rect)pygame.display.flip()pygame.time.wait(3000)pygame.quit()sys.exit()if __name__ == "__main__":main()
核心逻辑解读
-
Paddle(挡板)
- 只需实现水平移动;
- 在超出屏幕边界时,强制回到合法范围内。
-
Ball(球)
- 通过
self.x,self.y表示球心位置,self.speed_x,self.speed_y表示当前水平和垂直速度; - 每帧更新时,先加上速度;遇到左右墙、上墙时反转速度;遇到底部则表示掉落。
- 在与挡板或砖块相交时,需要根据碰撞方向做出相应反弹。
- 通过
-
Brick(砖块)
- 仅保存坐标、宽高、颜色;
- 被击中后从列表中移除。
-
碰撞检测
- 简化实现:只要球的圆心与砖块矩形区域重叠即可判断为碰撞;
- 在真实游戏中,可以做更精确的检测(圆与矩形边的距离、角度等)或更细致的物理反弹。
-
游戏结束
- 玩家失败:球掉出屏幕底部;
- 玩家胜利:所有砖块被清除。
5. 实现效果


6. 总结
通过本篇文章,你已经学会了如何使用 Python + Pygame 从零构建一个基础的打砖块游戏。该示例涵盖了碰撞检测、游戏循环、对象管理等常见2D游戏开发中的核心逻辑。你可以在此基础上自由发挥,加入更多道具、特效和关卡,从而打造一个更完整、更丰富的打砖块游戏。
相关文章:
使用Pygame制作“打砖块”游戏
1. 前言 打砖块(Breakout / Arkanoid) 是一款经典街机游戏,玩家控制一个可左右移动的挡板,接住并反弹球,击碎屏幕上方的砖块。随着砖块被击碎,不仅能获得分数,还可以体验到不断加速或复杂的反弹…...
【完整版】DeepSeek-R1大模型学习笔记(架构、训练、Infra)
文章目录 0 DeepSeek系列总览1 模型架构设计基本参数专家混合模型(MoE)[DeepSeek-V2提出, DeepSeek-V3改良]多头潜在注意力(MLA)[DeepSeek-V2提出]多token预测(MTP)[DeepSeek-V3提出] 2 DeepSeek-R1-Zero及…...
深入解析:如何利用 Python 爬虫获取商品 SKU 详细信息
在电商领域,SKU(Stock Keeping Unit,库存单位)详细信息是电商运营的核心数据之一。它不仅包含了商品的规格、价格、库存等关键信息,还直接影响到库存管理、价格策略和市场分析等多个方面。本文将详细介绍如何利用 Pyth…...
【3】高并发导出场景下,服务器性能瓶颈优化方案-文件压缩
使用EasyExcel导出并压缩文件是一种高效且常见的解决方案,尤其适用于需要处理大量数据的场景。 1. 导出多个Excel文件并压缩成ZIP文件的基本流程 (1)数据准备:从数据库或其他数据源获取需要导出的数据,并将其存储在Ja…...
FPGA|生成jic文件固化程序到flash
1、单击file-》convert programming files 2、flie type中选中jic文件,configuration decive里根据自己的硬件选择,单击flash loader选择右边的add device选项 3、选择自己的硬件,单击ok 4、选中sof选项,单机右侧的add file 5、选…...
【ArcGIS_Python】使用arcpy脚本将shape数据转换为三维白膜数据
说明: 该专栏之前的文章中python脚本使用的是ArcMap10.6自带的arcpy(好几年前的文章),从本篇开始使用的是ArcGIS Pro 3.3.2版本自带的arcpy,需要注意不同版本对应的arcpy函数是存在差异的 数据准备:准备一…...
用Python获取股票数据并实现未来收盘价的预测
获取数据 先用下面这段代码获取上证指数的历史数据,得到的csv文件数据,为后面训练模型用的 import akshare as ak import pandas as pd# 获取上证指数历史数据 df ak.stock_zh_index_daily(symbol"sh000001")# 将数据保存到本地CSV文件 df.…...
Rust 所有权特性详解
Rust 所有权特性详解 Rust 的所有权系统是其内存安全的核心机制之一。通过所有权规则,Rust 在编译时避免了常见的内存错误(如空指针、数据竞争等)。本文将从堆内存与栈内存、所有权规则、变量作用域、String 类型、内存分配、所有权移动、Cl…...
Gateway路由匹配规则详解
在微服务架构中,Gateway作为请求的入口,扮演着至关重要的角色。它不仅负责路由转发,还具备安全、监控、限流等多种功能。其中,路由匹配规则是Gateway的核心功能之一,它决定了请求如何被正确地转发到目标服务。本文将详…...
项目实操:windows批处理拉取git库和处理目录、文件
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
前端开发知识梳理 - HTMLCSS
1. 盒模型 由内容区(content)、内边距(padding)、边框(border)和外边距(margin)组成。 (1)标准盒模型(box-sizing默认值, content-boxÿ…...
nginx中的proxy_set_header参数详解
在使用 Nginx 作为反向代理服务器时,proxy_set_header 指令扮演着至关重要的角色。它允许我们自定义请求头信息,将客户端请求传递给上游服务器时,添加或修改特定的信息,从而实现更灵活的代理功能。本文将深入探讨 proxy_set_heade…...
MapReduce是什么?
MapReduce 是一种编程模型,最初由 Google 提出,旨在处理大规模数据集。它是分布式计算的一个重要概念,通常用于处理海量数据并进行并行计算。MapReduce的基本思想是将计算任务分解为两个阶段:Map 阶段和 Reduce 阶段。 Map 阶段&a…...
Text2Sql:开启自然语言与数据库交互新时代(3030)
一、Text2Sql 简介 在当今数字化时代,数据处理和分析的需求日益增长。对于众多非技术专业人员而言,数据库操作的复杂性常常成为他们获取所需信息的障碍。而 Text2Sql 技术的出现,为这一问题提供了有效的解决方案。 Text2Sql,即文…...
《图解设计模式》笔记(五)一致性
十一、Composite模式:容器与内容的一致性 像文件夹与文件一样,文件夹中可以放子文件夹与文件,再比如容器中可以放更小的容器和具体内容。 Composite模式:使容器与内容具有一致性,创造出递归结构。 Composite&#x…...
华为支付-免密支付接入免密代扣说明
免密代扣包括支付并签约以及签约代扣场景。 开发者接入免密支付前需先申请开通签约代扣产品(即申请配置免密代扣模板及协议模板ID)。 华为支付以模板维度管理每一个代扣扣费服务,主要组成要素如下: 接入免密支付需注意&#x…...
React组件中的列表渲染与分隔符处理技巧
React组件中的列表渲染与分隔符处理技巧 摘要问题背景解决方案分析方案一:数组拼接法方案二:Fragment组件方案三:动态生成key 关键技术点1. key的使用原则2. Fragment组件3. 性能优化 实战演练挑战1:动态分隔符样式挑战2ÿ…...
【Pytorch和Keras】使用transformer库进行图像分类
目录 一、环境准备二、基于Pytorch的预训练模型1、准备数据集2、加载预训练模型3、 使用pytorch进行模型构建 三、基于keras的预训练模型四、模型测试五、参考 现在大多数的模型都会上传到huggface平台进行统一的管理,transformer库能关联到huggface中对应的模型&am…...
快速了解 c++ 异常处理 基础知识
相关代码概览: #include<stdexcept>std::runtime_errorcatch (const std::runtime_error& e) e.what() 相信大家一定见过这些代码,那么这些代码具体什么意思呢?我们一起来看一下 知识精讲: 异常处理是C中非常重要…...
deepseek API 调用-python
【1】创建 API keys 【2】安装openai SDK pip3 install openai 【3】代码: https://download.csdn.net/download/notfindjob/90343352...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
