一、模块
1. 利用 pip 安装 pygame 模块
Windows系统下的安装参考如下文章:
https://blog.youkuaiyun.com/qq_38721302/article/details/83243632
注:应在PyCharm的系统解释器的 Scripts 目录安装了 pygame 再新建工程
Linux系统下的安装:
安装pygame
sudo pip3 install pygame
验证安装(aliens是一个内置小游戏)
方法 |
含义 |
---|---|
pygame.init() |
导入并初始化所有pygame模块,使用其他模块之前,必须先调用init方法 |
pygame.quit() |
卸载所有pygame模块,在游戏结束之前调用 |
python3 -m pygame.examples.aliens
2. 图片素材下载
图片素材直接在下面百度云链接下载即可:
https://pan.baidu.com/s/1pMM0beb
二、pygame 模块初识
1. 游戏的初始化和退出
2. pygame 中的游戏坐标系
原点在左上角 O(0,0)
x轴水平方向向右,逐渐增加
y轴竖直方向向下,逐渐增加
在游戏中,所有可见的元素都是以上述矩形区域来描述位置的
在 游戏窗口(坐标系)中,要描述一个矩形区域应该有四要素:(x,y) 和 (width,height),其中 (x,y) 描述的是矩形区域左上角(原点)所在的坐标,而 (width,height) 则控制矩形区域的大小
在pygame中提供了一个类 pygame.Rect,其用于描述矩形区域:
矩形区域对象名 = pygame.Rect(x, y, width, height)
创建一个矩形区域的对象
其中:x, y, width, height 均属于对象属性,可以通过对象名来访问
另有一个 size 的元组属性:它是一个元组——(width, height),可以直接访问到 width 和 height,可以作为参数值来传递到 pygame.display.set_mode(…) 中,之后会讲到
例:在坐标系原点创建一个width=100,height=140的 plane 对象
import pygame
pygame.init()
plane = pygame.Rect(0, 0, 100, 140)
print("飞机所在位置:(%d,%d),飞机的大小:(%d,%d)" % (plane.x, plane.y, plane.width, plane.height))
pygame.quit()
第6行代码更改为下述代码也可以:
方法 |
含义 |
---|---|
pygame.display.set_mode() |
初始化游戏显示窗口 |
pygame.display.update |
刷新显示游戏窗口 |
print("飞机所在位置:(%d,%d)" % (plane.x, plane.y), "飞机的大小:(%d,%d)" % plane.size)
3. 创建游戏主窗口
在pygame中提供了一个模块 pygame.display,其用于创建、管理游戏主窗口:
游戏主窗口对象名 = pygame.display.set_mode(resulution=(0, 0), flags=0, depth=0)
创建一个游戏显示窗口的对象
其中:resoluthon, flags, depth均属于对象属性
resolution 是一个元组,需要传递一个元组,它指定屏幕的宽和高,缺省时默认值为整个屏幕的大小,这个元组可以是 pygame.Rect(…) 函数返回的矩形区域对象的 size 属性 ——它是个元组
flags 指定屏幕的附加选项,例如是否全屏等,默认不需要传递
depth 表示颜色的位数,默认自动匹配
返回值 游戏的主窗口,游戏的元素都需要被绘制到游戏的主窗口上
例:创建一个 (480,700) 的游戏主窗口
import pygame
import time
"""窗口大小:(480,700)"""
window = pygame.display.set_mode((480, 700))
"""系统休眠5秒"""
time.sleep(5)
pygame.quit()
4. 游戏主窗口上图像的绘制
在游戏中,能够看到的游戏元素大多数是图像,图像文件初始是保存在磁盘上的,如果需要使用,第一步就需要把图像加载到内存中,一般要在屏幕上看到某一个图像的内容,需要安装下述三个步骤来进行:
使用 pygame.image.load() 加载图像的数据
使用 游戏主窗口 对象来调用 blit 方法将图像绘制到指定的位置
使用 pygame.display.update() 方法更新整个屏幕的显示
图片对象名 = pygame.image.load(图片所在路径)
把图像打开并把数据加载到内存中,其中路径可以是图片相对源代码所在 .py文件 的 相对路径 或 绝对路径,返回图片对象
游戏主窗口对象名.blit(图片对象名, 矩形区域对象或(x, y)坐标)
在游戏主窗口中绘制图像
矩形区域对象 图片对象在游戏主窗口中矩形区域原点对应的位置,一般所设置的这个矩形区域与图片的大小一致,以此来让图片对应这片矩形区域——图片负责动画的实现,矩形区域负责游戏的逻辑控制
(x, y) 坐标元组,即图片对象在游戏主窗口的位置
pygame.display.update()
刷新显示游戏主窗口
提示:要想在屏幕上看到绘制的结果,就一定要调用 pygame.display.update() 方法
例:我们尝试将飞机大战的背景图像 background.png 文件加载到游戏主窗口上
import pygame
import time
pygame.init()
"""创建游戏主窗口"""
window = pygame.display.set_mode((480, 700))
"""加载图片到内存"""
background = pygame.image.load("./游戏素材/background.png")
"""在游戏主窗口中显示图片"""
window.blit(background, (0, 0))
"""刷新显示"""
pygame.display.update()
"""系统休眠5秒"""
time.sleep(5)
pygame.quit()
提示:我们可以通过 blit() 方法将游戏主窗口的所有的图像布置完成后,再使用 pygame.display.update() 刷新游戏主窗口即可
5. 阶段小结(一):英雄飞机显示
需求:把英雄飞机 me1.png 或 me2.png 文件显示在游戏主窗口的背景上
import pygame
import time
pygame.init()
"""创建游戏主窗口"""
window = pygame.display.set_mode((480, 700))
"""加载需要的图片"""
background = pygame.image.load("./游戏素材/background.png")
me1 = pygame.image.load("./游戏素材/me1.png")
"""绘制背景和飞机"""
window.blit(background, (0, 0))
window.blit(me1, (189, 574))
"""刷新显示"""
pygame.display.update()
time.sleep(5)
pygame.quit()
我们使用 PyCharm 或 PS 打开图片,发现英雄飞机图片的背景是一系列灰白相间的小格子,这些灰白相间的小格子代表英雄飞机是透明背景:
6. 扩展
本文只针对 pygame 模块中一些简单的功能进行介绍,实际上 pygame 还拥有很多强大的功能,若有兴趣学习的可以参考下述文章:
pygame官网:https://www.pygame.org/news
pygame官网文档:https://www.pygame.org/docs/
三、游戏主功能
1. 动画实现原理——帧 Frame
我们知道,视频是一帧一帧地播放的,其实质是由一帧一帧变化的图像的动态刷新显示来呈现运动的效果,其利用了肉眼的视觉暂留原理,因此我们可以利用计算机对多张图片的快速刷新显示,即可达到动画的效果
一般在电脑上每秒绘制60次,就能够达到非常连续高品质的动画效果,每次绘制的结果被称为 帧 Frame
每秒播放图像的次数被称为 每秒传输帧数 FPS(Frames Per Second)),这就是游戏中的 fps
2. 游戏循环
通常,游戏循环意味着游戏的正式开始
游戏循环的作用:
保证游戏不会直接退出
变化图像位置——达到动画效果
每隔1/60秒移动一下所有图像的位置
调用 pygame.display.update() 刷新显示
检测用户的交互——键盘、鼠标等外设
3. 游戏时钟
在Python中,while True: 循环的速度可达每秒钟数十万次,而我们对图像帧率的要求不需要这么高,pygame 中有一个时钟类 pygame.time.Clock 可以非常方便地设置游戏主窗口的绘制速度——刷新帧率
时钟对象名 = pygame.time.Clock()
创建一个时钟对象
时钟对象名.tick(帧)
可以设置时钟的帧率,相当于在调用 tick() 方法的位置处暂停 1/帧 秒的时间,以此来实现固定帧率的刷新
例:
import pygame
pygame.init()
clock = pygame.time.Clock()
i = 0
while True:
clock.tick(1)
print(i)
i += 1
pygame.quit()
这里的0、1、2、3、4是每秒钟增加一个的
4. 英雄飞机的简单动画显示
注:由于 blit() 方法可以传递 坐标元组 或者 矩形区域对象,因此在创建了一个矩形区域对象后,我们就可以直接用矩形区域对象来作为动画播放时图片的位置,让图片位置与矩形区域位置一一对应
例:利用 Rect 的矩形区域在y轴上的移动来实现飞机的移动
import pygame
pygame.init()
"""创建游戏主窗口"""
window = pygame.display.set_mode((480, 700))
"""加载需要的图片"""
background = pygame.image.load("./游戏素材/background.png")
me1 = pygame.image.load("./游戏素材/me1.png")
"""创建一个矩形区域对象,设置初始位置"""
hero_plane = pygame.Rect(189, 574, 102, 126)
"""设定一个时钟"""
clock = pygame.time.Clock()
"""绘制背景"""
window.blit(background, (0, 0))
while True:
window.blit(me1, hero_plane)
"""刷新显示"""
pygame.display.update()
hero_plane.y -= 50
clock.tick(1)
pygame.quit()
5. 英雄飞机的正确动画显示
注:由于在同一张背景下绘制的图片不会消失,因此如果想要在一张背景下实现英雄飞机的动画式的变化,可以在游戏主窗口中再绘制一张背景,把原来的图像覆盖掉,再绘制英雄飞机图片,这样就可以实现英雄飞机的动画式变化
以上述代码为基础,只需把window.blit(background, (0, 0))
放在while True:
中即可实现
while True:
"""绘制背景"""
window.blit(background, (0, 0))
window.blit(me1, hero_plane)
"""刷新显示"""
pygame.display.update()
hero_plane.y -= 50
clock.tick(1)
注:这里飞机会飞出屏幕,而我们只需给矩形区域的位置做简单的判断即可实现飞机周而复始的运动;另外,我们调整一下帧率和飞机的移动距离,实现动画的连贯播放
if hero_plane.y + hero_plane.height <= 0:
hero_plane.y = 700
else:
hero_plane.y -= 1
clock.tick(240)
6. 英雄飞机的动作动画显示
利用两张或多张不同的图片在同一位置的显示,来完成英雄飞机的动作——喷气
例:利用 me1.png 和 me2.png 的不同来刷新显示英雄飞机的变化
注:由于在同一个背景下绘制的图像不会消失,因此要想在背景下显示不同的影响,则需要绘制新的背景覆盖原背景
import pygame
pygame.init()
"""创建游戏主窗口"""
window = pygame.display.set_mode((480, 700))
"""加载需要的图片"""
background = pygame.image.load("./游戏素材/background.png")
me1 = pygame.image.load("./游戏素材/me1.png")
me2 = pygame.image.load("./游戏素材/me2.png")
"""设定一个时钟"""
clock = pygame.time.Clock()
while True:
"""绘制背景和飞机"""
window.blit(background, (0, 0))
window.blit(me2, (189, 574))
"""刷新显示"""
pygame.display.update