Python(白银时代)——pygame 游戏开发

pygame 基本介绍与使用

介绍

  • pygame 就是一个Python 模块,专为电子游戏设计

  • 官方网站:www.pygame.org

  • Pygame 是一个高可移植性的模块可以支持多个操作系统

安装

  • 在命令窗口输入:pip3 install pygame

  • 验证安装成功,在命令窗口输入:python -m pygame.examples.aliens

游戏的初始化与退出

  • 要使用 pygame 提供所有功能之前,需要调用 init 方法

  • 在游戏结束时,需要调用 quit 方法,卸载所有pygame模块

方法说明
pygame.init()导入并初始化所有pygame模块,使用其它模块之前,必须先调用 init 方法
pygame.quit()卸载所有pygame模块,在游戏结束前调用

游戏中的坐标系

  • 原点  指游戏窗口的左上角 ,坐标是 0,0

  • x轴  水平方向向右,逐渐增加

  • y轴  垂直方向向下,逐渐增加

  • 在游戏中,所有可见的元素都是以 矩形区域 来描述位置的

    • 描述一个矩形区域有四个要素:x、y、width、height

  • pygame 专门提供了一个类 pygame.Rect 用于描述 矩形区域

  • pygame.Rect 是一个比较特殊的类,内部只是封装了一些数字计算,不执行pygame.init() 方法同样能够使用

示例

import pygame
# 定义一个英雄的矩形,参数:x轴,y轴,宽,高
hero_rect=pygame.Rect(100,300,120,50)
print("英雄的原点是:%d,%d"%(hero_rect.x,hero_rect.y))
print("英雄的宽高是:%d,%d"%(hero_rect.width,hero_rect.height))

创建游戏主窗口

  • pygame 专门提供了一个模块 pygame.display 用于创建和管理游戏窗口

方法说明

pygame.display.set_mode

(resolution=(0,0),flags=0,depth=0)

初始化游戏显示窗口

参数:

resolution: 指定屏幕的宽和高,默认创建的窗口大小和屏幕大小一致

flags:指定屏幕的附加选项,例如是否全屏等,默认不需要传递

depth:表示颜色的位数,默认自动匹配

pygame.display.update()刷新屏幕内容显示
  • 像绘制

    • 使用 pygame.image.load() 加载图像的数据

    • 使用 游戏屏幕 对象,调用 blit() 方法,将图像绘制到指定位置

    • 调用 pygame.update() 方法更新整个屏幕显示

示例

pygame.init()
# 创建游戏的主窗口,只指定宽和高
screen=pygame.display.set_mode((512,768))

# 加载图像
bg=pygame.image.load("./img/bg1.jpg")
# 在屏幕上绘制图像
screen.blit(bg,(0,0))
# 更新屏幕显示
pygame.display.update()

游戏中的动画原理

  • 动画的本质就是 快速 的在屏幕上绘制 图像

  • 电影是将多张 静止的电影胶片 连续、快速的播放,产生连贯的视觉效果

  • 一般在电脑上 每秒绘制60次,就能够达到非常连续、高品质的动画效果

    • 每次绘制的结果被称为 帧Frame

  • 游戏时钟

    • pygame 专门提供了一个类 pygame.time.Clock 可以非常方便的设置屏幕绘制速度(刷新频率)

    • 在游戏初始化 创建一个 时钟对象

    • 在游戏循环中,让时钟对象调用 tick(帧率) 方法

    • tick 方法会根据 上次被调用的时间,自动设置 游戏循环 中的延时

示例

# 创建游戏时钟
clock=pygame.time.Clock()

while True:
    # 设置每秒刷新60次
    clock.tick(60)

游戏的事件与监听(event)

  • 事件:就是游戏启动后,用户针对游戏所做的操作 (例如:点击关闭按钮)

    • pygame 中通过 pygame.event.get() 可以获取 用户当前所做的动作 的事件列表

    • 这段代码非常的固定,几乎所有的 pygame 游戏都大同小异

  • 监听:在游戏循环中,判断用户的 具体操作

示例

while True:
    # 设置每秒刷新60次
    clock.tick(60)

    # 监听用户点击关闭按钮
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            
            # 退出系统
            exit()

