《Python 飞机大战》(二)PyGame

这一章节,我们主要学习 PyGame 相关的内容,为后面《飞机大战》程序的编写做铺垫。主要内容如下:

  1. PyGame 游戏窗口创建
  2. PyGame 图像绘制操作
  3. PyGame 事件处理机制
  4. PyGame 音效相关实现

pygame官网:http://www.pygame.org
pygame手册:http://www.pygame.org/docs/

1. 游戏窗口创建

游戏主窗口创建大致分为以下几个步骤:

  1. 初始化模块
  2. 创建窗口
  3. 设置标题
  4. 窗口循环
import pygame


if __name__ == '__main__':

    # 初始化模块
    pygame.init()

    # 创建窗口
    SCENE_W, SCEBE_H = 512, 768
    window = pygame.display.set_mode([SCENE_W, SCEBE_H])

    # 设置标题
    pygame.display.set_caption("飞机大战")
    clock = pygame.time.Clock()

    while True:
        # 设置 60 帧数
        clock.tick(60)

while 循环被称作窗口的主循环,它主要有两个作用:

  1. 避免程序结束,窗口关闭
  2. 实时在窗口中绘制其他图像

pygame.time.Clock 是 Pygame 中用于控制游戏循环速度的工具。该对象的 tick 方法参数是期望的帧速率(以每秒帧数FPS为单位),它会根据当前时间和上一次调用该方法的时间来计算出需要等待多长时间,以满足目标帧速率。

例如:clock.tick(60) 表示希望游戏以每秒 60 帧的速度运行。它将确保游戏以恒定的速度运行,防止游戏在不同的硬件上表现不一致或运行得太快而变得不可控。

2. 图像绘制操作

游戏中最常用的图像操作,就是能够将图像绘制到指定坐标位置。

import pygame


# 1. 指定位置绘制图像
def test01():

    pygame.init()
    window = pygame.display.set_mode([512, 768])
    clock = pygame.time.Clock()

    # 1.1 加载图像
    image = pygame.image.load('hero.png')
    while True:
        # 1.2 绘制图像
        window.blit(image, (0, 0))
        # 绘制部分图像
        window.blit(image, (100, 100), (0, 0, 70, 70))

        # 1.3 刷新窗口
        pygame.display.update()
        clock.tick(60)


# 2. 绘制图像移动
def test02():

    pygame.init()
    window = pygame.display.set_mode([512, 768])
    clock = pygame.time.Clock()

    # 1.1 加载图像
    image = pygame.image.load('hero.png')
    postion = [0, 0]
    while True:

        # 清空窗口
        window.fill((0, 0, 0))

        # 1.2 绘制图像
        window.blit(image, postion)
        postion[0] += 1
        # 1.3 刷新窗口
        pygame.display.update()
        clock.tick(60)


if __name__ == '__main__':
    test02()

3. 事件处理机制

在窗口的鼠标点击、拖动、键盘等时间都可以通过 PyGame 模块提供的相关 API 进行捕获处理。

import pygame


# 1. 绘制矩形
def test01():

    pygame.init()
    window = pygame.display.set_mode([512, 768])
    pygame.display.set_caption("飞机大战")
    clock = pygame.time.Clock()
    # 创建矩形 (x, y, width, height)
    object = pygame.Rect(100, 100, 50, 50)

    while True:

        window.fill((0, 0, 0))
        # 第一个参数: 窗口对象
        # 第二个参数: 矩形颜色
        # 第三个参数: 位置尺寸
        pygame.draw.rect(window, (0, 0, 255), object)

        pygame.display.update()
        clock.tick(60)


# 2. 鼠标事件
def test02():

    pygame.init()
    window = pygame.display.set_mode([512, 768])
    pygame.display.set_caption("飞机大战")
    clock = pygame.time.Clock()
    # 创建矩形 (x, y, width, height)
    object = pygame.Rect(100, 100, 50, 50)

    is_drag = False
    while True:

        # 清屏
        window.fill((0, 0, 0))
        # 绘制
        pygame.draw.rect(window, (255, 0, 0), object)

        # 获得当前帧所有事件
        event_list = pygame.event.get()
        for event in event_list:

            # 窗口关闭事件
            if event.type == pygame.QUIT:
                pygame.display.quit()
                exit()

            # 鼠标按下事件
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == pygame.BUTTON_LEFT:
                    if object.collidepoint(event.pos):
                        is_drag = True

            # 鼠标弹起事件
            if event.type == pygame.MOUSEBUTTONUP:
                if event.button == pygame.BUTTON_LEFT:
                    is_drag = False

            # 鼠标拖动事件
            if event.type == pygame.MOUSEMOTION:
                if is_drag:
                    # 计算鼠标位置和 object 位置之间的差值
                    dx = event.pos[0] - object[0] - object[2]/2
                    dy = event.pos[1] - object[1] - object[3]/2
                    object.move_ip(dx, dy)

        pygame.display.update()
        clock.tick(30)


# 3. 键盘事件
def test03():

    pygame.init()
    window = pygame.display.set_mode([512, 768])
    pygame.display.set_caption("飞机大战")
    clock = pygame.time.Clock()
    # 创建矩形 (x, y, width, height)
    object = pygame.Rect(100, 100, 50, 50)


    while True:

        # 清屏
        window.fill((0, 0, 0))
        # 绘制
        pygame.draw.rect(window, (255, 0, 0), object)

        # 获得当前帧所有事件
        event_list = pygame.event.get()
        for event in event_list:

            # 窗口关闭事件
            if event.type == pygame.QUIT:
                pygame.display.quit()
                exit()

        # 获得所有键的状态
        keys = pygame.key.get_pressed()
        move_speed = 10
        # 上
        if keys[pygame.K_w]:
            object.move_ip(0, -move_speed)

        # 下
        if keys[pygame.K_s]:
            object.move_ip(0, move_speed)

        # 左
        if keys[pygame.K_a]:
            object.move_ip(-move_speed, 0)

        # 右
        if keys[pygame.K_d]:
            object.move_ip(move_speed, 0)


        pygame.display.update()
        clock.tick(30)


if __name__ == '__main__':
    test03()

4. 音效相关实现

为了增加游戏的效果,我们使用 PyGame 播放游戏背景音乐,并且当爆炸产生时播放音效。

import pygame


# 1. 播放音乐
def test01():

    pygame.init()
    window = pygame.display.set_mode([512, 768])
    pygame.display.set_caption("飞机大战")
    clock = pygame.time.Clock()

    # 1. 加载背景音乐
    pygame.mixer.music.load("bg.wav")
    # 2. 设置背景音乐音量
    pygame.mixer.music.set_volume(0.1)
    # 3. 设备背景音乐播放次数,-1 表示无限循环
    pygame.mixer.music.play(-1)

    while True:
        clock.tick(60)


# 2. 播放音效
def test02():
    pygame.init()
    window = pygame.display.set_mode([512, 768])
    pygame.display.set_caption("飞机大战")
    clock = pygame.time.Clock()

    # 1. 加载音效
    bomb = pygame.mixer.Sound("bomb.wav")
    # 2. 设置音量
    bomb.set_volume(0.1)

    while True:

        # 3. 播放音效
        pygame.mixer.Sound.play(bomb)
        # bomb.play()

        clock.tick(1)


if __name__ == '__main__':
    test02()
未经允许不得转载:一亩三分地 » 《Python 飞机大战》(二)PyGame
评论 (0)

9 + 2 =