PyGame游戏编程

这篇具有很好参考价值的文章主要介绍了PyGame游戏编程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  • Python非常受欢迎的一个原因是它的应用领域非常广泛,其中就包括游戏开发。而是用Python进行游戏开发的首选模块就是PyGame。

1. 初识Pygame

  • PyGame是跨平台Python模块,专为电子游戏设计,包含图像、声音等,创建在SDL(Simple DirectMedia Layer)基础上,允许实时电子游戏研发而不会被低级语言,如C语言或是更低级的汇编语言束缚。基于这样一个设想,所有需要的游戏功能和理念(主要是图像方面)都完全简化为游戏逻辑本身,所有的资源结构都可以由高级语言(如Python)提供。

1. 安装Pygame

  • PyGame的官方网址是www.pygame.org。在该网址中可以查看PyGame的相关文档。PyGame的安装命令很简单:
pip install pygame
  • 检查模块是否安装成功:
import pygame
pygame.ver
  • 运行结果如下:
    PyGame游戏编程

2. Pygame常用模块

  • Pygame做游戏开发的优势在于不需要过多地考虑底层相关的内容,可以把工作中心放在游戏逻辑上。例如,PyGame中集成了很多和底层相关的模块,如访问显示设备、管理事件、使用字体等。
  • Pygame常用模块如下:
模块名 功能
pygame.cdrom 访问光驱。
pygame.cursors 加载光标。
pygame.display 访问显示设备。
pygame.draw 绘制形状、线和点。
pygame.event 管理事件。
pygame.font 使用字体。
pygame.image 加载和存储图片。
pygame.joystick 使用游戏手柄或类似的东西。
pygame.key 读取键盘按键。
pygame.mixer 声音。
pygame.mouse 鼠标。
pygame.movie 播放视频。
pygame.music 播放音乐。
pygame.overlay 访问高级视频叠加。
pygame.rect 管理矩形区域。
pygame.sndarray 操作声音数据。
pygame.sprite 操作移动图像。
pygame.surface 管理图像和屏幕。
pygame.surfarray 管理点阵图像数据。
pygame.time 管理时间和帧信息。
pygame.transform 缩放和移动图像。
  • 使用Pygame的display模块和event模块创建一个PyGame窗口,代码如下:
# -*- coding: utf-8 -*-
import sys         # 导入sys模块
import pygame       # 导入pygame模块


pygame.init()        # 初始化pygame
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
  • 运行结果如下:
    PyGame游戏编程

2. 制作一个跳跃的小球游戏(Pygame基本使用)

  • 创建一个游戏窗口,然后在窗口内创建一个小球。以一定速度移动小球,当小球碰到游戏窗口的边缘时,小球弹回,继续移动。
    (1)创建一个游戏窗口,宽高设置640*480:
import sys    # 导入sys模块
import pygame    # 导入pygame模块

pygame.init()     # 初始化pygame
size = width,height=640,480     # 设置窗口
screen = pygame.display.set_mode(size)     # 显示窗口
  • 上述代码中,首先导入pygame模块,然后调用init()方法初始化pygame模块。接下来设置窗口的宽和高,最后使用display模块显示窗体。
  • display模块的常用方法:
方法名 功能
pygame.display.init 初始化display模块。
pygame.display.quit 结束display模块。
pygame.display.get_init 如果display模块已经被初始化,则返回True。
pygame.display.set_mode 初始化一个准备显示的界面。
pygame.display.get_surface 获取当前的Surface对象。
pygame.display.flip 更新整个待显示的Surface对象到屏幕上。
pygame.display.update 更新部分内容显示到屏幕上,如果没有参数则与flip功能相同。
(2)运行上述代码,会出现一个一闪而过的黑色窗口,这是因为程序执行完成后会自动关闭。如果让窗口一直显示,需要使用while True让程序一直执行,此外,还需要设置关闭按钮。代码具体如下:
# -*-coding:utf-8 -*-
import sys    # 导入sys模块
import pygame   # 导入pygame模块

pygame.init()     # 初始化pygame
size = width, height = 640, 480    # 设置窗口
screen = pygame.display.set_mode(size)   # 显示窗口

# 执行死循环,确保窗口一直显示
while True:
    # 检查事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:   # 如果单击关闭窗口,则退出
            sys.exit()
