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

Python 课程16-Pygame

前言

Pygame 是一个基于 Python 的游戏开发库,专门用于多媒体应用程序开发,特别是 2D 游戏。它提供了处理图像、声音、键盘、鼠标等交互功能的 API,并且能够与 OpenGL 集成,用于更复杂的图形操作。Pygame 是初学者和业余开发者学习游戏开发的绝佳选择,它简洁易懂,且功能强大。

本教程将为你提供 Pygame 的超详细介绍,从基础的窗口创建、图像加载到高级的游戏开发技巧,涵盖所有关键功能。


目录

  1. Pygame 基础

    • 安装 Pygame
    • 创建窗口
    • 设置帧率与游戏循环
    • 加载与显示图像
  2. 事件处理与用户输入

    • 处理键盘输入
    • 处理鼠标输入
    • 退出游戏
  3. 图像与精灵

    • 使用图像与表面(Surface)
    • 精灵与精灵组
    • 动画与精灵更新
  4. 声音与音乐

    • 加载与播放声音
    • 控制音量与声音效果
  5. 碰撞检测

    • 矩形碰撞检测
    • 精灵之间的碰撞检测
  6. 游戏开发技巧

    • 计分系统与游戏状态
    • 定时器与倒计时
    • 随机事件生成

1. Pygame 基础

安装 Pygame

可以通过 pip 安装 Pygame:

pip install pygame

 导入 Pygame:

import pygame
创建窗口

Pygame 使用 pygame.display.set_mode() 函数来创建窗口。

  • 创建窗口并设置标题
import pygame

# 初始化 Pygame
pygame.init()

# 创建一个宽 800、高 600 的窗口
screen = pygame.display.set_mode((800, 600))

# 设置窗口标题
pygame.display.set_caption('My Pygame Window')

# 设置窗口背景颜色
screen.fill((0, 0, 255))  # 蓝色背景

# 更新窗口
pygame.display.update()

# 退出 Pygame
pygame.quit()
设置帧率与游戏循环

游戏的核心是游戏循环,它不断运行以更新屏幕和处理用户输入。可以使用 pygame.time.Clock() 来控制帧率。

  • 设置帧率
# 创建时钟对象
clock = pygame.time.Clock()

# 游戏循环
running = True
while running:
    # 处理事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # 更新窗口
    pygame.display.update()

    # 控制帧率为 60 帧/秒
    clock.tick(60)

pygame.quit()
加载与显示图像
  • 加载图像并显示
# 加载图像
player_image = pygame.image.load('player.png')

# 显示图像
screen.blit(player_image, (100, 100))  # 将图像绘制在 (100, 100) 位置
pygame.display.update()

你可以使用 pygame.image.load() 加载图片,然后使用 blit() 方法将图片绘制到屏幕上。


2. 事件处理与用户输入

处理键盘输入

你可以使用 pygame.event.get() 来获取用户的键盘输入事件,或者直接使用 pygame.key.get_pressed() 获取当前按键状态。

  • 检测键盘事件
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                print("Left arrow key pressed")
            if event.key == pygame.K_RIGHT:
                print("Right arrow key pressed")
  •  持续检测按键状态
keys = pygame.key.get_pressed()  # 获取当前按键状态
if keys[pygame.K_LEFT]:
    print("Holding left arrow key")
if keys[pygame.K_RIGHT]:
    print("Holding right arrow key")
处理鼠标输入

你可以通过 pygame.mouse.get_pos() 获取鼠标当前位置,或者使用事件来检测鼠标点击。

  • 获取鼠标位置
mouse_pos = pygame.mouse.get_pos()
print(f"Mouse position: {mouse_pos}")
  •  检测鼠标点击
for event in pygame.event.get():
    if event.type == pygame.MOUSEBUTTONDOWN:
        if event.button == 1:  # 左键点击
            print("Left mouse button clicked")
退出游戏

要确保游戏能够正确退出,需要检测 QUIT 事件

for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False

3. 图像与精灵

使用图像与表面(Surface)

Surface 是 Pygame 中的基本图像元素,所有的游戏对象(如背景、角色)都是基于 Surface 绘制的。可以使用 blit() 函数将 Surface 绘制到屏幕上。

  • 创建自定义 Surface
# 创建一个 50x50 像素的红色矩形
red_square = pygame.Surface((50, 50))
red_square.fill((255, 0, 0))

# 绘制到窗口
screen.blit(red_square, (200, 200))
pygame.display.update()
精灵与精灵组

