用 Pygame 实现一个乒乓球游戏
用 Pygame 实现一个乒乓球游戏
伸手需要一瞬间,牵手却要很多年,无论你遇见谁,他都是你生命该出现的人,绝非偶然。若无相欠,怎会相见。
引言
在这篇文章中,我将带领大家使用 Pygame 库开发一个简单的乒乓球游戏。Pygame 是 Python 中广泛使用的游戏开发库,提供了简单易用的 2D 游戏框架。我们将从最基本的游戏框架入手,逐步实现球的运动、球拍的移动、边界碰撞以及得分系统,最后为游戏添加一些细节优化,形成一个完整的乒乓球游戏。
开始之前
首先,你需要确保系统中已经安装了 Pygame。你可以使用以下命令进行安装:
pip install pygame
安装完 Pygame 后,我们可以开始编写代码了。
第一步:基本框架
我们先来创建一个基本的 Pygame 窗口,并在屏幕上绘制一个可移动的球。以下是初始的代码实现:
import pygame# 初始化Pygame
pygame.init()# 定义窗口大小和颜色
S_W, S_H = 800, 600
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)# 设置窗口
screen = pygame.display.set_mode((S_W, S_H))
pygame.display.set_caption("乒乓球")# 初始化球的属性
ball_x = S_W / 2
ball_y = S_H / 2
ball_radius = 20
ball_x_velocity = 3
ball_y_velocity = 3# 设置帧率
clock = pygame.time.Clock()# 游戏主循环
running = True
while running:for event in pygame.event.get():if event.type == pygame.QUIT:running = False# 移动球ball_x += ball_x_velocityball_y += ball_y_velocity# 碰到屏幕边界时反弹if ball_x - ball_radius < 0 or ball_x + ball_radius > S_W:ball_x_velocity *= -1if ball_y - ball_radius < 0 or ball_y + ball_radius > S_H:ball_y_velocity *= -1# 绘制背景和球screen.fill(BLACK)pygame.draw.circle(screen, (255, 0, 0), (int(ball_x), int(ball_y)), ball_radius)# 更新显示pygame.display.update()# 控制帧率clock.tick(60)# 退出游戏
pygame.quit()
解释
- 窗口设置:我们定义了窗口的宽度和高度(800x600),并设置窗口标题为"乒乓球"。
- 球的移动:我们通过更新球的
x
和y
坐标来实现球的移动,并在球碰到窗口边缘时反弹。 - 帧率控制:
pygame.time.Clock()
用于限制游戏的帧率,使游戏每秒钟刷新60次,保证运行的流畅性。
运行这段代码,你会看到一个红色的球在黑色背景上不断移动并在边界反弹。
第二步:添加球拍
现在我们要给游戏加入球拍。球拍可以通过键盘输入来控制,让它上下移动,从而和球进行交互。
# 球拍尺寸和初始位置
paddle_width, paddle_height = 25, 100
paddle1_x, paddle1_y = 50, (S_H - paddle_height) / 2 # 玩家1球拍
paddle2_x, paddle2_y = S_W - paddle_width - 50, (S_H - paddle_height) / 2 # 玩家2球拍# 更新球拍的位置
keys = pygame.key.get_pressed()
if keys[pygame.K_w] and paddle1_y > 0:paddle1_y -= 5
if keys[pygame.K_s] and paddle1_y < S_H - paddle_height:paddle1_y += 5
if keys[pygame.K_UP] and paddle2_y > 0:paddle2_y -= 5
if keys[pygame.K_DOWN] and paddle2_y < S_H - paddle_height:paddle2_y += 5# 绘制球拍
pygame.draw.rect(screen, WHITE, (paddle1_x, paddle1_y, paddle_width, paddle_height))
pygame.draw.rect(screen, WHITE, (paddle2_x, paddle2_y, paddle_width, paddle_height))
解释
- 球拍绘制:使用
pygame.draw.rect
函数绘制球拍,paddle1_x
和paddle1_y
控制玩家1的球拍位置,而paddle2_x
和paddle2_y
控制玩家2的球拍。 - 球拍移动:通过
pygame.key.get_pressed()
检测按键输入,W
和S
键控制玩家1的球拍上下移动,UP
和DOWN
键控制玩家2的球拍。
第三步:碰撞检测
为了让游戏更加真实,我们需要检测球是否碰撞到球拍并实现反弹效果。下面是球拍碰撞的代码:
# 碰撞检测 - 玩家1球拍
if paddle1_x < ball_x - ball_radius < paddle1_x + paddle_width and paddle1_y < ball_y < paddle1_y + paddle_height:ball_x_velocity *= -1# 碰撞检测 - 玩家2球拍
if paddle2_x < ball_x + ball_radius < paddle2_x + paddle_width and paddle2_y < ball_y < paddle2_y + paddle_height:ball_x_velocity *= -1
解释
- 碰撞检测:我们通过检测球的坐标是否进入球拍的区域来判断碰撞。当球与球拍碰撞时,改变球的
x
方向速度,使其反弹。
第四步:得分系统
我们需要为游戏添加一个得分系统,当球越过一方边界时,另一方得分。下面是添加得分系统的代码:
# 初始化得分
score1 = 0
score2 = 0# 检测得分
if ball_x - ball_radius < 0:score2 += 1 # 玩家2得分ball_x, ball_y = S_W / 2, S_H / 2 # 重置球的位置
if ball_x + ball_radius > S_W:score1 += 1 # 玩家1得分ball_x, ball_y = S_W / 2, S_H / 2 # 重置球的位置
第五步:添加文字显示
为了在屏幕上显示得分,我们需要使用 Pygame 的字体功能。以下是实现代码:
# 初始化字体
font = pygame.font.Font(None, 36)# 绘制得分
text1 = font.render(f"Player 1: {score1}", True, WHITE)
text2 = font.render(f"Player 2: {score2}", True, WHITE)
screen.blit(text1, (50, 50))
screen.blit(text2, (S_W - 200, 50))
第六步:添加游戏结束条件
最后,我们可以为游戏添加一个结束条件,比如当某一方得分达到5分时游戏结束:
if score1 >= 5 or score2 >= 5:running = False # 游戏结束
完整代码
以下是这个乒乓球游戏的完整代码:
import pygame# 屏幕和颜色设置
S_W, S_H = 800, 600
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)# 球和球拍设置
ball_x, ball_y = S_W / 2, S_H / 2
ball_radius = 20
ball_x_velocity, ball_y_velocity = 3, 3
paddle_width, paddle_height = 25, 100
paddle1_x, paddle1_y = 50, (S_H - paddle_height) / 2
paddle2_x, paddle2_y = S_W - paddle_width - 50, (S_H - paddle_height) / 2# 初始化Pygame
pygame.init()
screen = pygame.display.set_mode((S_W, S_H))
pygame.display.set_caption("乒乓球")
clock = pygame.time.Clock()# 初始化得分
score1, score2 = 0, 0
font = pygame.font.Font(None, 36)running = True
while running:for event in pygame.event.get():if event.type == pygame.QUIT:running = False# 球移动ball_x += ball_x_velocityball_y += ball_y_velocity# 边界反弹if ball_x - ball_radius < 0 or ball_x + ball_radius >S_W:ball_x_velocity *= -1if ball_y - ball_radius < 0 or ball_y + ball_radius > S_H:ball_y_velocity *= -1# 球拍移动keys = pygame.key.get_pressed()if keys[pygame.K_w] and paddle1_y > 0:paddle1_y -= 5if keys[pygame.K_s] and paddle1_y < S_H - paddle_height:paddle1_y += 5if keys[pygame.K_UP] and paddle2_y > 0:paddle2_y -= 5if keys[pygame.K_DOWN] and paddle2_y < S_H - paddle_height:paddle2_y += 5# 碰撞检测if paddle1_x < ball_x - ball_radius < paddle1_x + paddle_width and paddle1_y < ball_y < paddle1_y + paddle_height:ball_x_velocity *= -1if paddle2_x < ball_x + ball_radius < paddle2_x + paddle_width and paddle2_y < ball_y < paddle2_y + paddle_height:ball_x_velocity *= -1# 得分系统if ball_x - ball_radius < 0:score2 += 1ball_x, ball_y = S_W / 2, S_H / 2if ball_x + ball_radius > S_W:score1 += 1ball_x, ball_y = S_W / 2, S_H / 2# 绘制背景、球和球拍screen.fill(BLACK)pygame.draw.circle(screen, (255, 0, 0), (int(ball_x), int(ball_y)), ball_radius)pygame.draw.rect(screen, WHITE, (paddle1_x, paddle1_y, paddle_width, paddle_height))pygame.draw.rect(screen, WHITE, (paddle2_x, paddle2_y, paddle_width, paddle_height))# 显示得分text1 = font.render(f"Player 1: {score1}", True, WHITE)text2 = font.render(f"Player 2: {score2}", True, WHITE)screen.blit(text1, (50, 50))screen.blit(text2, (S_W - 200, 50))pygame.display.update()clock.tick(60)# 游戏结束if score1 >= 5 or score2 >= 5:running = Falsepygame.quit()
总结
通过这篇博客,你可以看到如何从零开始开发一个简单的乒乓球游戏。我们逐步实现了球的移动、球拍控制、碰撞检测、得分系统和游戏结束条件。你可以根据自己的需求继续改进和扩展这个游戏,比如加入背景音乐、增加更复杂的物理效果等。希望你通过这次实践掌握了使用 Pygame 开发游戏的基础技能!
相关文章:

用 Pygame 实现一个乒乓球游戏
用 Pygame 实现一个乒乓球游戏 伸手需要一瞬间,牵手却要很多年,无论你遇见谁,他都是你生命该出现的人,绝非偶然。若无相欠,怎会相见。 引言 在这篇文章中,我将带领大家使用 Pygame 库开发一个简单的乒乓球…...

基于大数据可视化的化妆品推荐及数据分析系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…...

Java项目实战II基于Java+Spring Boot+MySQL的汽车销售网站(文档+源码+数据库)
目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在数字化时…...
数学基础 -- 微积分最优化之一个最简单的例子
微积分中的一个最简单的最优化例子 问题描述 假设你有一条长度为 10 米的栅栏,你需要围成一个矩形的鸡舍,使得围成的面积最大。求这个矩形的长和宽应是多少,以使得面积最大。 步骤 设定变量: 设矩形的长为 x x x 米࿰…...

kubernetes K8S 结合 Istio 实现流量治理
目录 1.Istio介绍? 1.1 Istio是什么? 1.2 Istio流量管理 1.2.1 熔断 1.2.2 超时 1.2.3 重试 2.Istio架构 3.istio组件详解 3.1 Pilot 3.2 Envoy 3.3 Citadel 3.4 Galley 3.5 Ingressgateway 3.5 egressgateway 扩展、k8s1.23及1.23以下版…...