pygame.quit()     # 退出pygame
  • 上述代码中,添加了轮询事件检测。pygame.event.get()能够获取事件队列,使用for…in遍历事件,然后根据type属性判断事件类型。这里的事件处理方式与GUI类似,如event.type等于pygame.GUIT表示检测到关闭pygame窗口事件,pygame.KEYDOWN表示键盘按下事件pygame.MOUSEBUTTONDOWN表示鼠标按下事件等。
    (3)在窗口中添加小球。我们先准备好一张ball.png图片,然后加载该图片,最后将图片显示在窗口中:
# #######################1. 窗口一闪而过
# import sys    # 导入sys模块
# import pygame    # 导入pygame模块
#
# pygame.init()     # 初始化pygame
# size = width,height=640,480     # 设置窗口
# screen = pygame.display.set_mode(size)     # 显示窗口

# ##############################2. 窗口持续
# # -*-coding:utf-8 -*-
# import sys    # 导入sys模块
# import pygame   # 导入pygame模块
#
# pygame.init()     # 初始化pygame
# size = width, height = 640, 480    # 设置窗口
# 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. 添加ball的窗口
# -*-coding:utf-8 -*-
import sys    # 导入sys模块
import pygame   # 导入pygame模块

pygame.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
  • 上述代码使用image模块的load()方法加载图片,返回值ball是一个Surface对象。Surface是用来代表图片的pygame对象,可以对一个Surface对象进行涂画、变形、复制等各种操作。事实上,屏幕也只是一个surface,pygame.display.set_mode就返回一个屏幕Surface对象。如果将ball这个Surface对象画到screen.Surface对象,需要使用blit()方法,最后使用display模块的flip方法更新整个待显示的Surface对象到屏幕上。
  • 运行结果如下:
    PyGame游戏编程
  • Surface对象的常用方法如下:
方法名 功能
pygame.Surface.blit 将一个图像画到另一个图像上。
pygame.Surface.convert 转换图像的像素格式。
pygame.Surface.convert_alpha 转换图像的像素格式,包含alpha通道的转换。
pygame.Surface.fill 使用颜色填充Surface
pygame.Surface.get_rect 获取Surface的矩形区域。

(4)下面该让小球动起来了。ball.get_rect()方法返回值ballrect()方法返回值ballrect是一个Rect对象,该对象有一个move()方法可用于移动矩形。move(x,y)函数有两个参数,第一个参数是X轴移动的距离,第二个参数是Y轴移动的距离。窗体左上角坐标为(0,0),例如move(100,50)。

  • 为实现小球不停地移动,将move()函数添加到while循环内:
# -*- coding:utf-8-*-
import sys
import pygame

pygame.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()       # 获取矩形区域

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()     # 退出pygame

PyGame游戏编程

  • 运行上述代码,小球在屏幕中一闪而过,此时,小球并没有真正消失,而是移动到窗体外了,此时需要添加碰撞检测的功能。当小球与窗体的任一边缘发生碰撞,则改变小球的移动方向:
# -*- coding:utf-8 -*-
import sys    # 导入sys模块
import pygame     # 导入pygame模块

pygame.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()    # 获取矩形区域

speed = [1, 1]      # 设置移动的X轴、Y轴距离
# 执行死循环,确保窗口一直显示
while True:
    # 检查事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:     # 如果单击关闭窗口,则退出
            sys.exit()
    ballrect = ballrect.move(speed)     # 移动小球
    # 碰到左右边缘
    if ballrect.left < 0 or ballrect.right > width:
        speed[0] = -speed[0]
    # 碰到上下边缘
    if ballrect.top < 0 or ballrect.bottom > height:
        speed[1] = -speed[1]
    screen.fill(color)      # 填充颜色
    screen.blit(ball, ballrect)     # 将图片画到窗口上
    pygame.display.flip()     # 更新全部显示

pygame.quit()     # 退出pygame
  • 上述代码中,添加了碰撞检测功能。如果球碰到左右边缘,则更改X轴数据为负数;如果碰到上下边缘,则改Y轴数据为负数。
  • 运行结果如下:
    PyGame游戏编程
    (6)运行上述代码发现好像有多个小球在飞快移动,这是因为运行上述代码的时间非常短,导致肉眼错觉,因此需要添加一个“时钟”来控制程序运行时间。用pygame的time模块控制。使用pygame时钟前,必须先创建一个Clock对象的一个实例,然后在while循环中设置多长时间运行一次。代码如下:
