当前位置: 首页 > news >正文

用 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()

解释

  1. 窗口设置:我们定义了窗口的宽度和高度(800x600),并设置窗口标题为"乒乓球"。
  2. 球的移动:我们通过更新球的 xy 坐标来实现球的移动,并在球碰到窗口边缘时反弹。
  3. 帧率控制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))

解释

  1. 球拍绘制:使用 pygame.draw.rect 函数绘制球拍,paddle1_xpaddle1_y 控制玩家1的球拍位置,而 paddle2_xpaddle2_y 控制玩家2的球拍。
  2. 球拍移动:通过 pygame.key.get_pressed() 检测按键输入,WS 键控制玩家1的球拍上下移动,UPDOWN 键控制玩家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

解释

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

基于大数据可视化的化妆品推荐及数据分析系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…...

Java项目实战II基于Java+Spring Boot+MySQL的汽车销售网站(文档+源码+数据库)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在数字化时…...

数学基础 -- 微积分最优化之一个最简单的例子

微积分中的一个最简单的最优化例子 问题描述 假设你有一条长度为 10 米的栅栏&#xff0c;你需要围成一个矩形的鸡舍&#xff0c;使得围成的面积最大。求这个矩形的长和宽应是多少&#xff0c;以使得面积最大。 步骤 设定变量&#xff1a; 设矩形的长为 x x x 米&#xff0…...

kubernetes K8S 结合 Istio 实现流量治理

目录 1.Istio介绍&#xff1f; 1.1 Istio是什么&#xff1f; 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学习笔记整理(网课+网站持续更新)

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

1.随机事件与概率

第一章 随机时间与概率 1. 随机事件及其运算 1.1 随机现象 ​ 确定性现象&#xff1a;只有一个结果的现象 ​ 确定性现象&#xff1a;结果不止一个&#xff0c;且哪一个结果出现&#xff0c;人们事先并不知道 1.2 样本空间 ​ 样本空间&#xff1a;随机现象的一切可能基本…...

Redis结合Caffeine实现二级缓存:提高应用程序性能

本文将详细介绍如何使用CacheFrontend和Caffeine来实现二级缓存。 1. 简介 CacheFrontend: 是一种用于缓存的前端组件或服务。通俗的讲&#xff1a;该接口可以实现本地缓存与redis自动同步&#xff0c;如果本地缓存&#xff08;JVM级&#xff09;有数据&#xff0c;则直接从本…...

【LLM】Ollama:本地大模型 WebAPI 调用

Ollama 快速部署 安装 Docker&#xff1a;从 Docker 官网 下载并安装。 部署 Ollama&#xff1a; 使用以下命令进行部署&#xff1a; docker run -d -p 11434:11434 --name ollama --restart always ollama/ollama:latest进入容器并下载 qwen2.5:0.5b 模型&#xff1a; 进入 O…...

SpringBoot集成阿里easyexcel(二)Excel监听以及常用工具类

EasyExcel中非常重要的AnalysisEventListener类使用&#xff0c;继承该类并重写invoke、doAfterAllAnalysed&#xff0c;必要时重写onException方法。 Listener 中方法的执行顺序 首先先执行 invokeHeadMap() 读取表头&#xff0c;每一行都读完后&#xff0c;执行 invoke()方法…...

使用ELK Stack进行日志管理和分析:从入门到精通

在现代IT运维中&#xff0c;日志管理和分析是确保系统稳定性和性能的关键环节。ELK Stack&#xff08;Elasticsearch, Logstash, Kibana&#xff09;是一个强大的开源工具集&#xff0c;广泛用于日志收集、存储、分析和可视化。本文将详细介绍如何使用ELK Stack进行日志管理和分…...

前端框架对比与选择

&#x1f916; 作者简介&#xff1a;水煮白菜王 &#xff0c;一位资深前端劝退师 &#x1f47b; &#x1f440; 文章专栏&#xff1a; 前端专栏 &#xff0c;记录一下平时在博客写作中&#xff0c;总结出的一些开发技巧✍。 感谢支持&#x1f495;&#x1f495;&#x1f495; 目…...

Springboot jPA+thymeleaf实现增删改查

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

【YashanDB知识库】yashandb执行包含带oracle dblink表的sql时性能差

本文内容来自YashanDB官网&#xff0c;具体内容请见https://www.yashandb.com/newsinfo/7396959.html?templateId1718516 问题现象 yashandb执行带oracle dblink表的sql性能差&#xff1a; 同样的语句&#xff0c;同样的数据&#xff0c;oracle通过dblink访问远端oracle执行…...

效率工具推荐 | 高效管理客服中心知识库

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

综合实验1 利用OpenCV统计物体数量

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

[Redis][主从复制][上]详细讲解

目录 0.前言1.配置1.建立复制2.断开复制3.安全性4.只读5.传输延迟 2.拓扑1.一主一从结构2.一主多从结构2.树形主从结构 0.前言 说明&#xff1a;该章节相关操作不需要记忆&#xff0c;理解流程和原理即可&#xff0c;用的时候能自主查到即可主从复制&#xff1f; 分布式系统中…...

【算法】leetcode热题100 146.LRU缓存. container/list用法

