第一章 Python 入门
第二章 Python基本概念
第三章 序列
第四章 控制语句
第五章 函数
第六章 面向对象基础
第七章 面向对象深入
第八章 异常机制
第九章 文件操作
第十章 模块
第十一章 GUI图形界面编程
第十二章 Pygame游戏开发基础
本篇博文首先对Pygame进行了介绍和安装,
然后介绍了Pygame 中的子模块以及如何开发简单的 Pygame程序
再然后对 Pygame 五个常用事件进行演示,
最后根据这些常用事件来实现坦克大战游戏
Pygame 是一组用于编写视频游戏的 Python 模块. 它具有高度的可移植性,几乎可以在所有平台和操作系统上运行.
Pygame 在优秀的 SDL 库之上添加了功能. 这使我们可以使用 python 语言创建功能齐全的游戏和多媒体程序. 官网入口
Pygame安装方式大致分为三种:
下面主要介绍前两种
Windows+R 输入 cmd, 在命令行中输入如下命令: pip install pygame
也可以通过pycharm 进入终端命令行. 然后输入相对应软件进行下载
安装时可以指定版本 pip install pygame ==版本号
但需要注意, 锁安装的模块版本要和自己当前安装的Python版本进行匹配, 否则可能会下载失败! 因此建议尽量不要指定版本.
在 Pygame 框架中有很多模块,其中最常用模块的具体 说明下表所示
模块名 | 功能说明 |
---|---|
pygame.display | 访问显示设备 |
pygame.draw | 绘制形状、线和点 |
pygame.event | 管理事件 |
pygame.font | 使用字体 |
pygame.image | 加载和存储图片 |
pygame.key | 读取键盘按键 |
pygame.mixer | 声音 |
pygame.mouse | 鼠标 |
pygame.movie | 播放视频 |
pygame.music | 播放音频 |
pygame.overlay | 访问高级视频叠加 |
pygame.rect | 管理矩形区域 |
pygame.sndarray | 操作声音数据 |
pygame.sprite | 操作移动图像 |
pygame.surface | 管理图像和屏幕 |
步骤: 初始化-> 生成主屏幕 -> 设置标题 -> 刷新屏幕
实操代码
import pygame
# 初始化
pygame.init()
# 生成主屏幕(“双缓冲”窗口)
"""
set_mode 函数:会返回一个 Surface 对象,代表了在桌面上出现的那个窗口
在 3 个参数中,第 1 个参数为元组,表示屏幕的大小;
第 2 个标志位,具体含义如表 1-2 所示,如果不用什么特性,就指定 0;
第 3 个为色深
"""
pygame.display.set_mode((600, 500), pygame.DOUBLEBUF, 32)
# 设置标题
pygame.display.set_caption("开发第一个pygame程序")
while True:
# 刷新屏幕
pygame.display.update()
注意:
set_mode 函数:会返回一个 Surface 对象,代表了在桌面上出现的那个窗口
在 3 个参数中,第 1 个参数为元组,表示屏幕的大小;
第 2 个标志位,具体含义如表 1-2 所示, 如果不用什么特性,就指定 0;
第 3 个为色深. 各标志位具体含义如下所示:
标志位 | 含义 |
---|---|
FULLSCREEN | 创建一个全屏窗口 |
DOUBLEBUF | 创建一个“双缓冲”窗口,建议和 |
HWSURFACE 和 OPENGL | 同时使用 NOFRAME 创建一个没有边框的窗口 |
RESIZEBLE | 创建一个可以改变大小的窗口 |
OPENGL | 创建一个 OPENGL 渲染的窗口 |
HWSURFACE | 创建一个硬件加速的窗口,必须和 FULLSCREEN 同时使用 |
游戏的主循环是一个无限循环,直到用户退出。在这个主循环里面做的事情就是
第 5 页 不停的刷新新画面。
效果展示
Pygame 会接受用户的各种操作(比如按键盘,移动鼠标等). 这些操作会产生对应的事件,例如按键盘事件,移动鼠标事件.
事件在软件开发中非常重要,Pygame 把一系列的事件存放在一个队列里,并逐个进行处理
事件检索
使用函数 pygame.event.get()获取所有的事件,表 1-3 列出了 Pygame 中常用的事件
事件 | 参数 | 产生途径 |
---|---|---|
QUIT | none | 用户按下关闭按钮 |
ACTIVEEVENT | gain, state | 激活或者隐藏 |
Pygame KEYDOWN | unicode, key, mod | 按下键 |
KEYUP | key, mod | 放开键 |
MOUSEMOTION | pos, rel, buttons | 鼠标移动 |
MOUSEBUTTONUP | pos, button | 放开鼠标键 |
MOUSEBUTTONDOWN | pos, button | 按下鼠标键 |
JOYBUTTONUP | joy, button | 游戏手柄放开 |
JOYBUTTONDOWN | joy, button | 游戏手柄按下 |
VIDEORESIZE | size, w, h Pygame | 窗口缩放 |
VIDEOEXPOSE | none Pygame | 窗口部分公开(expose) |
USEREVENT | code | 触发一个用户事件 |
处理鼠标事件
在 Pygame 框架中,MOUSEMOTION 事件会在鼠标动作的时候发生,它有如下所 示 3 个参数
buttons: 一个含有 3 个数字的元组,3 个值分别代表左键、中键和右键,1 就表示 按下.
pos: 位置 ;
rel: 代表现在距离上次产生鼠标事件时的距离.和MOUSEMOTION 类 似 , 常用的鼠标事件还有 MOUSEBUTTONUP 和 MOUSEBUTTONDOWN 两个
处理键盘事件
key:按下或者放开的键值,是一个数字,在 Pygame 中可以使用 K_xxx 来表示,比如字母 a 就是 K_a,还有 K_SPACE 和 K_RETURN 等
mod:包含了组合键信息,如果 mod&KMOD_CTRL 是真,表示用户同时按下了 Ctrl 键,类似的还有 KMODE_SHIFT 和 KMODE_ALT。
unicode:代表了按下键对应的 Unicode 值
实操代码
import pygame
pygame.init()
pygame.display.set_caption("处理键盘事件")
screen = pygame.display.set_mode((600, 500), 0, 32)
# 加载图片
image = pygame.image.load("img/1.gif") # 需要在当前包下面父类包下面创建文件夹
# 设置x,y作为初始位置
x, y = 0, 0
# 设置各个方向移动
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: # 退出(处理了框体右上角x)
exit()
if event.type == pygame.KEYDOWN: # 按下
if event.key == pygame.K_LEFT:
x -= 10
elif event.key == pygame.K_RIGHT:
x += 10
elif event.key == pygame.K_UP:
y -= 10
elif event.key == pygame.K_DOWN:
y += 10
screen.fill((0, 0, 0)) # 设置背景颜色
screen.blit(image, (x, y)) # 填充图像
pygame.display.update() # 刷新屏幕
效果展示
在 Pygame 模块中可以直接调用系统字体,或者可以直接使用 TTF 字体.
为了使用字体, 需要先创建一个 Font 对象:
font = pygame.font.SysFont(‘arial’,18)
COLOR_RED = pygame.Color(255, 0, 0)
textSurface = font.render(‘Hello Pygame’,True,COLOR_RED)
实操代码
import pygame
pygame.init()
# 创建窗口
screen = pygame.display.set_mode((600, 500), 0, 32)
pygame.display.set_caption("测试字体处理")
# 设置字体样式
font = pygame.font.SysFont("kaiti", 20)
# 设置字体颜色
COLOR_RED = pygame.Color(255, 0, 0)
# 设置文本内容
textSurface = font.render('你好世界', True, COLOR_RED)
# 设置文本初始坐标
x, y = 0, 0
# 设置各个方向移动
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: # 退出(处理了框体右上角x)
exit()
if event.type == pygame.KEYDOWN: # 按下
if event.key == pygame.K_LEFT:
x -= 10
elif event.key == pygame.K_RIGHT:
x += 10
elif event.key == pygame.K_UP:
y -= 10
elif event.key == pygame.K_DOWN:
y += 10
screen.fill((0, 0, 0)) # 设置背景颜色
screen.blit(textSurface, (x, y)) # 填充图像
pygame.display.update() # 刷新屏幕
Pygame 的坐标原点(0,0)点位于左上角,X 轴自左向右,Y 轴自上向下,单位为像素
绘制图形的方法下表
方法名 | 说明 |
---|---|
pygame.draw.line(Surface, color, start_pos, end_pos, width) | 绘制一条线段 |
pygame.draw.aaline(Surface, color, start_pos, end_pos, blend) | 绘制一条抗锯齿的线 |
pygame.draw.lines(Surface, color, closed, pointlist, width) | 绘制一条折线 |
pygame.draw.rect(Surface, color, Rect) | 绘制一个矩形 |
pygame.draw.rect(Surface, color, Rect, width) | 绘制一个矩形框 |
pygame.draw.ellipse(Surface, color, Rect) | 绘制一个椭圆 |
pygame.draw.ellipse(Surface, color, Rect, width) | 绘制一个多边形 |
pygame.draw.arc(Surface, color, Rect, start_angle, stop_angle, width) | 绘制一条弧线 |
pygame.draw.circle(Surface, color, Rect, radius) | 绘制一个圆 |
实操代码
from math import pi
import pygame
pygame.init()
screen = pygame.display.set_mode((400, 300))
pygame.display.set_caption(("测试图形绘制"))
# 定义颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# 背景颜色
screen.fill(WHITE)
# 绘制一条线
pygame.draw.line(screen, GREEN, [0, 0], [50, 30], 5)
# 绘制一套抗锯齿线
pygame.draw.aaline(screen, GREEN, [0, 50], [50, 80], True)
# 绘制一条折现
pygame.draw.lines(screen, BLACK, False, [[0, 80], [50, 90], [200, 80], [220, 30]], 5)
# 绘制一个空心矩形
pygame.draw.rect(screen, BLACK, [75, 10, 50, 20], 2)
# 绘制一个矩形
pygame.draw.rect(screen, BLACK, [150, 10, 50, 20])
# 绘制一个空心椭圆
pygame.draw.ellipse(screen, RED, [225, 10, 50, 20], 2)
# 绘制一个椭圆
pygame.draw.ellipse(screen, RED, [300, 10, 50, 20])
# 绘制多边形
pygame.draw.polygon(screen, BLACK, [[100, 100], [0, 200], [200, 200]], 5)
# 绘制多条弧线
pygame.draw.arc(screen, BLACK, [210, 75, 150, 125], 0, pi / 2, 2)
pygame.draw.arc(screen, GREEN, [210, 75, 150, 125], pi / 2, pi, 2)
pygame.draw.arc(screen, BLUE, [210, 75, 150, 125], pi, 3 * pi / 2, 2)
pygame.draw.arc(screen, RED, [210, 75, 150, 125], 3 * pi / 2, 2 * pi, 2)
# 绘制一个圆
pygame.draw.circle(screen, BLUE, [60, 250], 40)
# 主程序循环
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: # 退出(处理了框体右上角x)
exit()
# 绘制屏幕内容
pygame.display.update()
效果展示
由于人类眼睛的特殊生理结构,当所看画面的帧率高于 24 的时候,就会认为是连贯的, 此现象称之为视觉暂留 .
帧率(Frame rate)是用于测量显示帧数的量度,所谓的测量单位为每秒显示帧数(Frames per Second,简称:FPS).
在我们原有坐标系的基础上添加偏移量,再重新绘制,依次一张一张的循环绘制下去, 就会得到我们想要的物体移动的效果
Pygame 实现动画主要用到的方法如下表所示
方法名 | 说明 |
---|---|
pygame.image.load(filename) | 加载一张图片 |
pygame.Surface.blit(source, dest, area=None, special_flags = 0) | 将图片绘制到屏幕相应坐标上(后面两个参数默认, 可以不传) |
pygame.time.Clock() | 获得 pygame 的时钟 |
pygame.time.Clock.tick(FPS) | 设置 pygame 时钟的间隔时间 |
实操代码
import sys
import pygame
pygame.init()
# 设置帧率(屏幕每秒刷新次数)
FPS = 60
# 获得pygame的时钟
fpsClock = pygame.time.Clock()
# 设置窗口大小
screen = pygame.display.set_mode((500, 400), 0, 32)
pygame.display.set_caption("测试pygame动画")
# 定义颜色
WHITE = (255, 255, 255)
# 加载图片
img = pygame.image.load("img/1.gif")
# 初始化图片位置
imgx, imgy = 0, 0
# 初始化图片移动方向
direction = "right"
# 程序主循环
# 主程序循环
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: # 退出(处理了框体右上角x)
pygame.quit()
sys.exit()
# 每次都要重新绘制背景白色
screen.fill(WHITE)
# 判断移动的方向, 并对相应的坐标做加减
if direction == "right":
imgx += 5
if imgx == 380:
direction = "down"
elif direction == "down":
imgy += 5
if imgy == 300:
direction = "left"
elif direction == 'left':
imgx -= 5
if imgx == 10:
direction = 'up'
elif direction == 'up':
imgy -= 5
if imgy == 10:
direction = 'right'
# 该方法将用于图片绘制到相应的坐标中
screen.blit(img, (imgx, imgy))
# 刷新屏幕
pygame.display.update()
# 设置 pygame 时钟的间隔时间
fpsClock.tick(FPS)
效果展示
图片会沿着边框四周滚动
在 Pygame 里播放音频有两个方法,一个用来播放特效声音,一个用来播放背景音乐:
pygame.mixer.Sound(filename)
该方法返回一个 Sound 对象,调用它的.play( )方法,即可播放较短的音频文件(比如玩家受到伤害、收集到金币等)
pygame.mixer.music.load(filename)
该方法用来加载背景音乐,之后调用 pygame.mixer.music.play( )方法就可以播放背景音乐(Pygame 只允许在同一个时刻加载一个背景音乐)
实操代码
import sys
import pygame
pygame.init()
# 设置窗口的大小
screen = pygame.display.set_mode((500, 400))
pygame.display.set_caption("测试播放音乐")
# 定义颜色
WHITE = (255, 255, 255)
# 设置背景
screen.fill(WHITE)
# 加载并播放特效音频
sound = pygame.mixer.Sound('img/start.wav')
sound.play()
# 加载背景音乐文件
pygame.mixer.music.load('img/fire.wav')
# 播放背景音乐,第一个参数为播放的次数(-1 表示无限循环),第二个参数是设置播放 的起点(单位为秒)
pygame.mixer.music.play(-1, 0.0)
# 主程序循环
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: # 退出(处理了框体右上角x)
# 停止播放背景音乐
pygame.mixer.music.stop()
# 退出pygame
pygame.quit()
# 退出系统
sys.exit()
# 绘制屏幕内容
pygame.display.update()
《坦克大战》是由 Namco 游戏公司开发的一款平面射击游戏,于 1985 年发售.
游戏以坦克战斗及保卫基地为主题,属于策略型联机类. 同时也是 FC 平台上少有的内建关卡编辑 器的几个游戏之一
项目相关
tank25-> v1.0.0
, tank26->v1.0.1