# -*- coding:utf-8 -*-
import sys    # 导入sys模块
import pygame    # 导入pygame模块

pygame.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()   # 获取矩形区域

speed = [5, 5]     # 设置移动的X轴、Y轴距离
clock = pygame.time.Clock()     # 设置时钟
# 执行死循环,确保窗口一直显示
while True:
    clock.tick(60)    # 每秒执行60次
    # 检查事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:     # 如果单击关闭窗口,则退出
            sys.exit()
    ballrect = ballrect.move(speed)    # 移动小球
    # 碰到左右边缘
    if ballrect.left < 0 or ballrect.right > width:
        speed[0] = -speed[0]
    # 碰到上下边缘
    if ballrect.top < 0 or ballrect.bottom > height:
        speed[1] = -speed[1]
    screen.fill(color)     # 填充颜色
    screen.blit(ball, ballrect)     # 将图片画到窗口上
    screen.blit(ball, ballrect)     # 将图片画到窗口上
    pygame.display.flip()    # 更新全部显示
pygame.quit()      # 退出pygame
  • 至此,就完成了跳跃的小球游戏。
  • 运行效果如下:
    PyGame游戏编程

3. 开发Flappy Bird游戏

  • 游戏的素材可以从该网站上找自己喜欢的:https://www.aigei.com/s?tab=file&type=2d&q=flappy+bird&page=3#resContainer
  • 也可以使用我下载的:
    PyGame游戏编程

1. 游戏简介

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

2. 游戏分析

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

3. 搭建主框架

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


class Bird(object):
    """定义一个鸟类"""
    def __init__(self):
        """定义初始化方法"""
        pass

    def birdUpdate(self):
        pass


class Pipeline(object):
    """定义一个管道类"""
    def __init__(self):
        """定义初始化方法"""
        pass

    def updatePipeline(self):
        """水平移动"""
        pass


def createMap(screen, background):
    """定义创建地图的方法"""
    screen.fill((255, 255, 255))     # 填充颜色
    screen.blit(background, (0, 0))    # 填入到背景
    pygame.display.update()    # 更新显示


if __name__ == "__main__":
    """主程序"""
    pygame.init()     # 初始化pygame
    size = width, height = 400, 720    # 设置窗口
    screen = pygame.display.set_mode(size)    # 显示窗口
    clock = pygame.time.Clock()    # 设置时钟
    Pipeline = Pipeline()     # 实例化管道类
    Bird = Bird()    # 实例化鸟类
    while True:
        clock.tick(60)     # 每秒执行60次
        # 轮询事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
        background = pygame.image.load("assets/background.png")     # 加载背景图片
        createMap(screen, background)    # 绘制地图
    pygame.quit()    # 退出

  • 运行结果如下:
    PyGame游戏编程

4. 创建小鸟类

  • 下面创建小鸟类。该类需要初始化很多参数,所以定义一个__init__()方法,用来初始化各种参数,包括鸟飞行的几种状态、飞行的速度、跳跃的高度等。然后定义birdUpdate()方法,该方法用于实现小鸟的跳跃和坠落。接下来,在主逻辑的轮询事件中添加键盘按下事件或鼠标单击事件,如按下鼠标,使小鸟上升等。最后,在createMap()方法中显示小鸟的图像。
    PyGame游戏编程
    PyGame游戏编程
    PyGame游戏编程
import pygame
import sys
import random
# 素材参考地址:https://www.aigei.com/s?q=flappy+bird&type=2d


class Bird(object):
    """定义一个鸟类"""
    def __init__(self):
        """定义初始化方法"""
        self.birdRect = pygame.Rect(65, 50, 50, 50)    # 鸟的矩形
        # 定义鸟的3种状态列表
        self.birdStatus = [pygame.image.load("assets/1.png"),
                           pygame.image.load("assets/2.png"),
                           pygame.image.load("assets/dead.png")]
        self.status = 0   # 默认飞行状态
        self.birdX = 120   # 鸟所在X轴坐标
        self.birdY = 350    # 鸟所在Y轴坐标,即上下飞行高度
        self.jump = False      # 默认情况小鸟自动降落
        self.jumpSpeed = 10    # 跳跃高度
        self.gravity = 5    # 重力
        self.dead = False     # 默认小鸟生命状态为活着

    def birdUpdate(self):
        if self.jump:
            # 小鸟跳跃
            self.jumpSpeed -= 1    # 速度递减,上升越来越慢
            self.birdY -= self.jumpSpeed    # 鸟Y轴坐标减小,小鸟上升
        else:
            # 小鸟坠落
            self.gravity += 0.2     # 重力递增,下降越来越快
            self.birdY += self.gravity      # 鸟Y轴坐标增加,小鸟下降
        self.birdRect[1] = self.birdY    # 更改Y轴位置


