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同款,欢迎关注!