pygame 高级使用

精灵与精灵组

  • 精灵(pygame.sprite.Sprite)

    • 在游戏开发中,通过把 显示图像的对象 叫做精灵

    • 精灵有两个重要的属性

      • image:记录图像数据

      • rect:记录在屏幕上的位置

    • update(*args):更新精灵的位置

    • kill():从所有组中删除

    • Sprite 并没有提供 image 和 rect 两个属性

      • 需要程序员从 pygame.sprite.Sprite 派生子类

      • 并在子类的初始化方法中设置 image和rect属性

  • 精灵组(pygame.sprite.Group)

    • 一个精灵组可以包含多个精灵对象

    • 调用精灵组对象的 update方法 会自动调用组内每个精灵的 update方法

    • 调用精灵组的 draw(屏幕对象)方法,可以将组内每一个精灵的image 绘制在 rect 位置

    • 注:仍需要调用 pygame.display.update() 才能在屏幕上看到最终结果

示例

plane_sprites.py 模块(定义派生精灵子类)

import pygame

# 自定义派生精灵子类,继承pygame.sprite.Sprite
class GameSprites(pygame.sprite.Sprite):
    """游戏精灵基类"""

    def __init__(self,img_name,speed=1):
        # 调用父类的初始化方法
        super().__init__()

        # 加载图像
        self.image=pygame.image.load(img_name)
        # 设置尺寸; get_rect()可以获取图像的原始大小
        self.rect=self.image.get_rect()
        # 设置速度
        self.speed=speed

    def update(self):
        # 默认在屏幕上垂直方向移动
        self.rect.y+=self.speed
 

main.py

from plane_sprites import *

pygame.init()
# 创建游戏的主窗口,只指定宽和高
screen=pygame.display.set_mode((512,768))
# 加载图像
bg=pygame.image.load("./img/bg1.jpg")
# 在屏幕上绘制图像
screen.blit(bg,(0,0))

# 定义英雄飞机
hero_img=pygame.image.load("./img/hero.png")
screen.blit(hero_img,(200,500))

# 创建游戏时钟
clock=pygame.time.Clock()
hero_rect=pygame.Rect(200,500,120,79)

# 创建敌机的精灵
enemy1=GameSprites("./img/enemy1.png")
enemy2=GameSprites("./img/enemy1.png",2)
# 将精灵放入精灵组
enemy_group=pygame.sprite.Group(enemy1,enemy2)


while True:
    # 设置每秒刷新60次
    clock.tick(60)
    hero_rect.y-=1

    if hero_rect.bottom <= 0:
        hero_rect.top = 768

    screen.blit(bg,(0,0))
    screen.blit(hero_img,hero_rect)

    # 精灵组调用两个方法,更新位置和在屏幕上绘制精灵
    enemy_group.update()
    enemy_group.draw(screen)

    pygame.display.update()

    # 监听用户点击关闭按钮
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()

            # 退出系统
            exit()

定时器

  • pygame中可以使用 pygame.time.set_timer() 来添加定时器

  • 定时器:就是每隔一段时间,去执行一些动作

  • set_timer 可以创建一个事件

  • 可以在游戏循环的 事件监听中捕获到该事件

  • 定时器的监听

    • 通过 pygame.event.get() 可以获取当前时刻所有的事件列表

    • 遍历列表 并且判断 event.type 是否等于 eventid,如果相等,表示定时器事件 发生

语法

"""
第1个参数 事件代号 需要基于常量 pygame.USEREVENT 来指定,
USEREVENT 是一个整数,再增加的事件可以使用 USEREVENT+1 指定,依次类推.

第2个参数是 事件触发 间隔的毫秒值.
""" 
set_timer(eventid,milliseconds) ——>None

示例

键盘按键捕

  • 在 pygame 中针对键盘按键的捕获有 两种方式

  • 方式1:通过 event.type == pygame.KEYDOWN

  • 方式2:通过 pygame.key.get_pressed() 返回 所有按键元组,通过键盘常量,判断元组中 某一个键是否被按下 ——如果被按下,对应数值为 1(注:此种方式可以应对 长时间按住某个键)