class Pipeline(object):
    """定义一个管道类"""
    def __init__(self):
        """定义初始化方法"""
        pass

    def updatePipeline(self):
        """水平移动"""
        pass


def createMap(screen, background):
    """定义创建地图的方法"""
    screen.fill((255, 255, 255))     # 填充颜色
    screen.blit(background, (0, 0))    # 填入到背景
    # 显示小鸟
    if Bird.dead:     # 撞管道状态
        Bird.status = 2
    elif Bird.jump:    # 起飞状态
        Bird.status = 1
    screen.blit(Bird.birdStatus[Bird.status], (Bird.birdX, Bird.birdY))    # 设置小鸟的坐标
    Bird.birdUpdate()     # 鸟移动
    pygame.display.update()    # 更新显示


if __name__ == "__main__":
    """主程序"""
    pygame.init()     # 初始化pygame
    size = width, height = 400, 720    # 设置窗口
    screen = pygame.display.set_mode(size)    # 显示窗口
    clock = pygame.time.Clock()    # 设置时钟
    Pipeline = Pipeline()     # 实例化管道类
    Bird = Bird()    # 实例化鸟类
    while True:
        clock.tick(60)     # 每秒执行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 = 5    # 重力
                Bird.jumpSpeed = 10     # 跳跃速度
        background = pygame.image.load("assets/background.png")     # 加载背景图片
        createMap(screen, background)    # 绘制地图
    pygame.quit()    # 退出


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

PyGame游戏编程

5. 创建管道类

  • 创建完鸟类之后,我们来创建管道类。同样,在_init_()方法中初始化各种参数,包括设置管道的坐标,加载上下管道图片等。然后在updatePipline()方法中,定义管道向左移动的速度,并且当管道移出屏幕时重新绘制下一组管道。最后,在createMap()函数中显示管道。关键代码如下:
import pygame
import sys
import random
# 素材参考地址:https://www.aigei.com/s?q=flappy+bird&type=2d


class Bird(object):
    """定义一个鸟类"""
    def __init__(self):
        """定义初始化方法"""
        self.birdRect = pygame.Rect(65, 50, 50, 50)    # 鸟的矩形
        # 定义鸟的3种状态列表
        self.birdStatus = [pygame.image.load("assets/1.png"),
                           pygame.image.load("assets/2.png"),
                           pygame.image.load("assets/dead.png")]
        self.status = 0   # 默认飞行状态
        self.birdX = 120   # 鸟所在X轴坐标
        self.birdY = 350    # 鸟所在Y轴坐标,即上下飞行高度
        self.jump = False      # 默认情况小鸟自动降落
        self.jumpSpeed = 10    # 跳跃高度
        self.gravity = 5    # 重力
        self.dead = False     # 默认小鸟生命状态为活着

    def birdUpdate(self):
        if self.jump:
            # 小鸟跳跃
            self.jumpSpeed -= 1    # 速度递减,上升越来越慢
            self.birdY -= self.jumpSpeed    # 鸟Y轴坐标减小,小鸟上升
        else:
            # 小鸟坠落
            self.gravity += 0.2     # 重力递增,下降越来越快
            self.birdY += self.gravity      # 鸟Y轴坐标增加,小鸟下降
        self.birdRect[1] = self.birdY    # 更改Y轴位置


class Pipeline(object):
    """定义一个管道类"""
    def __init__(self):
        """定义初始化方法"""
        self.wallx = 400      # 管道所在X轴坐标
        self.pineUp = pygame.image.load("assets/top.png")     # 加载上管道图片
        self.pineDown = pygame.image.load("assets/bottom.png")     # 加载下管道图片

    def updatePipeline(self):
        """管道水平移动方法"""
        self.wallx -= 5      # 管道X轴坐标递减,即管道向左移动
        # 当管道运行到一定位置,即小鸟飞越管道,分数加1,并且管道重置
        if self.wallx < -80:
            self.wallx = 400