Selenium with Python学习笔记整理(网课+网站持续更新)
本篇是根据学习网站和网课结合自己做的学习笔记,后续会一边学习一边补齐和整理笔记 非常推荐白月黑羽的学习网站: 白月黑羽 (byhy.net) https://selenium-python.readthedocs.io/getting-started.html#simple-usage WEB UI自动化环境配置 (推荐靠谱…...

1.随机事件与概率
第一章 随机时间与概率 1. 随机事件及其运算 1.1 随机现象 确定性现象:只有一个结果的现象 确定性现象:结果不止一个,且哪一个结果出现,人们事先并不知道 1.2 样本空间 样本空间:随机现象的一切可能基本…...
Redis结合Caffeine实现二级缓存:提高应用程序性能
本文将详细介绍如何使用CacheFrontend和Caffeine来实现二级缓存。 1. 简介 CacheFrontend: 是一种用于缓存的前端组件或服务。通俗的讲:该接口可以实现本地缓存与redis自动同步,如果本地缓存(JVM级)有数据,则直接从本…...
【LLM】Ollama:本地大模型 WebAPI 调用
Ollama 快速部署 安装 Docker:从 Docker 官网 下载并安装。 部署 Ollama: 使用以下命令进行部署: docker run -d -p 11434:11434 --name ollama --restart always ollama/ollama:latest进入容器并下载 qwen2.5:0.5b 模型: 进入 O…...
SpringBoot集成阿里easyexcel(二)Excel监听以及常用工具类
EasyExcel中非常重要的AnalysisEventListener类使用,继承该类并重写invoke、doAfterAllAnalysed,必要时重写onException方法。 Listener 中方法的执行顺序 首先先执行 invokeHeadMap() 读取表头,每一行都读完后,执行 invoke()方法…...
使用ELK Stack进行日志管理和分析:从入门到精通
在现代IT运维中,日志管理和分析是确保系统稳定性和性能的关键环节。ELK Stack(Elasticsearch, Logstash, Kibana)是一个强大的开源工具集,广泛用于日志收集、存储、分析和可视化。本文将详细介绍如何使用ELK Stack进行日志管理和分…...