精灵 是 Pygame 中表示游戏对象的类。你可以通过继承 pygame.sprite.Sprite 来创建自己的精灵,并使用 sprite.Group 组织精灵组以便于管理多个精灵。

  • 创建自定义精灵
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load('player.png')
        self.rect = self.image.get_rect()
        self.rect.center = (400, 300)

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.rect.x -= 5
        if keys[pygame.K_RIGHT]:
            self.rect.x += 5

# 创建精灵组
all_sprites = pygame.sprite.Group()

# 创建玩家精灵
player = Player()

# 将玩家精灵添加到精灵组
all_sprites.add(player)

# 游戏循环
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # 更新所有精灵
    all_sprites.update()

    # 绘制精灵
    screen.fill((0, 0, 0))
    all_sprites.draw(screen)
    pygame.display.update()

pygame.quit()
动画与精灵更新
  • 通过精灵更新动画
class AnimatedSprite(pygame.sprite.Sprite):
    def __init__(self, images):
        super().__init__()
        self.images = images
        self.index = 0
        self.image = self.images[self.index]
        self.rect = self.image.get_rect()

    def update(self):
        # 每帧切换到下一个图像
        self.index += 1
        if self.index >= len(self.images):
            self.index = 0
        self.image = self.images[self.index]

# 加载多个动画帧
frames = [pygame.image.load(f'frame_{i}.png') for i in range(5)]

# 创建动画精灵
animated_sprite = AnimatedSprite(frames)
all_sprites.add(animated_sprite)

通过定期更新精灵的图像,Pygame 可以实现流畅的动画效果。


4. 声音与音乐

Pygame 支持加载和播放声音与音乐文件,常用的音频格式有 WAVMP3OGG

加载与播放声音
  • 加载声音文件
# 加载音效
sound = pygame.mixer.Sound('sound.wav')

# 播放音效
sound.play()
控制音量与声音效果
  • 设置音量
sound.set_volume(0.5)  # 将音量设置为 50%
  •  停止播放
sound.stop()  # 停止播放声音
播放背景音乐
  • 加载并播放背景音乐
# 加载并播放背景音乐
pygame.mixer.music.load('background.mp3')
pygame.mixer.music.play(-1)  # 无限循环播放背景音乐
  •  停止背景音乐
pygame.mixer.music.stop()  # 停止播放背景音乐

 


5. 碰撞检测

矩形碰撞检测

Pygame 提供了简单的矩形碰撞检测机制,可以通过精灵的 rect 属性来检测两个对象是否发生碰撞。你可以使用 colliderect() 函数来检测两个矩形是否重叠。

  • 矩形碰撞检测示例
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load('player.png')
        self.rect = self.image.get_rect()
        self.rect.center = (400, 300)

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.rect.x -= 5
        if keys[pygame.K_RIGHT]:
            self.rect.x += 5