def createMap(screen, background):
    """定义创建地图的方法"""
    screen.fill((255, 255, 255))     # 填充颜色
    screen.blit(background, (0, 0))    # 填入到背景

    # 显示管道
    screen.blit(Pipeline.pineUp, (Pipeline.wallx, -300))     # 上管道坐标位置(X,Y)
    screen.blit(Pipeline.pineDown, (Pipeline.wallx, 500))    # 下管道坐标位置(X,Y)
    Pipeline.updatePipeline()      # 管道移动

    # 显示小鸟
    if Bird.dead:     # 撞管道状态
        Bird.status = 2
    elif Bird.jump:    # 起飞状态
        Bird.status = 1
    screen.blit(Bird.birdStatus[Bird.status], (Bird.birdX, Bird.birdY))    # 设置小鸟的坐标
    Bird.birdUpdate()     # 鸟移动

    pygame.display.update()    # 更新显示


if __name__ == "__main__":
    """主程序"""
    pygame.init()     # 初始化pygame
    size = width, height = 400, 720    # 设置窗口
    screen = pygame.display.set_mode(size)    # 显示窗口
    clock = pygame.time.Clock()    # 设置时钟
    Pipeline = Pipeline()     # 实例化管道类
    Bird = Bird()    # 实例化鸟类
    while True:
        clock.tick(60)     # 每秒执行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 = 5    # 重力
                Bird.jumpSpeed = 10     # 跳跃速度
        background = pygame.image.load("assets/background.png")     # 加载背景图片
        createMap(screen, background)    # 绘制地图
    pygame.quit()    # 退出

  • 上述代码中,在createMap()函数中,设置先显示管道,再显示小鸟。这样做的目的是,当小鸟与管道图像重合的时候,小鸟的图像显示在上层,而管道的图像显示在底层。运行结果如下:
    PyGame游戏编程

6. 计算得分

  • 当小鸟飞过管道时,玩家得分加1.这里对于飞过管道的逻辑做了简化处理:当管道移动到窗体左侧一定距离后,默认小鸟飞过管道,使分数加1,并显示在屏幕上。在updatePipeline()方法中实现该功能。代码如下:
import pygame
import sys
import random
# 素材参考地址:https://www.aigei.com/s?q=flappy+bird&type=2d




class Bird(object):
    """定义一个鸟类"""
    def __init__(self):
        """定义初始化方法"""
        self.birdRect = pygame.Rect(65, 50, 50, 50)    # 鸟的矩形
        # 定义鸟的3种状态列表
        self.birdStatus = [pygame.image.load("assets/1.png"),
                           pygame.image.load("assets/2.png"),
                           pygame.image.load("assets/dead.png")]
        self.status = 0   # 默认飞行状态
        self.birdX = 120   # 鸟所在X轴坐标
        self.birdY = 350    # 鸟所在Y轴坐标,即上下飞行高度
        self.jump = False      # 默认情况小鸟自动降落
        self.jumpSpeed = 10    # 跳跃高度
        self.gravity = 5    # 重力
        self.dead = False     # 默认小鸟生命状态为活着

    def birdUpdate(self):
        if self.jump:
            # 小鸟跳跃
            self.jumpSpeed -= 1    # 速度递减,上升越来越慢
            self.birdY -= self.jumpSpeed    # 鸟Y轴坐标减小,小鸟上升
        else:
            # 小鸟坠落
            self.gravity += 0.2     # 重力递增,下降越来越快
            self.birdY += self.gravity      # 鸟Y轴坐标增加,小鸟下降
        self.birdRect[1] = self.birdY    # 更改Y轴位置


class Pipeline(object):
    """定义一个管道类"""
    def __init__(self):
        """定义初始化方法"""
        self.wallx = 400      # 管道所在X轴坐标
        self.pineUp = pygame.image.load("assets/top.png")     # 加载上管道图片
        self.pineDown = pygame.image.load("assets/bottom.png")     # 加载下管道图片

    def updatePipeline(self):
        """管道水平移动方法"""
        self.wallx -= 5      # 管道X轴坐标递减,即管道向左移动
        # 当管道运行到一定位置,即小鸟飞越管道,分数加1,并且管道重置
        if self.wallx < -80:
            global score
            score += 1
            self.wallx = 400


