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

Python基础篇(十五)-- Pygame游戏编程

1 初识Pygame

        Pygame是一个开源的Python模块,专门用于多媒体应用(如电子游戏)的开发,其中包含对图像、声音、视频、事件、碰撞等的支持。Pygame建立在SDL的基础上,SDL是一套跨平台的多媒体开发库,用C语言实现,被广泛的应用于游戏、模拟器、播放器等的开发。而Pygame让游戏开发者不再被底层语言束缚,可以更多的关注游戏的功能和逻辑。

        对于该模块的详细用法,可以参考:Pygame详解

        本节是在编写游戏的过程中学习Pygame。会先通过“跳跃的小球”的游戏学习 Pygame 基础知识,然后应用 Pygame 实现 Flappy Bird 游戏。


2 基本使用

2.1 Pygame常用模块

        Pygame中集成了很多和底层开发相关的模块,如访问显示设备、管理事件、使用字体等。Pygame常用模块如下图所示。

        下面,使用pygame的 display模块和 event 模块创建一个 Pygame 窗口,代码如下:

import sys
import pygamepygame.init()
size = width, height = 320, 240             # 设置窗口
screen = pygame.display.set_mode(size)      # 显示窗口# 执行死循环,确保窗口一直显示
while True:for event in pygame.event.get():        # 遍历所有事件if event.type == pygame.QUIT:       # 如果单击关闭窗口,则退出sys.exit()pygame.quit()       # 退出pygame

3 游戏开发

        先创建一个游戏窗口,然后在窗口内创建一个小球。以一定的速度移动小球,当小球碰到游戏窗口的边缘时,小球弹回,继续移动。按照如下步骤实现该功能:

        (1) 创建一个游戏窗口,宽和高设置为 640*480,并在窗口中添加小球。我们先准备好一张 ball.png 图片,然后加载该图片,最后将图片显示在窗口中,具体代码如下:

import sys
import pygamepygame.init()                               # 初始化 pygame
size = width, height = 640, 480             # 设置窗口
screen = pygame.display.set_mode(size)      # 显示窗口
color = (0, 0, 0)ball = pygame.image.load('ball.png')        # 加载图片
ballrect = ball.get_rect()                  # 获取矩形区域# 执行死循环,确保窗口一直显示
while True:for event in pygame.event.get():if event.type == pygame.QUIT:       # 如果单击关闭窗口,则退出sys.exit()screen.fill(color)                      # 填充颜色screen.blit(ball, ballrect)             # 将图片画到窗口上pygame.display.flip()                   # 更新全部显示pygame.quit()                               # 退出pygame

        上述代码中,首先导入pygame模块,然后调用 init() 方法初始化 pygame 模块。接下来,设置窗口的宽和高,最后使用 display 模块显示窗体。display模块的常用方法如下表所示。

        上述代码中,为了让窗口一直显示,需要使用 while True 让程序一直执行。同时设置关闭按钮,添加了轮询事件检测。pygame.event.get() 能够获取事件队列,使用for ... in遍历事件,然后根据type属性判断事件类型。这里的 event.type 等于 pygame.QUIT 表示检测到关闭 pygame 窗口事件,pygame.KEYDOWN 表示键盘按下事件,pgame.MOUSEBUTTONDOWN 表示鼠标按下事件等。

        上述代码中使用 image 模块的 load() 方法加载图片,返回值 ball 是一个 Surface 对象。Surface 是用来代表图片的 pygame 对象,可以对一个 Surface 对象进行涂画、变形、复制等各种操作。事实上,屏幕也只是一个 surface,pygame.display.set_mode就返回了一个屏幕 Surface 对象。如果将 ball 这个 Surface 对象画到 screen Surface 对象,需要使用 blit()方法,最后使用 display 模块的 flip() 方法更新整个待显示的 Surface 对象到屏幕上。Surface 对象的常用方法如下图所示。

        效果如下图所示:

        (2) 下面该让小球动起来了。ball.get_rect() 方法返回值balrect 是一个 Rect 对象,该对象有一个 move() 方法可以用于移动矩形。move(x,y) 函数有两个参数,第一个参数是 X 轴移动的距离,第二个参数是 Y 轴移动的距离。窗体左上角坐标为(0,0),为实现小球不停地移动,将 move() 函数添加到 while循环内,具体代码如下:

import sys
import pygamepygame.init()
size = width, height = 640, 480
screen = pygame.display.set_mode(size)
color = (0, 0, 0)ball = pygame.image.load('ball.png')
ballrect = ball.get_rect()speed = [5, 5]              # 设置移动的X轴、Y轴距离
while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()ballrect = ballrect.move(speed)         # 移动小球screen.fill(color)screen.blit(ball, ballrect)pygame.display.flip()pygame.quit()

        (3) 运行上述代码,发现小球在屏幕中一闪而过,此时,小球并没有真正消失,而是移动到窗体之外,此时需要添加碰撞检测的功能。当小球与窗体任一边缘发生碰撞,则更改小球的移动方向。具体代码如下:

import sys
import pygamepygame.init()
size = width, height = 640, 480
screen = pygame.display.set_mode(size)
color = (0, 0, 0)ball = pygame.image.load('ball.png')
ball_rect = ball.get_rect()speed = [5, 5]while True:for event in pygame.event.get():if event.type == pygame.QUIT:       # 如果单击关闭窗口,则退出sys.exit()ball_rect = ball_rect.move(speed)         # 移动小球# 碰到左右边缘if ball_rect.left < 0 or ball_rect.right > width:speed[0] = -speed[0]# 碰到上下边缘if ball_rect.top < 0 or ball_rect.bottom > height:speed[1] = -speed[1]screen.fill(color)                  # 填充颜色screen.blit(ball, ball_rect)        # 将图片画到窗口上pygame.display.flip()               # 更新全部显示pygame.quit()

        上述代码中,添加了碰撞检测功能。如果碰到左右边缘,更改 X 轴数据为负数,如果碰到上下边缘,更改 Y 轴数据为负数。运行结果如下图所示。

        (4) 运行上述代码发现好像有多个小球在飞快移动,这是因为运行上述代码的时间非常短,导致肉眼观察出现错觉,因此需要添加一个“时钟”来控制程序运行的时间。这时就需要使用 Pygame 的time 模块。使用 Pygame 时钟之前,必须先创建 Clock 对象的一个实例,然后在 while循环中设置多长时间运行一次。具体代码如下:

import sys
import pygamepygame.init()
size = width, height = 640, 480
screen = pygame.display.set_mode(size)
color = (0, 0, 0)ball = pygame.image.load('ball.png')
ball_rect = ball.get_rect()speed = [5, 5]
clock = pygame.time.Clock()     # 设置时钟 while True:clock.tick(60)              # 每秒执行60次for event in pygame.event.get():if event.type == pygame.QUIT:       # 如果单击关闭窗口,则退出sys.exit()ball_rect = ball_rect.move(speed)         # 移动小球# 碰到左右边缘if ball_rect.left < 0 or ball_rect.right > width:speed[0] = -speed[0]# 碰到上下边缘if ball_rect.top < 0 or ball_rect.bottom > height:speed[1] = -speed[1]screen.fill(color)                  # 填充颜色screen.blit(ball, ball_rect)        # 将图片画到窗口上pygame.display.flip()               # 更新全部显示pygame.quit()

        至此,我们完成了小球的跳跃游戏。


4 开发 Flappy Bird 游戏

4.1 游戏简介

        Flappy Bird 是一款鸟类飞行游戏,由越南河内独立游戏开发者阮哈东(Dong Nguyen)开发。在FlappyBird 这款游戏中,玩家只需要用一根手指来操控,单击触摸手机屏幕,小鸟就会往上飞。不断地单击屏幕,小鸟就会不断地往高处飞;放松手指,则会快速下降。玩家要控制小鸟一直向前飞行,并且注意躲避途中高低不平的管子。如果小鸟碰到了障碍物,游戏就会结束。每当小鸟飞过一组管道,玩家就会获得1分。

4.2 游戏分析

        在 Flappy Bird 游戏中,主要有两个对象:小鸟和管道。可以创建 Bird 类和 Pincline 类来分别表示这两个对象。小鸟可以通过上下移动来躲避管道,所以在 Bird 类中创建一个 bird_update()方法,实现小鸟的上下移动。为了体现小鸟向前飞行的特征,可以让管道一直向左侧移动,这样在窗口中就好像小鸟在向前飞行。所以,在 Pineline 类中也创建一个update_pipeline() 方法,实现管道的向左移动。此外,还创建了3个函数: create_map()函数用于绘制地图; check_dead()函数用于判断小鸟的生命状;get_result() 函数用于获攻最终分数。最后在主逻辑中,实例化类并调用相关方法,实现相应功能。

