# 一页纸 PythonGameZero 手册

PythonGameZero 简称 pgzero, 它对 Pygame 进行了封装, 屏蔽了繁琐枯燥的框架代码, 让学习者可以更专注于游戏的实现逻辑, 并且更快看到成果
更详细的语法说明见官方手册 (opens new window)

# 基本框架

# 坐标系

以左上角为原点 ( 0, 0 ) pythonturtle坐标系

# 导入 pgzero

from pgzrun import *
#表示导入pgzero库里面的所有函数
1
2

注意: 导入 pgzero 库, 不是直接直接pgzero, 而是pgzrun!!! 其实pgzrunpython game zero run 的缩写

# 设置窗口

from pgzrun import * #导入pgzero库

TITLE = 'hello' #设置窗口顶部的标题
WIDTH = 600 #设置窗口的宽度
HEIGHT = 800 #设置窗口的高度
1
2
3
4
5

也可以不设置, 不设置的话, 窗口顶部不会显示标题, 窗口会以默认的尺寸运行

# 定义绘制函数

from pgzrun import * #导入pgzero库

WIDTH = 600 #设置窗口的宽度
HEIGHT = 800 #设置窗口的高度

def draw(): #定义绘制函数
	screen.fill((128, 0, 0)) #设置窗口的背景颜色
1
2
3
4
5
6
7

我们所看到的屏幕上的物品运动, 其实是计算机每秒绘制了多次物品, 由于眼睛的"视觉暂留"特性, 所以才产生动画的感觉.

而这里的 draw() 函数就是绘制指令, 加上屏幕更新函数update(), 就可以形成眼中的动画.

注意: 即使通过 Actor() 创建了游戏角色, 但是如果没有用 draw() 绘制出来的话, 屏幕中是看不到游戏角色的

from pgzrun import * #导入pgzero库

alien = Actor("alien.png") #调用图片, 创建角色

def draw(): #定义绘制函数
	alien.draw() #绘制角色
1
2
3
4
5
6

# 定义更新函数

update() 函数是 pgzero 的主循环, 每秒钟调用 60 次. 也就是说, 在里面写上角色xy坐标的变化, 那么每秒钟执行 60 次, 相当于每秒绘制 60 帧, 从而可以形成流畅的动画.

from pgzrun import * #导入pgzero库

alien = Actor("alien.png") #调用图片, 创建角色

def draw(): #定义绘制函数
    screen.clear() #清除屏幕内容
    alien.draw() #绘制角色

def update(): #定义更新函数
    alien.x += 1 #改变角色位置
1
2
3
4
5
6
7
8
9
10

# 运行程序

是运行 pgzero 必须要调用的函数.
只有使用了 go() 函数, 才会正式执行:

  1. 创建窗口
  2. 调用 draw() 函数
  3. 调用 update() 函数
from pgzrun import * #导入pgzero库

alien = Actor("alien.png") #调用图片, 创建角色

def draw(): #定义绘制函数
    screen.clear() #清除屏幕内容
    alien.draw() #绘制角色

def update(): #定义更新函数
    alien.x += 1 #改变角色位置

go() #运行程序: 创建窗口、调用绘制函数、调用更新函数
1
2
3
4
5
6
7
8
9
10
11
12

❗️注意:
如果程序中定义了 updte()draw() 函数, 调用 go() 函数时会交替执行 updte()draw(). 导致的结果是, 角色会被反复绘制出来.
所以在上面的代码中, 我们添加了 screen.clear() 指令来清除屏幕内容

# 角色

# 支持的图片格式

  • 支持
    • png
    • jpg
    • gif
  • 推荐使用 png 类型, 因为这种类型支持透明背景

# 创建角色

Actor('图片名', center=(坐标))

创建角色所调用的图片必须放在项目的 images 文件夹中

通过 Actor() 创建的游戏角色, 必须使用 draw() 绘制出来, 否则不会显示

如果Actor()函数中不声明坐标, 则默认将图片的左上角放在原点 ( 0, 0 ) 位置

from pgzrun import * #导入pgzero库

alien = Actor("alien.png", center=(WIDTH/2, 200)) #调用图片, 创建角色

def draw(): #定义绘制函数
	alien.draw() #绘制角色

