[ English | 中文 | Deutsch | Español | Français | Italiano | 日本語 | 한국어 | Português | Русский ]
Pyxel是一个 python 的经典像素风游戏制作引擎。
由于像素风游戏的机制非常简单 (如:最多只能显示 16 种颜色、播放 4 种声音等),现在你也可以轻松地享受这种游戏的制作过程。
Pyxel 开发的动力来自于用户的反馈。请在 GitHub 上给 Pyxel 一颗星吧!
Pyxel 的规范和 API 受到PICO-8和TIC-80的启发。
Pyxel 是开源的,大家可以免费使用。现在就让我们一起用 Pyxel 制作自己的游戏吧!
- 可在 Windows、Mac、Linux 和 Web 上运行
- 可以使用 python 进行编程
- 16 色调色板
- 3 个 256x256 的图像库
- 8 个 256x256 的瓦片地图
- 4 个音轨,每个各可含有 64 个音符
- 可任意组合 8 个音乐
- 支持键盘、鼠标及游戏手柄输入
- 图像和音频编辑器
在安装Python3 (3.7 或更高版本) 之后,执行以下命令:
pip install -U pyxel
如果你使用官方安装程序安装 Python,请勾选Add Python 3.x to PATH
复选框以启用pyxel
命令。
在安装Python3 (3.7 或更高版本) 之后,执行以下命令:
python3 -m pip install -U pyxel
如果你使用默认安装在 Mac 上的 Python3,请在上述命令的开头添加sudo
以启用pyxel
命令。
安装 SDL2 (Ubuntu 下包名为:libsdl2-dev
),Python3 (3.7 或更高版本),以及python3-pip
这三个包之后,执行以下命令:
sudo pip3 install -U pyxel
如果上述方法不奏效,请根据Makefile中的说明尝试自我构建。
网络版 Pyxel 不需要安装 Python 或 Pyxel,可以在 PC 以及支持网络浏览器的智能手机和平板电脑上运行。
具体说明请参考本页面。
以 Python 包版本为例,安装 Pyxel 后,用以下命令将 Pyxe 例程复制到当前文件夹:
pyxel copy_examples
例程包含:
01_hello_pyxel.py | 最简单的应用 | Demo | Code |
02_jump_game.py | 用 Pyxel 制作的跳跃游戏 | Demo | Code |
03_draw_api.py | 绘画 API 的使用示例 | Demo | Code |
04_sound_api.py | 声音 API 的使用示例 | Demo | Code |
05_color_palette.py | 调色板列表 | Demo | Code |
06_click_game.py | 鼠标点击游戏 | Demo | Code |
07_snake.py | 带 BGM 的贪吃蛇游戏 | Demo | Code |
08_triangle_api.py | 三角形绘画 API 的使用示例 | Demo | Code |
09_shooter.py | 屏幕过渡射击游戏 | Demo | Code |
10_platformer.py | 屏幕横向滑动的游戏示例 | Demo | Code |
11_offscreen.py | 用 Image 类进行屏外渲染 | Demo | Code |
12_perlin_noise.py | 佩林噪音动画 | Demo | Code |
13_bitmap_font.py | 绘制一个位图字体 | Demo | Code |
14_synthesizer.py | 利用音频扩展功能的合成器 | Demo | Code |
99_flip_animation.py | 具有 flip 功能的动画 (仅在非网络平台上) | Demo | Code |
30SecondsOfDaylight.pyxapp | 第 1 届 Pyxel Jam 比赛获胜者是Adam | Demo | Code |
megaball.pyxapp | 商场球类物理游戏Adam | Demo | Code |
8bit-bgm-gen.pyxapp | 背景音乐生成器由frenchbread制作 | Demo | Code |
运行例程,可以使用以下命令:
cd pyxel_examples
pyxel run 01_hello_pyxel.py
pyxel play 30SecondsOfDaylight.pyxapp
在 python 文件中导入 Pyxel 包后,首先使用init
函数指定窗口大小,然后使用run
函数启动 Pyxel 应用。
import pyxel
pyxel.init(160, 120)
def update():
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw():
pyxel.cls(0)
pyxel.rect(10, 10, 20, 20, 11)
pyxel.run(update, draw)
run
函数的两个参数update
函数和draw
函数分别用来在需要时更新帧和绘制画面。
实际应用中,建议将 pyxel 代码封装成如下类:
import pyxel
class App:
def __init__(self):
pyxel.init(160, 120)
self.x = 0
pyxel.run(self.update, self.draw)
def update(self):
self.x = (self.x + 1) % pyxel.width
def draw(self):
pyxel.cls(0)
pyxel.rect(self.x, 0, 8, 8, 9)
App()
当创建没有动画的简单图形时,可以使用show
函数来使代码更加简洁。
import pyxel
pyxel.init(120, 120)
pyxel.cls(1)
pyxel.circb(60, 60, 40, 7)
pyxel.show()
创建的 Python 脚本可以使用以下命令执行:
pyxel run PYTHON_SCRIPT_FILE
它也可以像普通的 Python 脚本一样被执行:
python3 PYTHON_SCRIPT_FILE
以下快捷键可以在 Pyxel 运行时使用:
Esc
退出应用Alt(Option)+1
截屏并保存在桌面Alt(Option)+2
重置屏幕录制的开始时间Alt(Option)+3
保存屏幕录制动图到桌面 (最多 10 秒)Alt(Option)+9
切换屏幕模式 (Crisp/Smooth/Retro)Alt(Option)+0
切换性能监控 (fps,更新时间,画面绘制时间)Alt(Option)+Enter
切换全屏Shift+Alt(Option)+1/2/3
将相应的图像库保存到桌面
在 Pyxel 应用中使用的图像和音效,可以使用 Pyxel 编辑器进行制作。
Pyxel 编辑器使用以下命令启动:
pyxel edit PYXEL_RESOURCE_FILE
若指定 Pyxel 源文件 (.pyxres) 存在,则加载文件,若不存在,则以指定文件名新建文件。
若未指定源文件,则命名为my_resource.pyxres
。
Pyxel 编辑器启动后,可以拖放其他源文件进行切换。如果源文件被拖拽并在按下Ctrl(Cmd)
键时释放,则只有当前正在编译的类型 (图像、瓦片地图、音效、音乐) 会被加载。这个操作允许将多种类型的源文件合并入一个源文件中。
创建的源文件可以使用load
函数加载。
Pyxel 编辑器有以下编辑模式。
图像编辑器
此模式用来编辑图像库。
通过将图像文件拖放进图像编辑器,图像可以加载进当前的图像库中。
瓦片地图编辑器
此模式用来编辑瓦片地图,其中图像库的图像以瓦片的样式排列。
音频编辑器
此模式用来编辑音频。
音乐编辑器
此模式用来编辑将录音有序编排形成的音乐。
Pyxel 图像和瓦片地图也可以通过以下方法创建:
- 使用
Image.set
或Tilemap.set
函数,从字符串列表创建图片 - 使用
Image.load
函数从加载图像文件至 pyxel 调色板中
Pyxel 声音也可以通过以下方法创建:
- 使用
Sound.set
或Music.set
函数,从字符串列表中创建声音
这些函数的具体用法请查阅 API 参考手册。
Pyxel 支持跨平台的应用文件格式 (Pyxel 应用文件)。
使用以下命令创建 Pyxel 应用文件 (.pyxapp):
pyxel package APP_DIR STARTUP_SCRIPT_FILE
如果应用程序应包括资源或其他模块,请将它们放在应用程序目录中。
创建好的应用文件使用以下命令执行:
pyxel play PYXEL_APP_FILE
Pyxel 应用程序文件也可以通过pyxel app2exe
或pyxel app2html
命令转换为可执行文件或 HTML 文件。
-
width
,height
画面的宽和高 -
frame_count
目前为止,经过的总帧数 -
init(width, height, [title], [fps], [quit_key], [display_scale], [capture_scale], [capture_sec])
使用屏幕尺寸 (width
,height
) 初始化 Pyxel 应用。以下属性为可选配置项:窗口标题title
,帧率fps
,应用退出按键quit_key
,用 "display_scale "来决定显示的比例,用 "capture_scale "来决定屏幕捕捉的比例,以及屏幕捕获的最长记录时间capture_sec
。
示例:pyxel.init(160, 120, title="My Pyxel App", fps=60, quit_key=pyxel.KEY_NONE, capture_scale=3, capture_sec=0)
-
run(update, draw)
启动 Pyxel 应用,并调用update
函数刷新画面帧,并使用draw
函数渲染画面。 -
show()
显示屏幕直到Esc
键被按下。 -
flip()
将屏幕重新调整一帧。当按下Esc
键时,应用程序退出。该功能在网络版中不起作用。 -
quit()
退出 Pyxel 应用。
load(filename, [excl_images], [excl_tilemaps], [excl_sounds], [excl_musics])
加载源文件 (.pyxres)。如果选项为True
,则不会加载资源。如果在资源文件的同一位置存在同名的调色板文件 (.pyxpal),调色板的显示颜色也将改变。调色板文件是显示颜色的十六进制条目 (如1100FF
),以换行分隔。调色板文件也可用于更改 Pyxel 编辑器中显示的颜色。
-
mouse_x
,mouse_y
当前鼠标指针的位置。 -
mouse_wheel
当前鼠标滚轮的值。 -
btn(key)
如果key
被按下则返回True
,否则返回False
。(按键定义列表)。 -
btnp(key, [hold], [repeat])
如果key
被按下则返回True
。若设置了hold
和repeat
参数,则当key
被按下持续hold
帧时,在repeat
帧间隙返回True
。 -
btnr(key)
如果key
被松开,则在此帧返回True
,否则返回False
。 -
mouse(visible)
如果visible
为True
则显示鼠标指针,为False
则不显示。即使鼠标指针不显示,其位置同样会被更新。
-
colors
展示调色板可以显示的颜色列表。颜色以 24 位数值格式进行展示。使用colors.from_list
和colors.to_list
直接指定货检索 Python 列表。
示例:old_colors = pyxel.colors.to_list(); pyxel.colors.from_list([0x111111, 0x222222, 0x333333]); pyxel.colors[15] = 0x112233
-
images
图像库列表 (0-2)。 (参考前文 Image 类)
示例:pyxel.images[0].load(0, 0, "title.png")
-
tilemaps
瓦片贴图列表 (0-7)。 (参考前文 Tilemap 类) -
clip(x, y, w, h)
设置画面绘制区域为从 (x
,y
) 开始的宽度w
、高度为h
的区域。clip()
可以将绘制区域重置为全屏。 -
camera(x, y)
更改视角等起始位置,使位置 (x
,y
) 成为屏幕左上角的起始位置,这将有助于切换视角。若想恢复起始位置,使用camera()
或camera(0, 0)
即可完成重置。 -
pal(col1, col2)
绘制时用col1
颜色代替col2
颜色。pal()
可以重置为初始色调。 -
dither(alpha)
在绘制时应用抖动 (伪透明)。在 0.0-1.0 的范围内设置alpha
,其中 0.0 表示透明,1.0 表示不透明。 -
cls(col)
用col
颜色清空画面。 -
pget(x, y)
获取 (x
,y
) 处的像素颜色。 -
pset(x, y, col)
用col
颜色在 (x
,y
) 处绘制一个像素点。 -
line(x1, y1, x2, y2, col)
用col
颜色画一条从 (x1
,y1
) 到 (x2
,y2
) 的直线。 -
rect(x, y, w, h, col)
用col
颜色绘制一个从 (x
,y
) 开始的宽为w
、高为h
的矩形。 -
rectb(x, y, w, h, col)
用col
颜色绘制从 (x
,y
) 开始的宽为w
、高为h
的矩形边框。 -
circ(x, y, r, col)
用col
颜色绘制圆心为 (x
,y
),半径为r
的圆形。 -
circb(x, y, r, col)
用col
颜色绘制圆心为 (x
,y
),半径为r
的圆形边框。 -
elli(x, y, w, h, col)
从 (x
,y
) 画一个宽度w
,高度h
,颜色col
的椭圆。 -
ellib(x, y, w, h, col)
从 (x
,y
) 画出一个宽w
,高h
,颜色col
的椭圆轮廓。 -
tri(x1, y1, x2, y2, x3, y3, col)
用col
颜色绘制顶点分别为 (x1
,y1
),(x2
,y2
),(x3
,y3
) 的三角形。 -
trib(x1, y1, x2, y2, x3, y3, col)
用col
颜色绘制顶点分别为 (x1
,y1
),(x2
,y2
),(x3
,y3
) 的三角形边框。 -
fill(x, y, col)
从 (x
,y
) 画一个宽度w
,高度h
,颜色col
的椭圆。 -
blt(x, y, img, u, v, w, h, [colkey])
将尺寸为 (w
,h
) 的区域从图像库的 (u
,v
) 复制到 (x
,y
)。若w
或h
为负值,则在水平或垂直方向上翻转。若指定了colkey
的值,则视作透明颜色。
bltm(x, y, tm, u, v, w, h, [colkey])
从瓦片图tm
(0-7) 的 (u
,v
) 复制大小为 (w
,h
) 的区域到 (x
,y
)。如果为w
和/或h
设置了负值,它将在水平和/或垂直方向上反转。如果指定了colkey
,将被视为透明色。瓦片的大小是 8x8 像素,以(tile_x, tile_y)
的元组形式存储在瓦片图中。
text(x, y, s, col)
用col
颜色在 (x
,y
) 绘制字符串s
。
-
sounds
声音列表 (0-63)。 (参考 Sound 类)
示例:pyxel.sounds[0].speed = 60
-
musics
音乐列表 (0-7)。 (参考 Music 类) -
play(ch, snd, [tick], [loop])
播放通道ch
(0-3) 中的声音snd
(0-63)。如果声音snd
是一个列表,则按顺序播放。播放开始位置可以通过tick
(1 tick = 1/120 秒) 指定。如果loop
被指定为True
则循环播放。 -
playm(msc, [tick], [loop])
播放音乐msc
(0-7)。播放开始位置可以通过tick
(1 tick = 1/120 秒) 指定。如果loop
被指定为True
则循环播放。 -
stop([ch])
停止指定通道ch
(0-3) 的重播。stop()
可以停止所有通道的播放。 -
play_pos(ch)
获取通道ch
(0-3) 中音频重播位置(sound no, note no)
。若重播被停止则返回None
。
-
ceil(x)
返回大于或等于x
的最小的整数。 -
floor(x)
返回小于或等于x
的最大整数。 -
sgn(x)
当x
是正数时返回 1,当它是零时返回 0,当它是负数时返回 1。 -
sqrt(x)
返回x
的平方根。 -
sin(deg)
返回deg
度的正弦。 -
cos(deg)
返回deg
度的余弦。 -
atan2(y, x)
返回y
/x
的正切,单位是度。 -
rseed(seed)
设置随机数发生器的种子。 -
rndi(a, b)
返回一个大于或等于a
且小于或等于b
的随机整数。 -
rndf(a, b)
返回一个大于或等于a
且小于或等于b
的随机小数。 -
nseed(seed)
设置佩林噪声的种子。 -
noise(x, [y], [z])
返回指定坐标的佩林噪声值。
-
width
,height
图像的宽和高 -
get(x, y)
获取图像中 (x
,y
) 位置的值。 -
set(x, y, data)
使用字符串列表设置坐标 (x
,y
) 处的图像。
示例:pyxel.images[0].set(10, 10, ["0123", "4567", "89ab", "cdef"])
-
load(x, y, filename)
在 (x
,y
) 处加载图像文件 (png/gif/jpeg)。
-
width
,height
瓦片地图的宽和高 -
imgsrc
被瓦片地图 tilemap 引用的图像库 (0-2) -
set(x, y, data)
使用字符串列表在坐标 (x
,y
) 处设置瓦片地图。
示例:pyxel.tilemap(0).set(0, 0, ["0000 0100 a0b0", "0001 0101 a1b1"])
-
pget(x, y)
得到 (x
,y
) 处的瓦片。瓦片数据为元组(tile_x, tile_y)
。 -
pset(x, y, tile)
在 (x
,y
) 处画出瓦片tile
。瓦片数据为元组(tile_x, tile_y)
。
-
notes
音符列表 (0-127),数字越高,音调越高。数字达到 33 时,音调就达到'A2'(440Hz)。其余为-1。 -
tones
音色列表 (0:三角波 / 1:方波 / 2:脉冲 / 3:噪声) -
volumes
音量列表 (0-7) -
effects
音效列表 (0:无 / 1:滑动 / 2:颤音 / 3:淡出) -
speed
播放速度。1 为最快,数字越大,速度越慢。数字 120 时,每个音符长度为 1 秒。 -
set(notes, tones, volumes, effects, speed)
使用字符串设置音符、音色、音量及音效。如果音色、音量及音效的字符串比音符字符串短,则从开头重复。 -
set_notes(notes)
使用由'CDEFGAB'+'#-'+'01234'或'R'组成的字符串设置音符。大小写不敏感,且空格会被忽略。
示例:pyxel.sounds[0].set_notes("G2B-2D3R RF3F3F3")
-
set_tones(tones)
使用由'TSPN'组成的字符串设置音色。大小写不敏感,且空格会被忽略。
示例:pyxel.sounds[0].set_tones("TTSS PPPN")
-
set_volumes(volumes)
使用由'01234567'组成的字符串设置音量。大小写不敏感,且空格会被忽略。
示例:pyxel.sounds[0].set_volumes("7777 7531")
-
set_effects(effects)
使用由'NSVF'组成的字符串设置音效。大小写不敏感,且空格会被忽略。
示例:pyxel.sounds[0].set_effects("NFNF NVVS")
-
seqs
二维的声音列表 (0-63),带有通道的数量 -
set(seq0, seq1, seq2, ...)
设置通道的声音列表 (0-63)。如果指定了空列表,则对应通道不会用来播放。
示例:pyxel.musics[0].set([0, 1], [], [3])
Pyxel 还有一些“高级 API”,出于“可能令用户感到迷惑”、“需要专业知识”等一些原因,在本文尚未提及。
如果你对自己的技术很熟悉,可以参阅this,尝试挑战自己并创造一些神奇的作品!
使用Issue Tracker来提交 bug 报告或功能需求。在创建新 issue 之前,请确定没有类似的打开的 issue。
欢迎任何人在Issue Tracker中手动测试代码、上报 bug、提交优化建议等!
可以通过 pull requests (PRs) 形式来提交补丁或修复。请确认你的 pull request 对应的 issue 地址在 issue tracker 中依然是 open 状态。
一旦提交 pull request,则默认同意在MIT License的许可下发布。
Pyxel 遵循MIT License。您可以在专利软件中重复使用,前提是该软件的所有副本或重要部分均包含 MIT 许可条款的副本和版权声明。
Pyxel 正在 GitHub 赞助商上寻找赞助商。 考虑赞助 Pyxel 以进行持续维护和功能添加。 赞助商可以咨询 Pyxel 作为一个好处。 详情请参阅此处。