class Enemy(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load('enemy.png')
        self.rect = self.image.get_rect()
        self.rect.center = (600, 300)

    def update(self):
        self.rect.x -= 3  # 让敌人向左移动

# 创建玩家和敌人
player = Player()
enemy = Enemy()

# 游戏循环
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # 更新精灵
    player.update()
    enemy.update()

    # 碰撞检测
    if player.rect.colliderect(enemy.rect):
        print("Collision detected!")
        running = False  # 停止游戏

    # 绘制屏幕
    screen.fill((0, 0, 0))
    screen.blit(player.image, player.rect)
    screen.blit(enemy.image, enemy.rect)
    pygame.display.update()

pygame.quit()
精灵之间的碰撞检测

Pygame 也提供了精灵组之间的碰撞检测功能,可以使用 pygame.sprite.collide_rect()pygame.sprite.groupcollide() 检测精灵组中的多个精灵是否发生碰撞。

  • 精灵组碰撞检测
# 使用 collide_rect 检测两个精灵是否碰撞
if pygame.sprite.collide_rect(player, enemy):
    print("Player and Enemy collided!")

# 使用 groupcollide 检测两个精灵组中的精灵是否碰撞
collisions = pygame.sprite.groupcollide(player_group, enemy_group, False, True)
if collisions:
    print("Collision detected between sprite groups!")

 groupcollide() 的参数:

  • 第一个参数是第一个精灵组。
  • 第二个参数是第二个精灵组。
  • 第三个参数表示是否在发生碰撞时删除第一个组中的精灵。
  • 第四个参数表示是否在发生碰撞时删除第二个组中的精灵。

 


6. 游戏开发技巧

计分系统与游戏状态

在游戏中,我们经常需要追踪分数和管理游戏状态(如游戏是否结束)。你可以使用变量来存储游戏的分数,并在屏幕上显示。

  • 计分系统示例
# 初始化分数
score = 0
font = pygame.font.Font(None, 36)  # 设置字体

# 游戏循环
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # 更新分数
    score += 1

    # 绘制屏幕
    screen.fill((0, 0, 0))

    # 在屏幕上显示分数
    score_text = font.render(f'Score: {score}', True, (255, 255, 255))
    screen.blit(score_text, (10, 10))

    pygame.display.update()

pygame.quit()
定时器与倒计时

你可以使用 pygame.time.get_ticks() 来获取从程序开始运行以来经过的时间(以毫秒为单位)。通过计算时间差,你可以实现倒计时功能。

  • 倒计时示例
# 初始化倒计时
start_time = pygame.time.get_ticks()
countdown = 30  # 30 秒倒计时

# 游戏循环
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # 计算剩余时间
    elapsed_time = (pygame.time.get_ticks() - start_time) // 1000
    remaining_time = max(0, countdown - elapsed_time)

    # 绘制倒计时
    screen.fill((0, 0, 0))
    timer_text = font.render(f'Time: {remaining_time}', True, (255, 255, 255))
    screen.blit(timer_text, (10, 50))
    pygame.display.update()

    # 如果时间到了,结束游戏
    if remaining_time <= 0:
        running = False

pygame.quit()
随机事件生成

Pygame 可以使用 Python 的 random 模块来生成随机事件,如生成敌人的随机位置或道具掉落。

  • 生成随机位置的敌人
import random

class Enemy(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load('enemy.png')
        self.rect = self.image.get_rect()
        self.rect.x = random.randint(0, 800)
        self.rect.y = random.randint(0, 600)

    def update(self):
        self.rect.x -= 3  # 让敌人向左移动

# 创建敌人精灵组
enemy_group = pygame.sprite.Group()

# 生成 5 个随机位置的敌人
for _ in range(5):
    enemy = Enemy()
    enemy_group.add(enemy)

你可以通过 random.randint() 随机生成数值,并将这些数值用于控制对象的生成位置、运动方向等。


结论

通过本详细的 Pygame 教程,你已经学习了如何使用 Pygame 创建游戏,包括窗口设置、用户输入处理、图像与精灵管理、声音播放、碰撞检测和游戏逻辑控制。通过掌握这些功能,你可以轻松开发 2D 游戏,并逐步构建复杂的游戏机制。


http://www.kler.cn/a/316082.html

相关文章:

  • 华为路由策略配置
  • 【AI构思渲染】网络直播——建筑绘图大模型生成渲染图
  • StructuredStreaming (一)
  • 基于springboot的汽车租赁管理系统的设计与实现
  • Elasticsearch 8.16:适用于生产的混合对话搜索和创新的向量数据量化,其性能优于乘积量化 (PQ)
  • 使用Python实现定期从API获取数据并存储到数据库的完整指南
  • LabVIEW软件维护的内容是什么呢?
  • [2025]基于微信小程序慢性呼吸系统疾病的健康管理(源码+文档+解答)
  • 【数据结构与算法 | 灵神题单 | 栈基础篇】力扣155, 1472, 1381
  • 微信小程序03-页面交互
  • vue3中使用iframe不成功的问题
  • 逻辑回归 和 支持向量机(SVM)比较
  • 【深入理解SpringCloud微服务】了解微服务的熔断、限流、降级,手写实现一个微服务熔断限流器
  • 【spring】引入 Jackson 依赖 对java对象序列号和反序列化
  • 基于单片机的智能温控风扇系统的设计
  • C语言实现冒泡排序
  • 在泰国旅游不会口语怎么办?求推荐翻译软件!!!
  • 网安新声 | 黎巴嫩BP机爆炸事件带来的安全新挑战与反思
  • 计算机毕业设计选题推荐-基于python+Django的全屋家具定制服务平台
  • Vue3实现类ChatGPT聊天式流式输出(vue-sse实现)
  • torch.embedding 报错 IndexError: index out of range in self
  • 数据结构之二叉树遍历
  • 【Linux系统编程】第二十一弹---进程的地址空间
  • 《概率论与数理统计》学渣笔记
  • uni-app功能 1. 实现点击置顶,滚动吸顶2.swiper一个轮播显示一个半内容且实现无缝滚动3.穿透修改uni-ui的样式
  • 美团测开OC!