go() #运行程序
1
2
3
4
5
6
7
8

# 设置角色初始位置

可以指定角色以下 9 个点的坐标, 以此设定角色所在位置:

alien

  • topleft ( 默认 )
  • midtop
  • topright
  • midleft
  • center
  • midright
  • bottomleft
  • midbottom
  • bottomright

比如, 指定角色的中心位置:

from pgzrun import *

alien = Actor("alien.png", center=(100, HEIGHT/2)) #创建角色

def draw():
	alien.draw() #绘制角色
1
2
3
4
5
6

如果Actor()函数中不设置角色的初始位置, 则默认将图片的左上角放在 ( 0, 0 ) 的位置

# 设置角色的锚点

也就是角色的.pos属性以及角色的.x.y的位置

建议将锚点设置为图片的下方中心位置, 也就是('center', 'bottom'), 这样, 当需要角色站在某个平面上时, 就更容易设置

如果不特别声明锚点, 那么默认的锚点就是几何中心点.

from pgzrun import *

alien = Actor("alien.png", center=(100, HEIGHT/2), anchor=('center', 'bottom')) #创建角色

def draw():
	alien.draw() #绘制角色
1
2
3
4
5
6

# 其他属性

  • 图片
    • .image: 可以用来更换角色的图片, 也就是 Scratch 里面的"造型"
  • 尺寸
    • .width
    • .height
  • 位置 alien
    • .x
    • .y
    • .left
    • .right
    • topleft
    • midtop
    • topright
    • midleft
    • .center
    • midright
    • bottomleft
    • midbottom
    • bottomright
    • .pos(x, y)
  • 角度
    • .angle
  • 显示或者隐藏
    • .show
    • 为 1 表示显示, 为 0 表示隐藏
  • 指定帧
    • .frame 如果当前角色存在多个造型, 可以通过设置frame属性指定游戏角色显示的图片

# 其他函数

  • 计算并返回当前角色与指定坐标的距离
    • .distance_to((x, y))
  • 计算并返回当前角色与指定坐标的角度
    • .angle_to((x, y))
  • 删除角色
    • .remove()
  • 绘制角色
    • .draw()

# 碰撞检测

  • 判断角色是否与指定点产生碰撞
    • .collidepoint((x, y))
  • 判断角色是否与指定角色产生碰撞
    • .collideactor(角色名)
  • 判断角色是否与指定矩形产生碰撞
    • .colliderect(角色名)
from pgzrun import *

alien = Actor("alien.png", center=(100, 100)) #调用图片, 创建角色
planet = Actor('planet', center=(300, 100))

def draw(): #定义绘制函数
	alien.draw() #绘制角色
	planet.draw() #绘制角色

def update(): #定义更新函数
	if (alien.colliderect(planet)):
		alien.show = False

def on_mouse_down(pos): #鼠标被按下时
	if alien.collidepoint(pos):
		alien.image = 'alien_move'

def on_m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 屏幕

# 清空屏幕

screen.clear()

# 填充纯色背景

如果不声明背景填充的颜色, 默认就是黑色 / black

from pgzrun import * #导入pgzero库

def draw(): #定义绘制函数
    screen.fill((128, 0, 0)) #填充屏幕背景颜色
   
go() #运行程序
1
2
3
4
5
6

# 用图片作为背景

screen.blit('图片名', (左上角的坐标))

from pgzrun import *

def draw(): #定义绘制函数
    screen.blit('picture_name', (0, 0)) #使用图片做为背景
   
go() #运行程序
1
2
3
4
5
6

# 绘制文本

screen.draw.text(字符串, 颜色, 坐标, 字体大小, 阴影)

from pgzrun import *

def draw():
    button.draw()
    screen.draw.text(
	    "Score: " + str(10), 
	    color="white", 
	    center=(WIDTH / 2, 90), 
	    fontsize=70,
	    shadow = (0.8, 0.8),
	    scolor = 'black',
	)
1
2
3
4
5
6
7
8
9
10
11
12

# 绘制直线

screen.draw.line(起点, 终点, 颜色)

from pgzrun import * #导入pgzero库

def draw(): #定义绘制函数
    screen.draw.line((100, 100), (200, 200), 'red') #绘制线段
   
