使用Pygame做一个乒乓球游戏(2)使用精灵重构

本节没有添加新的功能,而是将前面的功能使用精灵类(pygame.sprite.Sprite) 重构。
顺便我们使用图片美化了一下程序。
在这里插入图片描述

看到之前的代码,你会发现代码有点混乱,很多地方使用了全局变量(global)。

本节我们将使用类进行重构。

  • Block(Sprite):基类,用于创建一个带图像的长方形。
  • Player(Block):玩家。
  • Ball(Block):球。
  • Opponent(Block): 对手。
  • GameManager: 绘制/更新元素。我们将游戏的主要逻辑移到了这个类中。

键盘的输入还是在主循环中处理,这样搞还是有些混乱。

在主程序中,需要创建pygame.sprite.Group(),并将精灵加入其中。

import sys 
import random
import pygameclass Block(pygame.sprite.Sprite):def __init__(self,path,x_pos,y_pos):super().__init__()self.image = pygame.image.load(path)self.rect = self.image.get_rect(center = (x_pos,y_pos))class Player(Block):def __init__(self,path,x_pos,y_pos,speed):super().__init__(path,x_pos,y_pos)self.speed = speedself.movement = 0def screen_constrain(self):if self.rect.top <= 0:self.rect.top = 0if self.rect.bottom >= screen_height:self.rect.bottom = screen_heightdef update(self,ball_group):self.rect.y += self.movementself.screen_constrain()class Ball(Block):def __init__(self,path,x_pos,y_pos,speed_x,speed_y,paddles):super().__init__(path,x_pos,y_pos)self.speed_x = speed_x * random.choice((1,-1))self.speed_y = speed_y * random.choice((1,-1))self.paddles = paddlesself.active = Falseself.score_time = 0def update(self):if self.active:self.rect.x += self.speed_xself.rect.y += self.speed_yself.collisions()else:self.restart_counter()def collisions(self):if self.rect.top <= 0 or self.rect.bottom >= screen_height:pygame.mixer.Sound.play(pong_sound)self.speed_y *= -1if pygame.sprite.spritecollide(self,self.paddles,False):pygame.mixer.Sound.play(pong_sound)collision_paddle = pygame.sprite.spritecollide(self,self.paddles,False)[0].rectif abs(self.rect.right - collision_paddle.left) < 10 and self.speed_x > 0:self.speed_x *= -1if abs(self.rect.left - collision_paddle.right) < 10 and self.speed_x < 0:self.speed_x *= -1if abs(self.rect.top - collision_paddle.bottom) < 10 and self.speed_y < 0:self.speed_y *= -1if abs(self.rect.bottom - collision_paddle.top) < 10 and self.speed_y > 0:self.speed_y *= -1def reset_ball(self):self.active = Falseself.speed_x *= random.choice((1,-1))self.speed_y *= random.choice((1,-1))self.score_time = pygame.time.get_ticks()self.rect.center = (screen_width/2,screen_height/2)pygame.mixer.Sound.play(score_sound)def restart_counter(self):current_time = pygame.time.get_ticks()countdown_number = 3if current_time - self.score_time <= 700:countdown_number = 3if 700 < current_time - self.score_time <= 1400:countdown_number = 2if 1400 < current_time - self.score_time <= 2100:countdown_number = 1if current_time - self.score_time >= 2100:self.active = Truetime_counter = basic_font.render(str(countdown_number),True,accent_color)time_counter_rect = time_counter.get_rect(center = (screen_width/2,screen_height/2 + 50))pygame.draw.rect(screen,bg_color,time_counter_rect)screen.blit(time_counter,time_counter_rect)class Opponent(Block):def __init__(self,path,x_pos,y_pos,speed):super().__init__(path,x_pos,y_pos)self.speed = speeddef update(self,ball_group):if self.rect.top < ball.rect.y:self.rect.y += self.speedif self.rect.bottom > ball.rect.y:self.rect.y -= self.speedself.constrain()def constrain(self):if self.rect.top <= 0: self.rect.top = 0if self.rect.bottom >= screen_height: self.rect.bottom = screen_heightclass GameManager:def __init__(self,ball_group,paddle_group):self.player_score = 0self.opponent_score = 0self.ball_group = ball_groupself.paddle_group = paddle_groupdef run_game(self):self.paddle_group.draw(screen)self.ball_group.draw(screen)self.paddle_group.update(self.ball_group)self.ball_group.update()self.reset_ball()self.draw_score()def reset_ball(self):if self.ball_group.sprite.rect.right >= screen_width:self.opponent_score += 1self.ball_group.sprite.reset_ball()if self.ball_group.sprite.rect.left <= 0:self.player_score += 1self.ball_group.sprite.reset_ball()def draw_score(self):player_score = basic_font.render(str(self.player_score),True,accent_color)opponent_score = basic_font.render(str(self.opponent_score),True,accent_color)player_score_rect = player_score.get_rect(midleft = (screen_width / 2 + 40,screen_height/2))opponent_score_rect = opponent_score.get_rect(midright = (screen_width / 2 - 40,screen_height/2))screen.blit(player_score,player_score_rect)screen.blit(opponent_score,opponent_score_rect)# General setup
pygame.mixer.pre_init(44100, -16, 2, 512)
pygame.init()
clock = pygame.time.Clock()# Main Window
screen_width = 980
screen_height = 720
screen = pygame.display.set_mode((screen_width,screen_height))
pygame.display.set_caption('Pong')# Global Variables
bg_color = pygame.Color('#2F373F')
accent_color = (27,35,43)
basic_font = pygame.font.Font('freesansbold.ttf', 32)
pong_sound = pygame.mixer.Sound("pong.ogg")
score_sound = pygame.mixer.Sound("score.ogg")
middle_strip = pygame.Rect(screen_width/2 - 2,0,4,screen_height)# Game Objects
player = Player('Paddle.png',screen_width - 20,screen_height/2,5)
opponent = Opponent('Paddle.png',20,screen_width/2,5)
paddle_group = pygame.sprite.Group()
paddle_group.add(player)
paddle_group.add(opponent)ball = Ball('Ball.png',screen_width/2,screen_height/2,4,4,paddle_group)
ball_sprite = pygame.sprite.GroupSingle()
ball_sprite.add(ball)game_manager = GameManager(ball_sprite,paddle_group)# Game Loop
while True:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()sys.exit()if event.type == pygame.KEYDOWN:if event.key == pygame.K_DOWN:player.movement += player.speedif event.key == pygame.K_UP:player.movement -= player.speedif event.type == pygame.KEYUP:if event.key == pygame.K_DOWN:player.movement -= player.speedif event.key == pygame.K_UP:player.movement += player.speed# Background Stuffscreen.fill(bg_color)pygame.draw.rect(screen,accent_color,middle_strip)# Run Gamegame_manager.run_game()# Renderingpygame.display.flip()clock.tick(120)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/759229.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NCV7428D15R2G中文资料PDF数据手册参数引脚图图片价格概述参数芯片特性原理