def createMap(screen, background, font):
    """定义创建地图的方法"""
    screen.fill((255, 255, 255))     # 填充颜色
    screen.blit(background, (0, 0))    # 填入到背景

    # 显示管道
    screen.blit(Pipeline.pineUp, (Pipeline.wallx, -100))     # 上管道坐标位置(X,Y)
    screen.blit(Pipeline.pineDown, (Pipeline.wallx, 500))    # 下管道坐标位置(X,Y)
    Pipeline.updatePipeline()      # 管道移动

    # 显示小鸟
    if Bird.dead:     # 撞管道状态
        Bird.status = 2
    elif Bird.jump:    # 起飞状态
        Bird.status = 1
    screen.blit(Bird.birdStatus[Bird.status], (Bird.birdX, Bird.birdY))    # 设置小鸟的坐标
    Bird.birdUpdate()     # 鸟移动

    # 显示分数
    screen.blit(font.render("score: " + str(score), -1, (255, 255, 255)), (230, 20))    # 设置颜色及坐标位置

    pygame.display.update()    # 更新显示


if __name__ == "__main__":
    """主程序"""
    pygame.init()     # 初始化pygame
    pygame.font.init()    # 初始化字体
    font = pygame.font.SysFont(None, 50)    # 设置默认字体和大小
    size = width, height = 400, 680    # 设置窗口
    screen = pygame.display.set_mode(size)    # 显示窗口
    clock = pygame.time.Clock()    # 设置时钟
    Pipeline = Pipeline()     # 实例化管道类
    Bird = Bird()    # 实例化鸟类
    score = 0    # 初始化分数
    while True:
        clock.tick(60)     # 每秒执行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 = 5    # 重力
                Bird.jumpSpeed = 10     # 跳跃速度
        background = pygame.image.load("assets/background.png")     # 加载背景图片
        createMap(screen, background, font)    # 绘制地图
    pygame.quit()    # 退出

  • 运行效果如下:
    PyGame游戏编程

7. 碰撞检测

  • 当小鸟与管道相碰撞时,小鸟颜色变为灰色,游戏结束,并且显示总分数。在checkDead()函数中通过pygame.Rect()可以分别获取小鸟的矩形区域对象和管道的矩形区域对象,该对象有一个colliderect()方法可以判断俩各个矩形区域是否相碰撞。如果相碰撞,设置Bird.dead属性为True。此外,当小鸟飞出窗体时,也设置Bird.dead属性为True。最后,用两行文字显示总成绩。关键代码如下:
import pygame
import sys
import random
# 素材参考地址:https://www.aigei.com/s?q=flappy+bird&type=2d


class Bird(object):
    """定义一个鸟类"""
    def __init__(self):
        """定义初始化方法"""
        self.birdRect = pygame.Rect(65, 50, 50, 50)    # 鸟的矩形
        # 定义鸟的3种状态列表
        self.birdStatus = [pygame.image.load("assets/1.png"),
                           pygame.image.load("assets/2.png"),
                           pygame.image.load("assets/dead.png")]
        self.status = 0   # 默认飞行状态
        self.birdX = 120   # 鸟所在X轴坐标
        self.birdY = 350    # 鸟所在Y轴坐标,即上下飞行高度
        self.jump = False      # 默认情况小鸟自动降落
        self.jumpSpeed = 10    # 跳跃高度
        self.gravity = 5    # 重力
        self.dead = False     # 默认小鸟生命状态为活着

    def birdUpdate(self):
        if self.jump:
            # 小鸟跳跃
            self.jumpSpeed -= 1    # 速度递减,上升越来越慢
            self.birdY -= self.jumpSpeed    # 鸟Y轴坐标减小,小鸟上升
        else:
            # 小鸟坠落
            self.gravity += 0.2     # 重力递增,下降越来越快
            self.birdY += self.gravity      # 鸟Y轴坐标增加,小鸟下降
        self.birdRect[1] = self.birdY    # 更改Y轴位置


class Pipeline(object):
    """定义一个管道类"""
    def __init__(self):
        """定义初始化方法"""
        self.wallx = 400      # 管道所在X轴坐标
        self.pineUp = pygame.image.load("assets/top.png")     # 加载上管道图片
        self.pineDown = pygame.image.load("assets/bottom.png")     # 加载下管道图片

    def updatePipeline(self):
        """管道水平移动方法"""
        self.wallx -= 5      # 管道X轴坐标递减,即管道向左移动
        # 当管道运行到一定位置,即小鸟飞越管道,分数加1,并且管道重置
        if self.wallx < -80:
            global score
            score += 1
            self.wallx = 400


