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))

python

创建游戏主窗口

  • 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

示例

# 自定义事件
EVENT_ENEMY=pygame.USEREVENT


# 添加定时器,每秒执行一次自定义事件
pygame.time.set_timer(EVENT_ENEMY,1000)


# 监听事件
while True:
    for event in pygame.event.get():
        # 监听自定义事件
        if event.type == EVENT_ENEMY:
            print("自定义事件触发了...")


        # 监听退出事件
        if event.type == pygame.QUIT:
            # 卸载模块
            pygame.quit()
            # 退出系统
            exit()

键盘按键捕****获

  • 在 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()   # 播放音乐,参数是一个正整数,表示具体循环次数, 不填写,默认是一次
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分