go() #运行程序
1
2
3
4
5
6

# 绘制空心圆

screen.draw.circle(圆心坐标, 半径, 颜色)

from pgzrun import * #导入pgzero库

def draw(): #定义绘制函数
    screen.draw.circle((100, 100), 150, 'red')
    screen.draw.circle((250, 100), 150, (255, 0, 0)) #使用RGB数字来指定颜色
   
go() #运行程序
1
2
3
4
5
6
7

# 绘制实心圆

screen.draw.filled_circle(圆心坐标, 半径, 颜色)

from pgzrun import * #导入pgzero库

def draw(): #定义绘制函数
    screen.draw.filled_circle((100, 100), 150, 'red')
    screen.draw.filled_circle((250, 100), 150, (255, 0, 0)) #使用RGB数字来指定颜色
   
go() #运行程序
1
2
3
4
5
6
7

# 绘制空心矩形

screen.draw.rect((左上角坐标, 右下角坐标), 颜色)

from pgzrun import * #导入pgzero库

def draw(): #定义绘制函数
    screen.draw.rect(((100, 100), (200, 200)), 150, 'red')
   
go() #运行程序
1
2
3
4
5
6

# 绘制实心矩形

screen.draw.filled_rect((左上角坐标, 右下角坐标), 颜色)

from pgzrun import * #导入pgzero库

def draw(): #定义绘制函数
    screen.draw.filled_rect(((100, 100), (200, 200)), 150, 'red')
   
go() #运行程序
1
2
3
4
5
6

# 鼠标

# 鼠标按下

鼠标按下时响应

on_mouse_down(pos, button)

  • pos 表示鼠标坐标
  • button 表示鼠标按键
from pgzrun import *

def on_mouse_down(pos, button):
	print(button, ":", pos) #鼠标按下时执行的代码

go()
1
2
3
4
5
6

# 鼠标抬起

鼠标按键抬起时响应

on_mouse_up(pos, button)

  • pos 表示鼠标坐标
  • button 表示鼠标按键
from pgzrun import *

def on_mouse_up(pos, button):
	print(button, ":", pos) #鼠标按键抬起时执行的代码

go()
1
2
3
4
5
6

# 鼠标移动

鼠标移动时响应

on_mouse_move(pos, button)

  • pos 表示鼠标坐标
  • button 表示鼠标按键
from pgzrun import *

def on_mouse_move(pos, button):
	print(button, ":", pos) #鼠标移动时执行的代码

go()
1
2
3
4
5
6

# 其他属性

  • x: 鼠标的x坐标
  • y: 鼠标的y坐标
  • pos: 鼠标的坐标
  • LEFT: 鼠标左键
  • MIDDLE: 鼠标中键
  • RIGHT: 鼠标右键
  • WHEEL_UP: 鼠标滚轮上滚
  • WHEEL_DOWN: 鼠标滚轮下滚

# 键盘

# 按键按下

键盘的按键被按下时响应

on_key_down(key)

from pgzrun import *

def on_key_down(key):
    print(key)
            
go()
1
2
3
4
5
6

# 按键抬起

键盘的按键抬起时响应

from pgzrun import *

def on_key_up(key):
    if key == Keys.I: # 当按键I抬起时
        print(key) # 打印按键
go()
1
2
3
4
5
6

# 支持的按键

  • 数字

    • K_0
    • K_1
    • K_2
    • K_3
    • K_4
    • K_5
    • K_6
    • K_7
    • K_8
    • K_9
  • 字母

    • A
    • B
    • C
    • D
    • E
    • F
    • G
    • H
    • I
    • J
    • K
    • L
    • M
    • N
    • O
    • P
    • Q
    • R
    • S
    • T
    • U
    • V
    • W
    • X
    • Y
    • Z
  • 控制键

    • SHIFT
    • CTRL
    • ALT
    • LEFT
    • UP
    • RIGHT
    • DOWN
    • PAGEUP
    • PAGEDOWN
    • END
    • HOME
    • ESCAPE
    • ENTER
    • SPACE
    • RETURN
    • BACKSPACE
    • INSERT
    • DELETE
  • 功能键

    • F1
    • F2
    • F3
    • F4
    • F5
    • F6
    • F7
    • F8
    • F9
    • F10
    • F11
    • F12
    • F13
    • F14
    • F15
  • 在键盘事件函数中, 可使用 key == keys.RIGHT 判断 right 键是否被按下

  • 在键盘事件函数以外, 比如在 update() 函数中, 可以通过 keyboard[keys.RIGHT] 来判断 right 是否被按下