4.3 搭建主框架

        通过前面的分析,我们可以搭建起 Flappy Bird 游戏的主框架。Flappy Bird 游戏有两个对象:小鸟和管道。先来创建这两个类,类中具体的方法可以先使用pass语句代替。然后创建一个绘制地图的函数 create_map()。最后,在主逻辑中绘制背景图片。关键代码如下:

import sys
import pygame
import randomclass Bird(object):"""定义一个鸟类"""def __init__(self):"""定义初始化方法"""passdef bird_update(self):passclass Pipeline(object):"""定义一个管道类"""def __init__(self):"""定义初始化方法"""passdef update_pipeline(self):"""管道水平移动"""passdef create_map():"""定义创建地图的方法"""screen.fill((255, 255, 255))        # 填充颜色screen.blit(back_ground, (0, 0))    # 填入到背景pygame.display.update()             # 更新显示if __name__ == '__main__':"""主程序"""pygame.init()                           # 初始化pygamesize = width, height = 288, 512screen = pygame.display.set_mode(size)clock = pygame.time.Clock()Pipeline = Pipeline()                   # 实例化管道类Bird = Bird()                           # 实例化鸟类while True:clock.tick(60)for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()back_ground = pygame.image.load('assets/bg_day.png')    # 加载背景图片create_map()            # 绘制地图pygame.quit()               # 退出

4.4 创建小鸟类

        下面来创建小鸟类。该类需要初始化很多参数,所以定义一个 __init__() 方法,用来初始化各种参数,包括鸟飞行的几种状态、飞行的速度、跳跃的高度等。然后定义 bird_update() 方法,该方法用于实现小鸟的跳跃和坠落。接下来,在主逻辑的轮询事件中添加键盘按下事件或鼠标单击事件,如按下鼠标,使小鸟上升等。最后,在 create_map() 方法中,显示小鸟的图像。关键代码如下:

import sys
import pygame
import randomclass Bird(object):"""定义一个鸟类"""def __init__(self):"""定义初始化方法"""self.bird_rect = pygame.Rect(65, 50, 50, 50)        # 鸟的矩形# 定义鸟的3种状态列表self.bird_status = [pygame.image.load('assets/bird0_0.png'),pygame.image.load('assets/bird0_1.png'),pygame.image.load('assets/bird0_2.png')]self.status = 0         # 默认飞行状态self.bird_x = 150       # 鸟所在的X轴坐标self.bird_y = 350       # 鸟所在的Y轴坐标,即上下飞行高度self.jump = False       # 默认情况小鸟自动降落self.jump_speed = 10    # 跳跃高度self.gravity = 5        # 重力self.dead = False       # 默认小鸟生命状态为活着def bird_update(self):if self.jump:# 小鸟跳跃self.jump_speed -= 1                # 速度递减,上升越来越慢self.bird_y -= self.jump_speed      # 鸟的Y轴坐标减小,小鸟上升else:# 小鸟坠落self.gravity += 0.2                 # 重力递增,下降越来越快self.bird_y += self.gravity         # 鸟的Y轴坐标增加,小鸟下降self.bird_rect[1] = self.bird_y         # 更改Y轴坐标class Pipeline(object):"""定义一个管道类"""def __init__(self):"""定义初始化方法"""passdef update_pipeline(self):"""管道水平移动"""passdef create_map():"""定义创建地图的方法"""screen.fill((255, 255, 255))        # 填充颜色screen.blit(back_ground, (0, 0))    # 填入到背景# 显示小鸟if Bird.dead:Bird.status = 2                 # 撞管道状态elif Bird.jump:Bird.status = 1                 # 起飞状态screen.blit(Bird.bird_status[Bird.status], (Bird.bird_x, Bird.bird_y))  # 设置小鸟坐标Bird.bird_update()                  # 鸟移动pygame.display.update()             # 更新显示if __name__ == '__main__':"""主程序"""pygame.init()                           # 初始化pygamesize = width, height = 288, 512screen = pygame.display.set_mode(size)clock = pygame.time.Clock()Pipeline = Pipeline()                   # 实例化管道类Bird = Bird()                           # 实例化鸟类while True:clock.tick(60)for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()if (event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN) and not Bird.dead:Bird.jump = True        # 跳跃Bird.gravity = 2        # 重力Bird.jump_speed = 10    # 跳跃速度back_ground = pygame.image.load('assets/bg_day.png')    # 加载背景图片create_map()            # 绘制地图pygame.quit()               # 退出

        上述代码在 Bird 类中设置了 bird_status 属性,该属性是一个鸟类图片的列表,列表中显示鸟类3种飞行状态,根据小鸟的不同状态加载相应的图片。在 bird_update() 方法中,为了达到较好的动画效果,使 jump_speedgravity 两个属性逐渐变化。运行上述代码,在窗体内创建一只小鸟,默认情况小鸟会一直下降。当单击一下鼠标或按一下键盘,小鸟会跳跃一下,高度上升。