https://leetcode.cn/problems/lru-cache/description/?envTypestudy-plan-v2&envIdtop-100-liked 实现语言&#xff1a;go lang LRU 最近最少未使用&#xff0c;是一种淘汰策略&#xff0c;当缓存空间不够使用的时候&#xff0c;淘汰一个最久没有访问的存储单元。目前…...

[论文总结] 深度学习在农业领域应用论文笔记13

文章目录 1. Downscaling crop production data to fine scale estimates with geostatistics and remote sensing: a case study in mapping cotton fibre quality &#xff08;Precision Agriculture &#xff0c;2024&#xff0c; IF5.585&#xff09;背景方法结果结论个人总…...

《Detection of Tea Leaf Blight in Low-Resolution UAV Remote Sensing Images》论文阅读

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

区块链+AI的致命组合:深扒某DeFi项目的测试黑幕

在数字经济浪潮中&#xff0c;区块链与人工智能&#xff08;AI&#xff09;的融合被视为金融创新的“致命组合”&#xff0c;尤其在去中心化金融&#xff08;DeFi&#xff09;领域&#xff0c;它承诺了前所未有的效率和智能决策能力。然而&#xff0c;这一组合也带来了隐蔽的测…...

ESP32-S3驱动JW01二氧化碳传感器:从供电陷阱到数据解析的实战指南

1. 硬件连接&#xff1a;电压匹配是生死线 第一次拿到JW01传感器时&#xff0c;我像往常一样顺手接上了ESP32-S3开发板的5V引脚——毕竟大多数传感器模块都标着"5V供电"的字样。结果串口监视器里一片死寂&#xff0c;连乱码都没有。翻出万用表测量才发现&#xff0c;…...

群晖7.2 Docker小白也能搞定:手把手教你部署WPS Office并绑定自己的域名

群晖7.2 Docker部署WPS Office全攻略&#xff1a;从零搭建专属云端办公平台 在数字化办公时代&#xff0c;拥有一个随时可访问的私有化办公套件不仅能提升团队协作效率&#xff0c;更能确保数据安全。本文将带你一步步在群晖NAS上通过Docker部署WPS Office&#xff0c;并绑定专…...

如何突破教育资源壁垒?智能解析工具让电子课本获取效率提升200%

如何突破教育资源壁垒&#xff1f;智能解析工具让电子课本获取效率提升200% 【免费下载链接】tchMaterial-parser 国家中小学智慧教育平台 电子课本下载工具&#xff0c;帮助您从智慧教育平台中获取电子课本的 PDF 文件网址并进行下载&#xff0c;让您更方便地获取课本内容。 …...

如何在Linux系统中快速找到文件:FSearch终极文件搜索工具完整指南

如何在Linux系统中快速找到文件&#xff1a;FSearch终极文件搜索工具完整指南 【免费下载链接】fsearch A fast file search utility for Unix-like systems based on GTK3 项目地址: https://gitcode.com/gh_mirrors/fs/fsearch 在Linux系统中寻找特定文件常常令人头疼…...

2026年AI就业风口!这5个神仙岗位,高薪低门槛,普通人也能转行!

根据LinkedIn数据&#xff0c;2026年AI相关岗位增长迅猛&#xff0c;其中AI咨询顾问、机器学习工程师、AI产品经理、数据与检索工程师等岗位需求旺盛&#xff0c;且部分岗位对计算机科学学位要求不高。文章详细介绍了这5个岗位的火热原因、转行路径及薪资范围&#xff0c;并给出…...

完整贡献指南:如何为endoflife.date添加新的产品支持信息

完整贡献指南&#xff1a;如何为endoflife.date添加新的产品支持信息 【免费下载链接】endoflife.date Informative site with EoL dates of everything 项目地址: https://gitcode.com/gh_mirrors/en/endoflife.date 你是否想为开源项目贡献自己的力量&#xff0c;但不…...

如何高效管理LiteDB数据库?LiteDB.Studio实战指南与深度解析

如何高效管理LiteDB数据库&#xff1f;LiteDB.Studio实战指南与深度解析 【免费下载链接】LiteDB.Studio A GUI tool for viewing and editing documents for LiteDB v5 项目地址: https://gitcode.com/gh_mirrors/li/LiteDB.Studio 在现代软件开发中&#xff0c;嵌入式…...

项目管理和技术管理的区别

在单位从事管理岗快2年了&#xff0c;负责单位内的研发项目管理和技术管理工作。感觉这是两个不同的管理赛道。其中项目管理侧重进度、资源、风险、责任人、排期等要素推进和汇报。技术管理则侧重研发环节的技术深度、技术方向、技术领先性、技术栈&#xff0c;以及项目产出的质…...

Pixel Epic动态卷轴效果展示:从空白屏幕到完整研报的实时生成录屏

Pixel Epic动态卷轴效果展示&#xff1a;从空白屏幕到完整研报的实时生成录屏 1. 引言&#xff1a;当科研遇上像素冒险 在传统的研究报告撰写过程中&#xff0c;我们常常面对冰冷的界面和机械化的交互体验。Pixel Epic彻底改变了这一现状&#xff0c;将严肃的学术研究变成了一…...