from pgzrun import *

def on_key_up(key):
    if key == Keys.RIGHT: # 当右方向键抬起时
        print('右方向键') # 打印按键

def update():
	if keyboard[keys.RIGHT]:
		print('右方向键')
go()
1
2
3
4
5
6
7
8
9
10

# 音乐

# 支持的音频格式

  • wav
  • ogg
  • mp3 ( 在一些 Linux 系统上可能有问题 )

# 音量属性

music.volume

from pgzrun import *

music.volume = 0.5   # 设置当前音量
print(music.volume)  # 获取当前音量
1
2
3
4

# 设置音量

music.set_volume(数字)

  • 音量的范围是 0 - 1
from pgzrun import *

music.set_volume(0.5)
1
2
3

# 获取当前音量

music.get_volume()

from pgzrun import *

print(music.get_volume())
1
2
3

# 循环播放

music.play(音乐文件路径)

from pgzrun import *

path = '' # 音乐文件的路径
music.play(path)
1
2
3
4

# 播放一次后停止

music.play_once(音乐文件路径)

from pgzrun import *

path = '' # 音乐文件的路径
music.play_once(path)
1
2
3
4

# 之前播放完之后再播放

在当前正在播放的音乐结束之后, 再播放. 或者在之前代码中设定的音乐播放完之后, 再播放

music.queue(音乐文件路径)

from pgzrun import *

path = '' # 音乐文件的路径
music.play_once(path)
1
2
3
4

# 检查是否在播放

music.is_playing()

from pgzrun import *

path = '' # 音乐文件的路径
music.play(path)

if music.is_playing():
	print('正在播放音乐')
1
2
3
4
5
6
7

# 停止播放

music.stop()

from pgzrun import *

path = '' # 音乐文件的路径
music.play(path)

if music.is_playing(): # 检查是否在播放
	music.stop() # 停止播放
1
2
3
4
5
6
7

# 音效

# 支持的音频格式

  • wav
  • ogg
  • mp3 ( 在一些 Linux 系统上可能有问题 )

# 播放一次

sounds.xxx.paly()

  • xxx是音效文件名称
from pgzrun import *

sounds.xxx.play() 
1
2
3

# 停止播放

sounds.xxx.stop()

from pgzrun import *

sounds.xxx.play() #播放音效
sounds.xxx.stop() #停止播放音效
1
2
3
4

# 获取时长

sounds.xxx.get_length()

from pgzrun import *

sounds.xxx.play()
print(sounds.xxx.get_length())
1
2
3
4

# 时间

# 一段时间后再调用

clock.schedule(调用的函数, 几秒之后)

from pgzrun import *

path = '' # 音乐文件的路径
clock.schedule(music.play_once(path), 10) # 10秒之后播放音乐
1
2
3
4

# 每隔一段时间调用一次

clock.schedule_interval(调用的函数, 间隔的秒数)

from pgzrun import *

time = 0

def update_time():
	global time
	time = time + 1
	
clock.schedule_interval(update_time, 1.0)
1
2
3
4
5
6
7
8
9

# 动画

# 创建动画

animate(actor, tween, duration, on_finished, targets)

  • actor 游戏角色
  • tween 动画类型 ( 类似 AfterEffect 的"速度曲线" )
    • linear 线性
    • accelerate 加速
    • decelerate 减速
    • accel_decel 先加速再加速
    • elastic_start 开始时反弹
    • elastic_end 结束时反弹
    • elastic_start_end 开始结束都反弹
    • bounce_start 开始时弹跳
    • bounce_end 结束时弹跳
    • bounce_start_end 开始和结束都弹跳
  • duration 动画持续时间, 单位为"秒", 默认是 1 秒
  • on_finished 动画结束后的回调函数
  • targets 可以为 (pos) 、 (x) 、 (y)

# 播放动画

running()

# 停止动画

stop()