4.5 创建管道类

        创建完鸟类后,接下来创建管道类。同样,在 __init__ 方法中初始化各种参数,包括设置管道的坐标,加载上下管道图片等。然后在 update_pipeline() 方法中,定义管道向左移动的速度,并且当管道移出屏幕时,重新绘制下一组管道。最后,在 create_map() 函数中显示管道。关键代码如下:

import sys
import pygame
import randomclass Bird(object):"""定义一个鸟类"""# 代码和前面一致,此处省略class Pipeline(object):"""定义一个管道类"""def __init__(self):"""定义初始化方法"""self.wall_x = 288               # 管道所在X轴坐标self.pipe_up = pygame.image.load('assets/pipe_up.png')          # 加载上管道图片self.pipe_down = pygame.image.load('assets/pipe_down.png')      # 加载下管道图片def update_pipeline(self):"""管道水平移动"""self.wall_x -= 5        # 管道X轴坐标递减,即管道向左移动# 当管道运行到一定位置,即小鸟飞跃管道,分数加1,并且重置管道if self.wall_x < -80:global scorescore += 1self.wall_x = 288def create_map():"""定义创建地图的方法"""screen.fill((255, 255, 255))        # 填充颜色screen.blit(back_ground, (0, 0))    # 填入到背景# 显示管道screen.blit(Pipeline.pipe_up, (Pipeline.wall_x, -200))      # 上管道坐标位置screen.blit(Pipeline.pipe_down, (Pipeline.wall_x, 400))     # 下管道坐标位置Pipeline.update_pipeline()          # 管道移动# 显示小鸟if Bird.dead:Bird.status = 2                 # 撞管道状态elif Bird.jump:Bird.status = 1                 # 起飞状态screen.blit(Bird.bird_status[Bird.status], (Bird.bird_x, Bird.bird_y))  # 设置小鸟坐标Bird.bird_update()                  # 鸟移动# 显示分数screen.blit(font.render('Score:'+str(score), -1, (255, 255, 255)), (100, 50))   # 设置颜色及坐标位置pygame.display.update()             # 更新显示if __name__ == '__main__':"""主程序"""# 代码和前面一致,此处省略while True:clock.tick(60)for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()if (event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN) and not Bird.dead:Bird.jump = True        # 跳跃Bird.gravity = 2        # 重力Bird.jump_speed = 10    # 跳跃速度back_ground = pygame.image.load('assets/bg_day.png')    # 加载背景图片create_map()            # 绘制地图pygame.quit()               # 退出

        上述代码中,在 create_map() 函数内,设置先显示管道,再显示小鸟。这样傲的目的是为了当小鸟与管道图像重合时,小鸟的图像显示在上层,而管道的图像显示在底层。

4.6 计算得分

        当小鸟飞过管道时,玩家得分加1。这里对于飞过管道的逻辑做了简化处理:当管道移动到窗体左侧一定距离后,默认为小鸟飞过管道,使分数加1,并显示在屏幕上。在 update_pipeline() 方法中已实现该功能,代码如下:

import sys
import pygame
import randomclass Bird(object):"""定义一个鸟类"""# 代码和前面一致,此处省略class Pipeline(object):"""定义一个管道类"""# 代码和前面一致,此处省略def update_pipeline(self):"""管道水平移动"""self.wall_x -= 5        # 管道X轴坐标递减,即管道向左移动# 当管道运行到一定位置,即小鸟飞跃管道,分数加1,并且重置管道if self.wall_x < -80:global scorescore += 1self.wall_x = 288def create_map():"""定义创建地图的方法"""# 代码和前面一致,此处省略# 显示分数screen.blit(font.render('Score:'+str(score), -1, (255, 255, 255)), (100, 50))   # 设置颜色及坐标位置pygame.display.update()             # 更新显示if __name__ == '__main__':"""主程序"""pygame.init()                           # 初始化pygamepygame.font.init()                      # 初始化字体font = pygame.font.SysFont(None, 50)    # 设置默认字体和大小size = width, height = 288, 512screen = pygame.display.set_mode(size)clock = pygame.time.Clock()Pipeline = Pipeline()                   # 实例化管道类Bird = Bird()                           # 实例化鸟类score = 0while True:# 代码和前面一致,此处省略