前端框架对比与选择
🤖 作者简介:水煮白菜王 ,一位资深前端劝退师 👻 👀 文章专栏: 前端专栏 ,记录一下平时在博客写作中,总结出的一些开发技巧✍。 感谢支持💕💕💕 目…...

Springboot jPA+thymeleaf实现增删改查
项目结构 pom文件 配置相关依赖: 2.thymeleaf有点类似于jstlel th:href"{url}表示这是一个链接 th:each"user : ${users}"相当于foreach,对user进行循环遍历 th:if进行if条件判断 {变量} 与 ${变量}的区别: 4.配置好application.ym…...

【YashanDB知识库】yashandb执行包含带oracle dblink表的sql时性能差
本文内容来自YashanDB官网,具体内容请见https://www.yashandb.com/newsinfo/7396959.html?templateId1718516 问题现象 yashandb执行带oracle dblink表的sql性能差: 同样的语句,同样的数据,oracle通过dblink访问远端oracle执行…...

效率工具推荐 | 高效管理客服中心知识库
人工智能AI的广泛应用,令AI知识库管理已成为优化客服中心运营的核心策略之一。一个高效、易用且持续更新的知识库不仅能显著提升客服代表的工作效率,还能极大提升客户的服务体验。而高效效率工具如HelpLook,能够轻松搭建AI客服帮助中心&#…...

综合实验1 利用OpenCV统计物体数量
一、实验简介 传统的计数方法常依赖于人眼目视计数,不仅计数效率低,且容易计数错误。通常现实中的对象不会完美地分开,需要通过进一步的图像处理将对象分开并计数。本实验巩固对OpenCV的基础操作的使用,适当的增加OpenCV在图像处…...

[Redis][主从复制][上]详细讲解
目录 0.前言1.配置1.建立复制2.断开复制3.安全性4.只读5.传输延迟 2.拓扑1.一主一从结构2.一主多从结构2.树形主从结构 0.前言 说明:该章节相关操作不需要记忆,理解流程和原理即可,用的时候能自主查到即可主从复制? 分布式系统中…...
【算法】leetcode热题100 146.LRU缓存. container/list用法
https://leetcode.cn/problems/lru-cache/description/?envTypestudy-plan-v2&envIdtop-100-liked 实现语言:go lang LRU 最近最少未使用,是一种淘汰策略,当缓存空间不够使用的时候,淘汰一个最久没有访问的存储单元。目前…...
[论文总结] 深度学习在农业领域应用论文笔记13
文章目录 1. Downscaling crop production data to fine scale estimates with geostatistics and remote sensing: a case study in mapping cotton fibre quality (Precision Agriculture ,2024, IF5.585)背景方法结果结论个人总…...

《Detection of Tea Leaf Blight in Low-Resolution UAV Remote Sensing Images》论文阅读
学习资料 论文题目:Detection of Tea Leaf Blight in Low-Resolution UAV Remote Sensing Images(低分辨率UAV遥感图像中茶叶枯萎病的检测)论文地址:https://ieeexplore.ieee.org/stamp/stamp.jsp?tp&arnumber10345618 Abstr…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...