[ English | 日本語 | Other Languages ]
Pyxel is a retro game engine for Python.
Thanks to its simple specifications inspired by retro gaming consoles, such as only 16 colors can be displayed and only 4 sounds can be played back at the same time, you can feel free to enjoy making pixel art style games.
![](https://raw.githubusercontent.com/kitao/pyxel/master/pyxel/examples/screenshots/01_hello_pyxel.gif)
![](https://raw.githubusercontent.com/kitao/pyxel/master/pyxel/examples/screenshots/02_jump_game.gif)
![](https://raw.githubusercontent.com/kitao/pyxel/master/pyxel/examples/screenshots/03_draw_api.gif)
![](https://raw.githubusercontent.com/kitao/pyxel/master/pyxel/examples/screenshots/04_sound_api.gif)
![](https://raw.githubusercontent.com/kitao/pyxel/master/pyxel/editor/screenshots/image_tilemap_editor.gif)
![](https://raw.githubusercontent.com/kitao/pyxel/master/pyxel/editor/screenshots/sound_music_editor.gif)
The specifications of the gaming console, APIs, and palettes of Pyxel are referring to awesome PICO-8 and TIC-80.
Pyxel is open source and free to use. Let's start making a retro game with Pyxel!
- Run on Windows, Mac, and Linux
- Code writing with Python3
- Fixed 16 color palette
- 256x256 sized 3 image banks
- 256x256 sized 8 tilemaps
- 4 channels with 64 definable sounds
- 8 musics which can combine arbitrary sounds
- Keyboard, mouse, and joystick(WIP) inputs
- Image and sound editor
After installing Python3, the following pip
command installs Pyxel:
pip install pyxel
After installing Python3 and glfw (version 3.2.1 or higher), install Pyxel with pip
command.
If Homebrew package manager is ready, the following command installs all the necessary packages:
brew install python3 glfw
pip3 install pyxel
Install the required packages in a way appropriate for each distribution. glfw must be version 3.2.1 or higher.
Arch:
Install python-pixel
by using your favorite AUR helper:
yay -S python-pyxel
Debian:
apt-get install python3 python3-pip libglfw3 libportaudio2 libasound-dev
pip3 install pyxel
Fedora:
dnf install glfw portaudio
pip3 install pyxel
After installing Pyxel, the examples of Pyxel will be copied to the current directory with the following command:
install_pyxel_examples
The examples can be executed like normal Python code:
cd pyxel_examples
python 01_hello_pyxel.py
or
cd pyxel_examples
python3 01_hello_pyxel.py
After importing the Pyxel module in your python code, specify the window size with init
function first, then starts the Pyxel application with run
function.
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)
The arguments of run
function are update
function to update each frame and draw
function to draw screen when necessary.
In an actual application, it is recommended to wrap pyxel code in a class as below:
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, self.x + 7, 7, 9)
App()
The following special controls can be performed while a Pyxel application is running:
Alt(Option)+1
Save the screenshot to the desktopAlt(Option)+2
Reset the recording start time of the screen capture videoAlt(Option)+3
Save the screen capture video (gif) to the desktop (up to 30 seconds)Alt(Option)+0
Toggle the performance monitor (fps, update time, and draw time)Alt(Option)+Enter
Toggle full screen
The attached Pyxel Editor can create images and sounds used in a Pyxel application.
Pyxel Editor runs with an arbitrary resource file name.
pyxeleditor pyxel_resource_file
The created resource file (.pyxel) can be loaded with the load
function.
Pyxel Editor has the following edit modes.
Image Editor:
The mode to edit the image banks.
Tilemap Editor:
The mode to edit tilemaps in which images of the image banks are arranged in a tile pattern.
Sound Editor:
The mode to edit sounds.
Music Editor:
The mode to edit musics in which the sounds are arranged in order of playback.
Pyxel images and tilemaps can also be created in the following way:
- Create an image from a list of strings with
Image.set
orTilemap.set
function - Load a png file in Pyxel palette with
Image.load
function
Because Pyxel uses the same palette as PICO-8, when creating png images for Pyxel, it is recommended to use Aseprite in PICO-8 palette mode.
Pyxel sounds can also be created in the following way:
- Create a sound from strings with
Sound.set
orMusic.set
function
Please refer to the API reference for usage of these functions.
-
width
,height
The width and height of the screen -
frame_count
The number of the elapsed frames -
init(width, height, [caption], [scale], [palette], [fps], [border_width], [border_color])
Initialize the Pyxel application with screen size (width
,height
). The maximum width and height of the screen is 255
It is also possible to specify the window title withcaption
, the display magnification withscale
, the palette color withpalette
, the frame rate withfps
, and the margin width and color outside the screen withborder_width
andborder_color
.palette
is specified as a list of 16 elements of 24 bit color,border_color
as 24 bit color -
run(update, draw)
Start the Pyxel application and callupdate
function for frame update anddraw
function for drawing -
quit()
End the Pyxel application at the end of the current frame
-
save(filename)
Save the resource file (.pyxel) to the directory of the execution script -
load(filename)
Read the resource file (.pyxel) from the directory of the execution script
-
mouse_x
,mouse_y
The current position of the mouse cursor -
btn(key)
ReturnTrue
ifkey
is pressed, otherwise returnFalse
(key definition list) -
btnp(key, [hold], [period])
ReturnTrue
ifkey
is pressed at that frame, otherwise returnFalse
. Whenhold
andperiod
are specified,True
will be returned at theperiod
frame interval when thekey
is held down for more thanhold
frames -
btnr(key)
ReturnTrue
ifkey
is released at that frame, otherwise returnFalse
-
mouse(visible)
Ifvisible
isTrue
, show the mouse cursor. IfFalse
, hide it. Even if the mouse cursor is not displayed, its position is updated.
-
image(img, [system])
Operate the image bankimg
(0-2) (see the Image class). Ifsystem
isTrue
, the image bank 3 for system can be accessed
e.g.pyxel.image(0).load(0, 0, 'title.png')
-
tilemap(tm)
Operate the tilemaptm
(0-7) (see the Tilemap class) -
clip(x1, y1, x2, y2)
Set the drawing area of the screen to (x1
,y1
)-(x2
,y2
). Reset the drawing area withclip()
-
pal(col1, col2)
Replace colorcol1
withcol2
at drawing.pal()
to reset to the initial palette -
cls(col)
Clear screen with colorcol
-
pix(x, y, col)
Draw a pixel of colorcol
at (x
,y
) -
line(x1, y1, x2, y2, col)
Draw a line of colorcol
from (x1
,y1
) to (x2
,y2
) -
rect(x1, y1, x2, y2, col)
Draw a rectangle of colorcol
from (x1
,y1
) to (x2
,y2
) -
rectb(x1, y1, x2, y2, col)
Draw the outline of a rectangle of colorcol
from (x1
,y1
) to (x2
,y2
) -
circ(x, y, r, col)
Draw a circle of radiusr
and colorcol
at (x
,y
) -
circb(x, y, r, col)
Draw the outline of a circle of radiusr
and colorcol
at (x
,y
) -
blt(x, y, img, u, v, w, h, [colkey])
Copy the region of size (w
,h
) from (u
,v
) of the image bankimg
(0-2) to (x
,y
). If negative value is set forw
and/orh
, it will reverse horizontally and/or vertically. Ifcolkey
is specified, treated as transparent color -
bltm(x, y, img, tm, tu, tv, tw, th, [colkey])
Copy the image bankimg
(0-2) to (x
,y
) according to the tile information of size (tw
,th
) from (tu
,tv
) of the tilemaptm
(0-7). Ifcolkey
is specified, treated as transparent color. A tile of the tilemap is drawn with a size of 8x8, and if the tile number is 0, indicates the region (0, 0)-(7, 7) of the image bank, if 1, indicates (8, 0)-(15, 0). -
text(x, y, s, col)
Draw a strings
of colorcol
at (x
,y
)
-
sound(snd, [system])
Operate the soundsnd
(0-63) (see the Sound class). Ifsystem
isTrue
, the sound 64 for system can be accessed
e.g.pyxel.sound(0).speed = 60
-
music(msc)
Operate the musicmsc
(0-7) (see the Music class) -
play(ch, snd, loop=False)
Play the soundsnd
(0-63) on channelch
(0-3). Play in order whensnd
is a list -
playm(msc, loop=False)
Play the musicmsc
(0-7) -
stop([ch])
Stop playback of all channels. Ifch
(0-3) is specified, stop the corresponding channel only
-
width
,height
The width and height of the image -
data
The data of the image (NumPy array) -
get(x, y)
Retrieve the data of the image at (x
,y
) -
set(x, y, data)
Set the data of the image at (x
,y
) by a value or a list of strings
e.g.pyxel.image(0).set(10, 10, ['1234', '5678', '9abc', 'defg'])
-
load(x, y, filename)
Read the png image from the directory of the execution script at (x
,y
) -
copy(x, y, img, u, v, w, h)
Copy the region of size (w
,h
) from (u
,v
) of the image bankimg
(0-2) to (x
,y
)
-
width
,height
The width and height of the tilemap -
data
The data of the tilemap (NumPy array) -
get(x, y)
Retrieve the data of the tilemap at (x
,y
) -
set(x, y, data)
Set the data of the tilemap at (x
,y
) by a value or a list of strings
e.g.pyxel.tilemap(0).set(0, 0, ['000102', '202122', 'a0a1a2', 'b0b1b2'])
-
copy(x, y, tm, u, v, w, h)
Copy the region of size (w
,h
) from (u
,v
) of the tilemaptm
(0-7) to (x
,y
)
-
note
List of note(0-127) (33 = 'A2' = 440Hz) -
tone
List of tone(0:Triangle / 1:Square / 2:Pulse / 3:Noise) -
volume
List of volume(0-7) -
effect
List of effects(0:None / 1:Slide / 2:Vibrato / 3:FadeOut) -
speed
The length of one note(120 = 1 second per tone) -
set(note, tone, volume, effect, speed)
Set a note, tone, volume, and effect with a string. If the tone, volume, and effect length are shorter than the note, it is repeated from the beginning -
set_note(note)
Set the note with a string made of 'CDEFGAB'+'#-'+'0123' or 'R'. Case-insensitive and whitespace is ignored
e.g.pyxel.sound(0).set_note('G2B-2D3R RF3F3F3')
-
set_tone(tone)
Set the tone with a string made of 'TSPN'. Case-insensitive and whitespace is ignored
e.g.pyxel.sound(0).set_tone('TTSS PPPN')
-
set_volume(volume)
Set the volume with a string made of '01234567'. Case-insensitive and whitespace is ignored
e.g.pyxel.sound(0).set_volume('7777 7531')
-
set_effect(effect)
Set the effect with a string made of 'NSVF'. Case-insensitive and whitespace is ignored
e.g.pyxel.sound(0).set_effect('NFNF NVVS')
-
ch0
List of sound(0-63) play on channel 0 -
ch1
List of sound(0-63) play on channel 1 -
ch2
List of sound(0-63) play on channel 2 -
ch3
List of sound(0-63) play on channel 3 -
set(ch0, ch1, ch2, ch3)
Set the list of sound(0-63) of all channels
e.g.pyxel.music(0).set([0, 1], [2, 3], [4], [])
-
set_ch0(data)
Set the list of sound(0-63) of channel 0 -
set_ch1(data)
Set the list of sound(0-63) of channel 1 -
set_ch2(data)
Set the list of sound(0-63) of channel 2 -
set_ch3(data)
Set the list of sound(0-63) of channel 3
Use the issue tracker to submit bug reports and feature/enhancement requests. Before submitting a new issue, search the issue tracker to ensure that there is no similar open issue.
When submitting a report, use this link.
Anyone manually testing the code and reporting bugs or suggestions for enhancements in the issue tracker are very welcome!
Patches/fixes are accepted in form of pull requests (PRs). Make sure the issue the pull request addresses is open in the issue tracker.
Submitted pull request is deemed to have agreed to publich under MIT license.
Pyxel is under MIT license. It can be reused within proprietary software provided that all copies of the licensed software include a copy of the MIT License terms and the copyright notice.