4.7 碰撞检测

        当小鸟与管道相撞时,小鸟颜色变为灰色,游戏结束,并且显示总分数。在 check_dead() 函数中通过 pygame.Rect() 可以分别获取小鸟的矩形区域对象和管道的矩形区域对象,该对象有一个 collidcrect() 方法可以判断两个矩形区域是否相撞。如果相撞,设置 Bird.dead 属性为 True。此外,当小鸟飞出窗体时,也设置 Bird.dead 属性为True。最后,用两行文字显示游戏得分。关键代码如下:

import sys
import pygame
import randomclass Bird(object):"""定义一个鸟类"""# 代码和前面一致,此处省略class Pipeline(object):"""定义一个管道类"""# 代码和前面一致,此处省略def create_map():"""定义创建地图的方法"""# 代码和前面一致,此处省略def check_dead():# 上方管子的矩形位置up_rect = pygame.Rect(Pipeline.wall_x, -200, Pipeline.pipe_up.get_width() - 10,Pipeline.pipe_up.get_height())down_rect = pygame.Rect(Pipeline.wall_x, 400, Pipeline.pipe_down.get_width() - 10,Pipeline.pipe_down.get_height())# 检测小鸟与上下方管道是否碰撞if up_rect.colliderect(Bird.bird_rect) or down_rect.colliderect(Bird.bird_rect):Bird.dead = True# 检测小鸟是否飞出上下边界if not 0 < Bird.bird_rect[1] < height:Bird.dead = Truereturn Trueelse:return Falsedef get_result1():final_text1 = "Game Over"final_text2 = "Your final score is: " + str(score)ft1_font = pygame.font.SysFont('Arial', 40)             # 设置第一行文字字体ft1_surf = ft1_font.render(final_text1, 1, (243, 3, 36))    # 设置第一行文字颜色ft2_font = pygame.font.SysFont('Arial', 30)ft2_surf = ft2_font.render(final_text2, 1, (253, 177, 6))# 设置第一行文字显示位置screen.blit(ft1_surf, [screen.get_width()/2-ft1_surf.get_width()/2, 100])screen.blit(ft2_surf, [screen.get_width()/2-ft2_surf.get_width()/2, 200])pygame.display.flip()       # 更新整个待显示的Surface对象到屏幕上if __name__ == '__main__':"""主程序"""# 代码和前面一致,此处省略while True:# 代码和前面一致,此处省略back_ground = pygame.image.load('assets/bg_day.png')    # 加载背景图片if check_dead():            # 检测小鸟生命状态get_result1()           # 如果小鸟死亡,显示游戏总分数        else:create_map()            # 绘制地图pygame.quit()               # 退出

        上述代码的 check_dead() 方法中,up_rect.colliderect(Bird.bird_rect) 用于检测小鸟的矩形区域是否与上面的管道的矩形区域相撞, colliderect()函数的参数是另一个矩形区域对象。运行结果如下图所示。

        这里只是实现了 Flappy Bird 的基本功能,还可以继续完善设置游戏的难度,包括设置管道的高度、小鸟的飞行速度等,感兴趣的朋友可以进一步尝试。

完整代码如下:

# -*- encoding: utf-8 -*-
# @Author: CarpeDiem
# @Date: 230210
# @Version: 1.0
# @Description: 移动小球import sys
import pygame
import randomclass Bird(object):"""定义一个鸟类"""def __init__(self):"""定义初始化方法"""self.bird_rect = pygame.Rect(65, 50, 50, 50)        # 鸟的矩形# 定义鸟的3种状态列表self.bird_status = [pygame.image.load('assets/bird0_0.png'),pygame.image.load('assets/bird0_1.png'),pygame.image.load('assets/bird0_2.png')]self.status = 0         # 默认飞行状态self.bird_x = 150       # 鸟所在的X轴坐标self.bird_y = 350       # 鸟所在的Y轴坐标,即上下飞行高度self.jump = False       # 默认情况小鸟自动降落self.jump_speed = 10    # 跳跃高度self.gravity = 5        # 重力self.dead = False       # 默认小鸟生命状态为活着def bird_update(self):if self.jump:# 小鸟跳跃self.jump_speed -= 1                # 速度递减,上升越来越慢self.bird_y -= self.jump_speed      # 鸟的Y轴坐标减小,小鸟上升else:# 小鸟坠落self.gravity += 0.2                 # 重力递增,下降越来越快self.bird_y += self.gravity         # 鸟的Y轴坐标增加,小鸟下降self.bird_rect[1] = self.bird_y         # 更改Y轴坐标class Pipeline(object):"""定义一个管道类"""def __init__(self):"""定义初始化方法"""self.wall_x = 288               # 管道所在X轴坐标self.pipe_up = pygame.image.load('assets/pipe_up.png')          # 加载上管道图片self.pipe_down = pygame.image.load('assets/pipe_down.png')      # 加载下管道图片def update_pipeline(self):"""管道水平移动"""self.wall_x -= 5        # 管道X轴坐标递减,即管道向左移动# 当管道运行到一定位置,即小鸟飞跃管道,分数加1,并且重置管道if self.wall_x < -80:global scorescore += 1self.wall_x = 288def create_map():"""定义创建地图的方法"""screen.fill((255, 255, 255))        # 填充颜色screen.blit(back_ground, (0, 0))    # 填入到背景# 显示管道screen.blit(Pipeline.pipe_up, (Pipeline.wall_x, -200))      # 上管道坐标位置screen.blit(Pipeline.pipe_down, (Pipeline.wall_x, 400))     # 下管道坐标位置Pipeline.update_pipeline()          # 管道移动# 显示小鸟if Bird.dead:Bird.status = 2                 # 撞管道状态elif Bird.jump:Bird.status = 1                 # 起飞状态screen.blit(Bird.bird_status[Bird.status], (Bird.bird_x, Bird.bird_y))  # 设置小鸟坐标Bird.bird_update()                  # 鸟移动# 显示分数screen.blit(font.render('Score:'+str(score), -1, (255, 255, 255)), (100, 50))   # 设置颜色及坐标位置pygame.display.update()             # 更新显示def check_dead():# 上方管子的矩形位置up_rect = pygame.Rect(Pipeline.wall_x, -200, Pipeline.pipe_up.get_width() - 10,Pipeline.pipe_up.get_height())down_rect = pygame.Rect(Pipeline.wall_x, 400, Pipeline.pipe_down.get_width() - 10,Pipeline.pipe_down.get_height())# 检测小鸟与上下方管道是否碰撞if up_rect.colliderect(Bird.bird_rect) or down_rect.colliderect(Bird.bird_rect):Bird.dead = True# 检测小鸟是否飞出上下边界if not 0 < Bird.bird_rect[1] < height:Bird.dead = Truereturn Trueelse:return Falsedef get_result1():final_text1 = "Game Over"final_text2 = "Your final score is: " + str(score)ft1_font = pygame.font.SysFont('Arial', 40)             # 设置第一行文字字体ft1_surf = ft1_font.render(final_text1, 1, (243, 3, 36))    # 设置第一行文字颜色ft2_font = pygame.font.SysFont('Arial', 30)ft2_surf = ft2_font.render(final_text2, 1, (253, 177, 6))# 设置第一行文字显示位置screen.blit(ft1_surf, [screen.get_width()/2-ft1_surf.get_width()/2, 100])screen.blit(ft2_surf, [screen.get_width()/2-ft2_surf.get_width()/2, 200])pygame.display.flip()       # 更新整个待显示的Surface对象到屏幕上if __name__ == '__main__':"""主程序"""pygame.init()                           # 初始化pygamepygame.font.init()                      # 初始化字体font = pygame.font.SysFont(None, 50)    # 设置默认字体和大小size = width, height = 288, 512screen = pygame.display.set_mode(size)clock = pygame.time.Clock()Pipeline = Pipeline()                   # 实例化管道类Bird = Bird()                           # 实例化鸟类score = 0while True:clock.tick(60)for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()if (event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN) and not Bird.dead:Bird.jump = True        # 跳跃Bird.gravity = 2        # 重力Bird.jump_speed = 10    # 跳跃速度back_ground = pygame.image.load('assets/bg_day.png')    # 加载背景图片if check_dead():            # 检测小鸟生命状态get_result1()           # 如果小鸟死亡,显示游戏总分数        else:create_map()            # 绘制地图pygame.quit()               # 退出