第一种方式语法

if event.type== pygame.KEYDOWN and event.key==pygame.K_RIGHT:
  print("向右移动...")

第二种方式语法

# 返回所有按键的元组,如果某个按键按下,对应的值是1
keys_pressed=pygame.key.get_pressed()
if keys_pressed[pygame.K_RIGHT]:
  print("向右移动...")

碰撞检测

  • pygame 提供了两个非常方便的方法,可以实现碰撞检测

  • 方法一:pygame.sprite.groupcollide()

    • 检测两个精灵组中 所有的精灵 的碰撞检测

    • groupcollide(group1,group2,dokill1,dokill2,collided=None)——> Dict[Sprite, Sprite]
    • 如果将dokill 设置为 True,则发生碰撞的精灵将被自动移除

    • collided 参数用于 计算碰撞的回调函数,如果没有指定,则每个精灵必须有一个 rect 属性

  • 方法二:pygame.sprite.spritecollide()

    • 检测 某个精灵 和指定精灵组 中的精灵的碰撞

    • spritecollide(sprite,group,dokill,collided=None)——>  List[Sprite]
    • 如果将 dokill 设置为 True,则指定精灵组中发生碰撞的精灵将自动被移除

    • collided 码数用于 计算碰撞的回调函数,如果没有指定,则每个精灵必须有一个 rect 属性

    • 返回 精灵组 中跟精灵 发生碰撞的 精灵列表          

绘制字体

  • 在 pygame 中有三个步骤

    • 步骤1:使用 pygame.font.Font 方法初始化字体

    • 步骤2:使用 font.render(内容, 布尔值,是否开启抗锯齿, 字体颜色,字体背景(不填,默认是透明))

    • 步骤3:使用 屏幕对象.blit(字体对象,位置)

示例:

# 第一个参数是字体名,第二个大小
# 字体文件可以在自己的系统中查找,然后拷贝到 代码同级目录下即可。
# 字体文件路径,以下以win7为例:C:\Windows\Fonts\微软雅黑
my_font =  pygame.font.Font("msyh.ttf",58)

# 第一个参数是写的文字;
# 第二个参数是个布尔值,以为这是否开启抗锯齿,就是说True的话字体会比较平滑,不过相应的速度有一点点影响;
# 第三个参数是字体的颜色;
# 第四个参数是背景色,如果你想没有背景色(也就是透明),那么可以不加这第四个参数。
ext_surface = my_font.render("Pygame Score! ", True, (0,0,0), (255, 255, 255))

# 在屏幕上绘制字体,第一个参数是字体对象,第二个参数是x,y轴的位置
screen.blit(text_surface, (0, 0))
# 刷新屏幕
pygame.display.update()

播放音

  • 在 pygame 中用 pygame.mixer模块 来播放音乐,其中播放音乐有两种方式

  • 方式一: pygame.mixer.music.load(音频文件名)

    • 可以播放OGG、WAV、mp3 等格式音频

    • 适用音乐文件比较大,时长比较长的音乐,比如背景音乐

  • 方式二: pygame.mixer.Sound(音频文件名)

    • 可以播放OGG、WAV、mp3 等格式音频

    • 这种方式一般是用来加载一些比较短的声音,比如一些音效

示例

# 方式一 ,加载背景音乐
pygame.mixer.music.load("./music/bg.mp3")   # 加载背景音乐
pygame.mixer.music.set_volume(0.5)          # 设置音量,音量值在 0~1 区间
pygame.mixer.music.play(-1)                 # 播放音乐,参数是一个正整数,表示具体循环次数, -1 则表示无限循环

# 方式二 ,加载短音效,如 爆炸,发射子弹等
boomMusic = pygame.mixer.Sound("./music/boom.mp3") # 加载背景音乐
boomMusic.set_volume(0.3) # 设置音量,音量值在 0~1 区间
boomMusic.play()   # 播放音乐,参数是一个正整数,表示具体循环次数, 不填写,默认是一次

程序猿与投资生活实录已改名为  程序猿知秋,WX同款,欢迎关注! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值