产品概述&#xff1a; NCV7428 是一款系统基础芯片 (SBC)&#xff0c;集成了汽车电子控制单元 (ECU) 中常见的功能。NCV7428 为应用微控制器和其他负载提供低电压电源并对其进行监控&#xff0c;包括了一个 LIN 收发器。 产品特性&#xff1a; 控制逻辑3.3 V或5 V VOUT电源&…

Spark-Scala语言实战(4)

在之前的文章中&#xff0c;我们学习了如何在scala中定义无参&#xff0c;带参以及匿名函数。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-Scala语言…

四、HarmonyOS应用开发-ArkTS开发语言介绍

目录 1、TypeScript快速入门 1.1、编程语言介绍 1.2、基础类型 1.3、条件语句 1.4、函数 1.5、类 1.6、模块 1.7、迭代器 2、ArkTs 基础&#xff08;浅析ArkTS的起源和演进&#xff09; 2.1、引言 2.2、JS 2.3、TS 2.4、ArkTS 2.5、下一步演进 3、ArkTs 开发实践…

Verilog基础:always结构和initial结构

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 always和initial是Verilog中的核心&#xff0c;它们被称为结构(construct)&#xff0c;用于组织语句的执行方式。下面将分别对这两者进行阐述。 always结构 图1是…

弹框el-dialog title展示不下,鼠标hover显示tip

el-dialog title展示不下&#xff0c;鼠标hover显示tip <el-dialog:visible.sync"shows":close-on-click-modal"false"v-dialogDragwidth"520px"><template #title><div class"custom-title"><el-tooltipplaceme…

【文件操作和IO】

文件操作和IO 1.文件2. 硬盘上文件的目录结构3. 文件路径4. 文件重要分类&#xff1a;5. Java中操作文件5.1 Java对于文件操作的API5.2 Java中使用File类来进行文件操作5.3 File类属性5.4 构造方法5.5 方法&#xff1a; 6. 文件内容的读写 -- 文件流&#xff08;数据流&#xf…

Apache Superset

前言 最近在准备一个小的项目&#xff0c;需要对 Hive 的数据进行展示&#xff0c;所以想到了把 Hive 的数据导出到 MySQL 然后用 Superset 进行展示。 Superset 1.1 Superset概述 Apache Superset是一个现代的数据探索和可视化平台。它功能强大且十分易用&#xff0c;可对接…

kubesphere all in one部署Jenkins提示1 Insufficient cpu

原因 devops 至少一个cpu&#xff08;1000m&#xff09;&#xff0c;但是其他资源已经占用了很多cpu CPU 资源以 CPU 单位度量。Kubernetes 中的一个 CPU 等同于&#xff1a; 1 个 AWS vCPU 1 个 GCP核心 1 个 Azure vCore 裸机上具有超线程能力的英特尔处理器上的 1 个超线程…

RISC-V架构的三种特权模式如何切换