参考

  • Pygame教程:http://c.biancheng.net/pygame/
  • PYGAME主页:https://www.osgeo.cn/pygame/
  • Pygame详解:https://blog.csdn.net/qq_41556318/category_9283450.html
  • PyGame模块的所有功能函数详解:https://blog.51cto.com/u_15274949/2922576

相关文章:

Python基础篇(十五)-- Pygame游戏编程

1 初识Pygame Pygame是一个开源的Python模块&#xff0c;专门用于多媒体应用&#xff08;如电子游戏&#xff09;的开发&#xff0c;其中包含对图像、声音、视频、事件、碰撞等的支持。Pygame建立在SDL的基础上&#xff0c;SDL是一套跨平台的多媒体开发库&#xff0c;用C语言实…...

LeetCode 热题 HOT 100 Java 题解 -- Part 2

练习地址 Part 1 : https://blog.csdn.net/qq_41080854/article/details/128829494 LeetCode 热题 HOT 100 Java 题解 -- Part 236. 二叉树的中序遍历 9437. 不同的二叉搜索树 9638. 验证二叉搜索树 9839. 对称二叉树 10140. 二叉树的层序遍历 10241. 二叉树的最大深度 10442.…...

【项目实战】IDEA常用快捷键汇总

一、修改为Eclipse的快捷键 相信很多朋友跟我一样&#xff0c; 都是习惯了eclipse的快捷键&#xff0c;没错&#xff0c;习惯这东西真的很难改&#xff01;IDEA非常强大&#xff0c;支持我们修改IDEA中的keymap为Eclipse的快捷键&#xff01;友好又贴心&#xff0c;有没有&…...

更新 TKK 失败,请检查网络连接。谷歌翻译 translation插件不能用解决办法 亲测有效

谷歌翻译无法使用&#xff0c;谷歌回应解释是&#xff0c;谷歌翻译使用率过低&#xff0c;所以选择停止服务。网上也有说法&#xff0c;指出根本原因为&#xff0c;提供API接口的googleapis被墙&#xff0c;这导致js文件和字体资源无法加载。 这里提供两种解决办法 方案一 修…...

SpringBoot整合MybatisPlus多数据源

相信在很多使用MybatisPlus框架的小伙伴都会遇到多数据源的配置问题&#xff0c;并且官网也给出了推荐使用多数据源 (dynamic-datasource-spring-boot-starter) 组件来实现。由于最近项目也在使用这个组件来实现多数据源切换&#xff0c;因此想了解一下该组件是如何运行的&…...

【教程】如何使用Java生成PDF文档?

在如今数字化时代&#xff0c;越来越多的人使用PDF文档进行信息传递和共享。而使用Java生成PDF文档也成为了一个非常重要的技能&#xff0c;因为Java作为一种通用的编程语言&#xff0c;可以在不同的操作系统和平台上运行。下面&#xff0c;我们将为您介绍如何使用Java生成PDF文…...

I.MX6ULL内核开发13:pinctrl子系统和gpio子系统-led实验

目录 一、pinctrl子系统 1.1 pinctrl子系统编写格式以及引脚属性介绍 1.1.1 iomux节点介绍 1.1.2 pinctrl子节点编写格式 1.1.3 引脚配置信息介绍 1.2 将RGB灯引脚添加到pinctrl子系统 1.2.1 查找RGB灯使用的引脚 1.2.2找到引脚宏定义 1.2.3 设置引脚属性 1.2.4 在…...

Linux系列 使用vi文本编辑器

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.vi文本编辑器 1.使用vi文本编辑器 2.vi编辑器的工作模式 3.命令模式中的…...

【java基础】接口(interface)

文章目录基础介绍接口的定义关于接口字段和方法的说明使用接口抽象类和接口接口方法冲突的一些说明方法相同名称和参数&#xff0c;返回值相同方法名称相同&#xff0c;参数不同&#xff0c;返回值相同方法返回值不同&#xff0c;名称参数相同方法完全相同&#xff0c;一个有默…...

ChatGPT(GPT3.5) OpenAI官方API正式发布

