一、模块
1. 利用 pip 安装 pygame 模块
Windows系统下的安装参考如下文章:
https://blog.csdn.net/qq_38721302/article/details/83243632
注:应在PyCharm的系统解释器的 Scripts 目录安装了 pygame 再新建工程
Linux系统下的安装:
安装pygame
sudo pip3 install pygame
验证安装(aliens是一个内置小游戏)
python3 -m pygame.examples.aliens
2. 图片素材下载
图片素材直接在下面百度云链接下载即可:
https://pan.baidu.com/s/1pMM0beb
二、pygame 模块初识
1. 游戏的初始化和退出
方法 | 含义 |
---|---|
pygame.init() | 导入并初始化所有pygame模块,使用其他模块之前,必须先调用init方法 |
pygame.quit() | 卸载所有pygame模块,在游戏结束之前调用 |
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行代码更改为下述代码也可以:
print("飞机所在位置:(%d,%d)" % (plane.x, plane.y), "飞机的大小:(%d,%d)" % plane.size)
3. 创建游戏主窗口
在pygame中提供了一个模块 pygame.display,其用于创建、管理游戏主窗口:
方法 | 含义 |
---|---|
pygame.display.set_mode() | 初始化游戏显示窗口 |
pygame.display.update | 刷新显示游戏窗口 |
游戏主窗口对象名 = 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. 英雄飞机的正确动画显示
注:由于在同一张背