def createMap(screen, background, font):
    """定义创建地图的方法"""
    screen.fill((255, 255, 255))     # 填充颜色
    screen.blit(background, (0, 0))    # 填入到背景

    # 显示管道
    screen.blit(Pipeline.pineUp, (Pipeline.wallx, -100))     # 上管道坐标位置(X,Y)
    screen.blit(Pipeline.pineDown, (Pipeline.wallx, 500))    # 下管道坐标位置(X,Y)
    Pipeline.updatePipeline()      # 管道移动

    # 显示小鸟
    if Bird.dead:     # 撞管道状态
        Bird.status = 2
    elif Bird.jump:    # 起飞状态
        Bird.status = 1
    screen.blit(Bird.birdStatus[Bird.status], (Bird.birdX, Bird.birdY))    # 设置小鸟的坐标
    Bird.birdUpdate()     # 鸟移动

    # 显示分数
    screen.blit(font.render("score: " + str(score), -1, (255, 255, 255)), (230, 20))    # 设置颜色及坐标位置

    pygame.display.update()    # 更新显示


def checkDead():
    # 上方管子的矩形位置
    upRect = pygame.Rect(Pipeline.wallx, -100,Pipeline.pineUp.get_width() - 10, Pipeline.pineUp.get_height())
    # 下方管子的矩形位置
    downRect = pygame.Rect(Pipeline.wallx, 500, Pipeline.pineDown.get_width() - 10, Pipeline.pineDown.get_height())
    # 检测小鸟与上下方管子是否碰撞
    if upRect.colliderect(Bird.birdRect) or downRect.colliderect(Bird.birdRect):
        Bird.dead = True
        return True
    else:
        return False


def getResult():
    final_text1 = "Game over"
    final_text2 = "Your final score is: " + str(score)
    ft1_font = pygame.font.SysFont("Arial", 70)      # 设置第一行文字字体
    ft1_surf = ft1_font.render(final_text1, 1, (242, 3, 36))     # 设置第一行文字的颜色
    ft2_font = pygame.font.SysFont("Arial", 50)     # 设置第二行文字字体
    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()     # 初始化pygame
    pygame.font.init()    # 初始化字体
    font = pygame.font.SysFont(None, 50)    # 设置默认字体和大小
    size = width, height = 400, 680    # 设置窗口
    screen = pygame.display.set_mode(size)    # 显示窗口
    clock = pygame.time.Clock()    # 设置时钟
    Pipeline = Pipeline()     # 实例化管道类
    Bird = Bird()    # 实例化鸟类
    score = 0    # 初始化分数
    while True:
        clock.tick(60)     # 每秒执行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 = 5    # 重力
                Bird.jumpSpeed = 10     # 跳跃速度
        background = pygame.image.load("assets/background.png")     # 加载背景图片
        if checkDead():   # 检测小鸟生命状态
            getResult()     # 如果小鸟死亡,游戏结束,显示游戏总分数
        else:
            createMap(screen, background, font)    # 绘制地图
    pygame.quit()    # 退出

  • 上述代码的checkDead()方法中,upRect.colliderect(Bird.birdRect)用于检测小鸟的矩形区域是否与上管道的矩形区域相撞,colliderect()函数的参数是另一个矩形区域对象。碰撞后小鸟死亡的情况如下图:

PyGame游戏编程文章来源地址https://www.toymoban.com/news/detail-477924.html

  • 本实例已经实现了Flappy Bird的基本功能,但还有很多需要完善的地方,如设置游戏的难度,包括设置管道的高度、小鸟的飞行速度等。

4. 小结

  • 主要讲解了如何使用Pygame开发游戏。首先通过一个跳跃的小球游戏来了解Pygame的基本使用方法,然后利用Python逐步开发一个知名游戏Flappy Bird。通过本章的学习,可以掌握Pygame的基础知识,并使用Python面向对象的思维方式开发一个Python小游戏,进一步体会Python编程的乐趣。