1、RISC-V的三种特权模式 特权模式功能描述机器模式&#xff08;M-mode&#xff09;具有最高特权等级&#xff0c;具有访问所有资源的权限&#xff0c;通常运行固件和内核用户模式&#xff08;U-mode&#xff09;权限要比M模式低&#xff0c;通常是用来运行操作系统内核管理员…

MyBatis3源码深度解析(十七)MyBatis缓存(一)一级缓存和二级缓存的实现原理

文章目录 前言第六章 MyBatis缓存6.1 MyBatis缓存实现类6.2 MyBatis一级缓存实现原理6.2.1 一级缓存在查询时的使用6.2.2 一级缓存在更新时的清空 6.3 MyBatis二级缓存的实现原理6.3.1 实现的二级缓存的Executor类型6.3.2 二级缓存在查询时使用6.3.3 二级缓存在更新时清空 前言…

2024年第六届区块链与物联网国际会议(BIOTC 2024)即将召开!

2024年第六届区块链与物联网国际会议&#xff08;简称&#xff1a;BIOTC 2024&#xff09;将于2024 年 7 月 19 日至 21 日在日本福冈召开&#xff0c;旨在为来自行业、学术界和政府的研究人员、从业者和专业人士提供一个论坛&#xff0c;就研发区块链和物联网的专业实践进行交…

简介:使用TensorFlow实现python简版神经网络模型

如果你想进一步深入AI编程的魔法世界&#xff0c;那么TensorFlow和PyTorch这两个深度学习框架将是你的不二之选。它们可以帮助你构建更加复杂的神经网络模型&#xff0c;实现图像识别、语音识别等高级功能。 模型原理&#xff1a;神经网络是一种模拟人脑神经元结构的计算模型&a…

python 基于 websocket 的简单将视频推流到网页

本来有一台设备是要搞成无线的形式的&#xff0c;设备的摄像头的数据可以在一台局域网连接的平板上查看&#xff0c;因为试着使用 RTMP 推流&#xff0c;感觉延时太大了&#xff0c;而 Webrtc 感觉有太麻烦了&#xff0c;所以一开始看到这篇文章使用 UDP 协议进行推流&#xff…

stable diffusion webui ubuntu 安装

1.git clone 下来 GitHub - AUTOMATIC1111/stable-diffusion-webui: Stable Diffusion web UIStable Diffusion web UI. Contribute to AUTOMATIC1111/stable-diffusion-webui development by creating an account on GitHub.https://github.com/AUTOMATIC1111/stable-diffus…

数据仓库相关概述

数据仓库概述 数据仓库概念 数据仓库是一个为数据分析而设计的企业级数据管理系统。数据仓库可集中、整合多个信息源的大量数据&#xff0c;借助数据仓库的分析能力&#xff0c;企业可从数据中获得宝贵的信息进而改进决策。同时&#xff0c;随着时间的推移&#xff0c;数据仓…

期刊如何反击一波可疑图像

出版商正在部署基于人工智能的工具来检测可疑图像&#xff0c;但生成式人工智能威胁着他们的努力。 期刊正在努力检测用于分析蛋白质和DNA的凝胶的操纵图像。图片来源&#xff1a;Shutterstock 似乎每个月都会有一系列针对研究人员的新高调指控&#xff0c;这些研究人员的论文…

Go --- Go语言垃圾处理

概念 垃圾回收&#xff08;GC-Garbage Collection&#xff09;暂停程序业务逻辑SWT&#xff08;stop the world&#xff09;程序根节点&#xff1a;程序中被直接或间接引用的对象集合&#xff0c;能通过他们找出所有可以被访问到的对象&#xff0c;所以Go程序的根节点通常包括…

完全理解ARM启动流程:Uboot-Kernel

内容共计5W字数&#xff0c;但是我还是很多地方说的不够尽兴。那么下次聊&#xff01; 前言 bootloader是系统上电后最初加载运行的代码。它提供了处理器上电复位后最开始需要执行的初始化代码。 PC机上引导程序一般由BIOS开始执行&#xff0c;然后读取硬盘中位于MBR(Main Bo…

openGauss学习笔记-247 openGauss性能调优-SQL调优关键参数调整

文章目录 openGauss学习笔记-247 openGauss性能调优-SQL调优关键参数调整247.1 SQL调优关键参数调整 openGauss学习笔记-247 openGauss性能调优-SQL调优关键参数调整 247.1 SQL调优关键参数调整 本节将介绍影响openGauss SQL调优性能的关键数据库主节点配置参数&#xff0c;配…

【JVM】为对象分配内存的方式,死亡对象判断方法

目录 为对象分配内存的方式 指针碰撞 空闲列表 TLAB 死亡对象判断方法 引用计数法 可达性分析算法 为对象分配内存的方式 指针碰撞 一般情况下&#xff0c;JVM的对象都放在堆内存中&#xff08;发生逃逸分析除外&#xff09;。当类加载检查通过后&#xff0c;JVM为新生…