1.游戏框架搭建
介绍pygame开发图像界面游戏的几个要素,并且把贪吃蛇游戏的整体框架搭建完成
本节知识点包括:
pygame的初始化和退出
游戏主窗口
游戏循环和游戏时钟
主窗口背景颜色
绘制文本
pygame的坐标系
游戏事件监听
绘制图形
定时器事件
1.1pygame的初始化和退出
pygame是专为开发电子游戏而设计的跨平台的Python包。而包中又针对不同的开发需求提供有不同的模块,例如:显示模块、字体模块、混音器模块等等。
注意:在这些模块中,有一部分模块是必须要初始化之后,才能够正常使用的,例如:字体模块等。
pygame为了程序员更加方便地使用包中的模块,提供有两个方法:init 和quit,其中:
init方法可以一次性初始化pygame的所有模块,这样在后续开发中,程序员可以直接使用这些模不必再单独为某一个模块调用对应的初始化方法
quit方法可以取消初始化之前已经初始化过的模块
提示:由于Python解释器在退出之前会释放所有的模块,所以quit方法不是必须要调用的
代码演练
要实现pygame的初始化和退出,需要在game.py模块中实现以下代码:
import pygame # 导入pygame
from game_items import * # 导入游戏元素模块中所有类和全局变量
if __name__ == '__main__':
# 游戏开始时要初始化pygame的模块
pygame.init()
# 游戏逻辑
# 游戏结束是要释放pygame模块占用的资源
pygame.quit()
提示:虽然quit方法的调用不是必须的,但是很多程序员在开发程序时,还是习惯按照谁申请、谁释放的原则来编写代码。因此,大家可以在很多pygame的开源代码中看到init和quit成对调用的情况
1.2游戏主窗口
贪吃蛇游戏是一款图形界面游戏, 而所谓的图形界面就是指窗口,所有游戏元素(例如:蛇、食物、得分等)都显示在这个窗口的内部。
pygame的display模块提供的一系列方法可以用于创建游戏窗口以及更新窗口显示内容等操作。
序号 | 方法 | 说明 |
1 | pygame.display.set_mode() | 初始化游戏窗口 |
2 | pygame.display.set_caption() | 设置窗口标题 |
3 | pygame.display.update() | 更新屏幕显示内容 |
1.2.1创建游戏主窗口
使用set_ mode 方法,可以非常方便地创建一个游戏主窗口
语法格式
set_mode(resolution=(0,0), flags=0, depth=0) -> Surface
其中:
参数
resolution 指定屏幕的宽和高的元组,默认创建的窗口大小和屏幕大小一致
flags 参数指定屏幕的附加选项,例如是否全屏等等,默认使用resolution 指定的窗口大小。
depth参数表示颜色的位数,默认自动匹配
●返回
Surface 对象
可以把一个Surface对象被看作是一个油画的画布,我们可以在这个画布上作画,例如:绘制贪吃蛇、绘制食物、绘制分数文字等
所有游戏元素绘制在游戏的主窗口之后,就是用户看到的游戏画面
注意:必须记录set_ mode方法的返回结果!因为后续其他的游戏元素都需要绘制在游戏主窗口上。
1.2.2设置窗口标题
使用set_ caption 方法,可以设置窗口标题
语法格式
set_caption(title, icontitle=None) -> None
其中:
参数
title 指定显示在标题栏上的窗口标题
icontitle 在某些操作系统中,可以指定显示在任务栏上的程序标题,默认与title一致
要创建游戏主窗口并设置窗口标题,在game.py中定义Game类,并且实现初始化方法
代码演练
此时的游戏主窗口是一闪而过
class Game(object):
"""游戏类"""
def __init__(self):
self.main_window = pygame.display.set_mode((640, 480))
pygame.display.set_caption("贪吃蛇")
if __name__ == '__main__':
# 游戏开始时要初始化pygame的模块
pygame.init()
# 游戏逻辑
Game()
# 游戏结束是要释放pygame模块占用的资源
pygame.quit()
1.2.3阶段性小节
pygame.display.set_mode((宽, 高)) 方法可以创建游戏主窗口
pygame.display.set_caption((标题字符串)) 可以设置窗口标题
1.3游戏循环和游戏时钟
1.3.1游戏循环
要做到游戏程序启动执行之后,不会立即退出,需要在游戏程序中增加一个游戏循环。所谓游戏循环就是一个无限循环。
可以在game.py的Game类中增加start方法
代码如下:
def start(self):
"""启动并控制游戏"""
while True:
pass
在game.py的末尾修改代码:
# 游戏逻辑
Game().start() # 创建游戏对象并且启动游戏
1.3.2游戏中的动画实现原理
在一款图形界面的游戏中,通常游戏的画面是不断变化的,也就是我们常说的动画。例如:贪吃蛇的运动、食物的出现与消失以及分数值的变化等等。
那么游戏中的动画效果是怎样实现的呢?跟电影的原理类似,游戏中的动画效果,本质上是快速地在屏幕上绘制图像
电影是将多张静止的电影胶片连续、快速地播放,产生连贯的视觉效果!
一般在电脑上每秒绘制60次,就能够达到非常连续、高品质的动画效果。每次绘制的结果被称为帧Frame
因此,刚刚完成的代码中,无限循环的执行频率(刷新帧率)只要能达到每秒60帧,就能够达到我们预期的动画效果了。但是,实际运行中,这个无限循环的执行频率有多快呢?
调整一下game.py的Game类中的start方法代码,运行观察一下循环体的执行频率
代码如下:
def start(self):
"""启动并控制游戏"""
i = 0
while True:
print(i)
i += 1
运行程序发现循环体的执行频率非常高!远远超过了我们预期的60帧秒,而且CPU的负荷也比较大。
1.3.3游戏时钟
游戏循环就是一 个无限循环,主要目的是保证游戏不会立即退出
在游戏循环中,利用时钟对象的tick方法可以设置刷新帧率,从而能够
达到连续、高品质的动画效果
减低CPU的负荷
1.4主窗口背景颜色
1.4.1 pygame的颜色定义
pygame的颜色使用的是RGB色彩模式,即通过对红(R)、绿(G)、 蓝(B)三个颜色相互之间的叠加来得到各种各样的颜色。
在pygame中,使用(R, G, B) 格式的元组来定义一个颜色。红(R)、 绿(G)、 蓝(B) 的数值是 0~ 255 之间的一个整数。数值对应颜色的亮级,数值越大亮级就越大。
常用的颜色定义如下:
元组数值 | 颜色 |
(255, 255, 255) | 白色 |
(0, 0, 0) | 黑色 |
(255, 0, 0) | 红色 |
(0, 255, 0) | 绿色 |
(0, 0, 255) | 蓝色 |
(255, 255,0) | 黄色 |
(255, 128, 0) | 橘色 |
(128, 128, 128) | 灰色 |
1.4.2定义并绘制窗口背景颜色
在game_ items.py 模块中定义一个主窗口背景颜色的全局常量,代码如下:
import pygame
# 全局变量
BACKGROUND_COLOR = (232, 232, 232) # 窗口背景色
提示:
Python中没有变量和常量的区别
所谓常量就是定义之后,只允许访问,但是不允许修改
Python中,如果要定义常量,可以使用全大写命名,单词之间使用_分隔
修改game.py的Game类中的start方法,填充窗口颜色并更新显示,代码如下:
def start(self):
"""启动并控制游戏"""
clock = pygame.time.Clock() # 游戏时钟
while True:
# 设置窗口背景颜色
self.main_window.fill(BACKGROUND_COLOR)
# 刷新窗口内容
pygame.display.update()
# 设置刷新率
clock.tick(60)
提示:填充了主窗口颜色之后,务必要使用pygame.display.update()方法更新屏幕内容
update方法的作用就是将在游戏主窗口中绘制的最终结果一次性的显示在屏幕上
1.4.3阶段性小结
颜色使用(R, G, B)格式的元组定义
常量命名使用全大写,单词之间使用下划线_分隔
self.main_window.fill(背景颜色) 使用背景颜色填充窗口
要在屏幕上看到最终绘制结果,需要调用 pygame.display.update()方法
内容总结于:https://space.bilibili.com/441640380