使用 pygame 制作游戏并发布到个人网站

本文简要介绍如何使用 pygame 制作一个简易测试游戏,并使用 pygbag 将游戏打包上传至个人网站,使游戏可在浏览器中直接游玩。

查看本文创建的测试游戏,初次打开网页请耐心等待加载。 点击屏幕中间显示 Ready to start! 的绿色横条开始游戏。 使用 WASD上下左右 方向键控制红色小球移动。

构建 Python 虚拟环境

详情请参考使用 pyenv 管理 Python 的版本和虚拟环境

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 新建文件夹,游戏编写会在此目录下进行
$ mkdir PyGame
$ cd PyGame

# 为编写游戏构建 Python 虚拟环境
$ pyenv virtualenv 3.11.5 PyGame

# 在项目目录下设置自动激活 Python 虚拟环境
$ pyenv local PyGame

# 查看虚拟环境及 Python 版本
(PyGame) $ pyenv versions
  system
  3.11.5
  3.11.5/envs/PyGame
* PyGame --> /Users/user/.pyenv/versions/3.11.5/envs/PyGame (set by /Users/user/PyGames/.python-version)

安装 Pygame

Pygame 是专为编写游戏而设计的一套 Python 模组,基于 SDL 库添加了各种游戏功能的实现,可利用 Python 语言的灵活性快速、轻松创建各种游戏。

  • Pygame 具有极高的可移植性,几乎可以在任何平台和操作系统上运行。
  • 轻松调用和发挥多核 CPU 的性能。
  • 核心功能基于优化的 C 和汇编代码,运行速度更快。
  • 核心代码十分简洁,各种核心功能模组均可按需调用。
  • 无需依赖 GUI 即可调用所有功能函数。
  • 完全控制所有 pygame 函数的调用,方便引入各种第三方库。

在 macOS 中可 使用 Python 包管理工具 pip 安装 Pygame

1
2
3
4
5
# 使用 pip 安装 pygame
$ pip install pygame

# 运行内置游戏示例
$ python -m pygame.examples.aliens

测试游戏

参考 pygame 官方文档给出最简单的测试游戏示例:

1
2
3
4
5
6
# 新建测试文档 TestGame
$ mkdir TestGame
$ cd TestGame

# 新建游戏文件,命名为 main.py
vim main.py

输入游戏代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# 游戏描述:玩家可控制一个红色的圆,使其在屏幕上四处移动

# 导入 pygame 模组
import pygame

# 初始化 pygame
pygame.init()
# 设置窗口屏幕尺寸为 1280x720 像素
screen = pygame.display.set_mode((1280, 720))
# 设置游戏时钟,用于控制游戏帧数
clock = pygame.time.Clock()
# running 参数用于控制游戏的运行和结束
running = True # True:游戏运行;False:游戏结束
# dt 记录上一帧结束后经历的时间,单位为秒
# dt 用于描述游戏中实际的物理过程,与游戏帧数无关
dt = 0

# 将玩家(一个红色圆圈)的初始位置定为屏幕中间
player_pos = pygame.Vector2(screen.get_width() / 2, screen.get_height() / 2)

# 开始游戏循环,running 为 True 时游戏持续运行
while running:

	# 获取游戏事件列表
	for event in pygame.event.get():
		# 当用户点击窗口左上 x 关闭游戏窗口时触发 pygame.QUIT 类型事件
		if event.type == pygame.QUIT:
			# 此时将 running 值设为 False,下次循环时游戏结束
			running = False

	# 使用背景色(黑色)填充整个游戏窗口,覆盖上一帧绘制的所有游戏内容
	screen.fill("black")

	# 获取玩家按下的按键
	keys = pygame.key.get_pressed()
	# 根据按键上下左右更新玩家位置
	if keys[pygame.K_w] or keys[pygame.K_UP]:
		player_pos.y -= 300 * dt
	if keys[pygame.K_s] or keys[pygame.K_DOWN]:
		player_pos.y += 300 * dt
	if keys[pygame.K_a] or keys[pygame.K_LEFT]:
		player_pos.x -= 300 * dt
	if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
		player_pos.x += 300 * dt

	# 在当前位置绘制代表玩家的红色圆圈
	pygame.draw.circle(screen, "red", player_pos, 30)

	# 将游戏界面输出至窗口屏幕
	pygame.display.flip()

	# 将游戏帧数(FPS)设置为 60,并获取 dt 值
	dt = clock.tick(60) / 1000