到了这里,关于PyGame游戏编程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 15. python从入门到精通——Pygame游戏编程

    目录 游戏的原理 安装Pygame Pygame常用模块 Pygame的基本使用      实例:制作一个跳跃的小球游戏,如果碰到窗口边缘会改变小球移动方向 实现步骤:  运行效果: 小球图片:      python代码: 开发Flappy Bird游戏 游戏简介: 运行效果: 图片素材 游戏分析  以面向对象的思维

    2024年02月12日
    浏览(45)
  • Python “贪吃蛇”游戏,在不断改进中学习pygame编程

    目录 前言 改进过程一 增加提示信息 原版帮助摘要 pygame.draw pygame.font class Rect class Surface 改进过程二 增加显示得分 改进过程三 增加背景景乐 增加提示音效 音乐切换 静音切换 mixer.music.play 注意事项 原版帮助摘要 pygame.mixer pygame.mixer.Sound 改进过程四 增加WASD方向键 增加退出事

    2024年02月12日
    浏览(53)
  • 强化学习Agent系列(一)——PyGame游戏编程,Python 贪吃蛇制作实战教学

    大家好,未来的开发者们请上座 随着人工智能的发展,强化学习基本会再次来到人们眼前,遂想制作一下相关的教程。强化学习第一步基本离不开虚拟环境的搭建,下面用大家耳熟能详的贪吃蛇游戏为基础,制作一个Agent,完成对这个游戏的绝杀。 万里长城第一步:用pytho

    2024年01月21日
    浏览(65)
  • 基于Python+Pygame实现一个俄罗斯方块小游戏【完整代码】

    俄罗斯方块,一款起源于上世纪80年代的经典电子游戏,凭借简单的规则和独特的魅力,一跃成为全球家喻户晓的经典。你知道其实只需要一些基础的编程知识,就可以自己实现它吗?今天,我们将使用Python的Pygame库,一步步带你构建属于自己的俄罗斯方块小游戏! 游戏初始

    2024年02月04日
    浏览(50)
  • 很合适新手入门使用的Python游戏开发包pygame实例教程-01[开发环境配置与第一个界面]

    我们假定你已经安装好了我们开发python程序的sublime text,如果不知道怎么安装的可以参照我前面的博文。这里只需要解决的是配置好Pygame的问题。本篇博文主要解决开发环境配置以及第一个游戏界面的显示问题。 文章原出处: https://blog.csdn.net/haigear/article/details/130173836 没有

    2024年01月25日
    浏览(96)
  • PyGame游戏编程

    Python非常受欢迎的一个原因是它的应用领域非常广泛,其中就包括游戏开发。而是用Python进行游戏开发的首选模块就是PyGame。 PyGame是跨平台Python模块,专为电子游戏设计,包含图像、声音等,创建在SDL(Simple DirectMedia Layer)基础上,允许实时电子游戏研发而不会被低级语言,

    2024年02月08日
    浏览(43)
  • 打地鼠游戏编程代码,pygame打地鼠游戏代码

    大家好,小编来为大家解答以下问题,打地鼠游戏编程代码,pygame打地鼠游戏代码,今天让我们一起来看看吧! 文章目录 0 项目简介 1 游戏介绍 2 实现效果 3 开发工具 3.1 环境配置 3.2 Pygame介绍 4 具体实现 4.1 实现游戏精灵类 4.2 实现游戏主循环 4.3 制作简易的游戏开始和结束

    2024年01月25日
    浏览(42)
  • Erocool是一个编程项目 - 实现一个基于Python的简单游戏

    在这篇文章中,我们将探讨一个名为Erocool的编程项目,它是一个基于Python的简单游戏。我们将详细介绍这个项目的目标、功能和实现细节,并提供相应的源代码。 Erocool项目的目标是创建一个有趣的游戏,其中玩家需要通过键盘输入正确的答案来解决问题。这个游戏的主题是

    2024年01月23日
    浏览(53)
  • 使用Pygame创建一个简单游戏界面

    首先需要安装Pygame 模块,在Python代码中添加引用。 1. 引用代码如下: 2. 定义初始化窗口函数: 在初始化窗口函数中,定义窗口大小和窗口标题。 3. 创建一个循环,不断更新界面和检测事件 加载背景图片,将背景图片对象放置在窗口上,位置(0,0) 最左角,图片有实际的

    2024年02月13日
    浏览(49)
  • 使用Pygame做一个乒乓球游戏

    使用 Pygame 做一个乒乓球游戏。左侧为电脑,右侧为玩家。 视频地址-YT 视频搬运-B站 视频教程约90分钟。 代码地址 环境:需要 pygame 库,可用pip安装: pip install pygame 首先进行一些 初始化 ,初始化pygame以及物体的初始状态。 然后是 主循环 ,游戏的主循环主要包含3个内容

    2024年04月16日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包