OpenAI社区今天凌晨4点多发送的邮件&#xff0c;介绍了ChatGPT官方API的发布。官方介绍文档地址为“OpenAI API”和“OpenAI API”。 ChatGPT(GPT3.5)官方API模型名称为“gpt-3.5-turbo”和“gpt-3.5-turbo-0301”。API调用价格比GPT text-davinci-003模型便宜10倍。调用费用为…...

CAD中如何将图形对象转换为三维实体?

有些小伙伴在CAD绘制完图纸后&#xff0c;想要将图纸中的某些图形对象转换成三维实体&#xff0c;但却不知道该如何操作&#xff0c;其实很简单&#xff0c;本节CAD绘图教程就和小编一起来了解一下浩辰CAD软件中将符合条件的对象转换为三维实体的相关操作步骤吧&#xff01; 将…...

【K8S笔记】Kubernetes 集群架构与组件介绍

K8S 官方文档 https://kubernetes.io/zh/docs/home ##注重关注 概念和任务 板块。 K8S 集群架构 K8S也是运用了分布式集群架构&#xff1a; 管理节点/Master 整个集群的管理&#xff0c;任务协作。工作节点/Node 容器运行、删除。 K8S 组件介绍 管理节点/Master 相关组件 …...

9 怎么登录VNC

1&#xff09;首先在ssh登录后启动vncserver。登陆后输入下面的指令来创建自己的VNC。 命令vncserver :16 –geometry 1900x1000 其中&#xff1a;16是分配的端口号&#xff0c;1900x1000是分辨率。如果没有响应&#xff0c;建议执行下面操作后再次重复上面操作。 命令&#xf…...

MPI ubuntu安装,mpicc,mpicxx,mpif90的区别

介绍 MPI是并行计算的一个支持库&#xff0c;支持对C、C、fortran语言进行并行计算。 安装基础环境 ubuntu进行gcc/g/gfortran的安装&#xff1a; gcc&#xff1a; ubuntu下自带gcc编译器。可以通过gcc -v命令来查看是否安装。 g&#xff1a; sudo apt-get install buil…...

移动端笔记

目录 一、移动端基础 二、视口 三、二倍图/多倍图 四、移动端开发 &#xff08;一&#xff09;开发选择 &#xff08;二&#xff09;常见布局 &#xff08;三&#xff09;移动端技术解决方案 五、移动WEB开发之flex布局 六、移动WEB开发之rem适配布局 #END&#xff08…...

操作系统笔记、面试八股(一)—— 进程、线程、协程

文章目录1. 进程、线程、协程1.1 进程1.1.1 进程间的通信方式1.1.2 进程同步方式1.1.3 进程的调度算法1.1.4 优先级反转1.1.5 进程状态1.1.6 PCB进程控制块1.1.7 进程的创建和撤销过程1.1.8 为什么要有进程1.2 线程1.2.1 为什么要有线程1.2.2 线程间的同步方式1.3 协程1.3.1 什…...

Python每日一练(20230302)

目录 1. 字符串统计 2. 合并两个有序链表 3. 下一个排列 附录 Python字典内置方法 增 删 改 查 其它 1. 字符串统计 从键盘输入一个包含有英文字母、数字、空格和其它字符的字符串&#xff0c;并分别实现下面的功能&#xff1a;统计字符串中出现2次的英文字母&#…...

Numpy课后练习

Numpy课后练习 文章目录 Numpy课后练习一、前言二、题目及答案一、前言 答案仅供参考,谢谢大家! 二、题目及答案 导入Numpy包并设置随机数种子为666 import numpy as np np.random.seed(666)创建并输出一个包含12个元素的随机整数数组r1,元素的取值范围在[30,100)之间 r1 …...

动态规划dp中的子序列、子数组问题总结

目录 定义dp数组 初始化dp数组 状态转移方程 最终结果 题目 定义dp数组 这类问题的共性是会提供两个数组,寻找他们共同的子序列、子数组。设第一个数组为s,第二个数组为t。则可以设二维dp数组,其大小为len(s + 1)*len(t + 1) dp[i][j]表示 s 前 i 个长度,...

Zookeeper3.5.7版本——Zookeeper的概述、工作机制、特点、数据结构及应用场景

目录一、Zookeeper的概述二、Zookeeper的工作机制三、Zookeeper的特点四、Zookeeper的数据结构五、Zookeeper的应用场景5.1、统一命名服务5.2、统一配置管理5.3、统一集群管理5.4、服务器动态上下线5.5、软负载均衡一、Zookeeper的概述 Zookeeper 是一个开源的分布式的&#x…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...