# 若 running 值为 False,则游戏结束
pygame.quit()

运行游戏:

1
2
# 直接使用 python 运行代码即可
$ python main.py

此时弹出一个游戏窗口,玩家可使用 WASD上下左右 键,控制红色小球的移动。

使用 Pygbag 打包游戏

使用 pygbag 将 pygame 制作的游戏打包,使游戏可在浏览器中直接运行。 pygbag 的使用可参考 Pygbag Wiki

基于 Python 包管理工具 pip,pygbag 的安装同样非常简易:

1
2
# 使用 pip 安装 pygbag
pip install pygbag

使用 pygbag 打包游戏前,待打包的目录下的游戏代码文件须名为 main.py。 然后仅需对游戏代码做简易修改:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 导入 asyncio 模组(Python 默认安装)
import asyncio
import pygame

# 将所有全局变量的定义统一放置在主函数 main() 之前
pygame.init()
screen = pygame.display.set_mode((1280, 720))
clock = pygame.time.Clock()
running = True # True:游戏运行;False:游戏结束
dt = 0

player_pos = pygame.Vector2(screen.get_width() / 2, screen.get_height() / 2)

# 将游戏主循环放置在 main() 函数中,并使用 async 进行定义
async def main():
	# 声明要使用的全局变量
	global screen, clock, running, dt

	# 其余游戏代码无需改动
	while running:
	
		for event in pygame.event.get():
			if event.type == pygame.QUIT:
				running = False
	
		screen.fill("black")
	
		keys = pygame.key.get_pressed()
		if keys[pygame.K_w] or keys[pygame.K_UP]:
			player_pos.y -= 300 * dt
		if keys[pygame.K_s] or keys[pygame.K_DOWN]:
			player_pos.y += 300 * dt
		if keys[pygame.K_a] or keys[pygame.K_LEFT]:
			player_pos.x -= 300 * dt
		if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
			player_pos.x += 300 * dt
	
		pygame.draw.circle(screen, "red", player_pos, 30)
	
		pygame.display.flip()
	
		dt = clock.tick(60) / 1000

		# 当刷新游戏界面后,刷新网页页面
		await asyncio.sleep(0)

	pygame.quit()

# 添加程序入口,运行 main()
if __name__ == '__main__':
	# 使用 asyncio.run() 调用主函数 main()
	asyncio.run(main())

# 此后添加的任何代码都将被忽略

使用 pygbag 将修改后的游戏代码打包:

1
2
3
4
5
# 返回 TestGame 的父级文件夹
$ cd ..

# 使用 pygbag 打包 TestGame 文件夹
pygbag TestGame

Pygbag 会同时在本地部署一个测试服务器,用于在浏览器中查看、测试游戏的运行情况。

根据屏幕提示,pygbag 在 127.0.0.18000 端口部署了一个用于测试的本地服务器,可在浏览器中输入 http://localhost:8000/ 查看游戏的运行情况。

pygbag 同时还提供了一个附带终端界面的网页用于调试程序,可在浏览器中输入 http://localhost:8000#debug 查看。

将游戏部署至网站

Pygbag 打包构建好的游戏页面代码存放在 /WebTest/build/web/ 目录下。将该文件夹下的所有内容上传至网站服务器相应目录即可。

如本网页给出的游戏示例存放在网页根目录下的 /games/webtest/ 目录下。在网页主域名后加入上述目录地址 https://www.newverse.wiki/games/webtest,可直接运行游戏。

0%