Install TinyDrawer package on Thonny
A collection of drawing methods inspired by PICO-8 game engine built for Raspberry Pi Pico devices written in MicroPython. These methods handle drawing on the high-level while pushing pixels to the RGB565 framebuf.FrameBuffer.
Waveshare's Pico LCD 1.14 | ZhongJungYuan's 1.69 TFT LCD |
---|---|
Just like PICO-8, TinyDrawer comes with the sprite buffer that can store 32 sprites (8 columns and 4 rows, and each sprite is 8x8 pixels) by default. Design your sprites using TinyDrawer Sprite Buffer Editor
At the bottom, copy the Hex String, and initialize the TinyDrawer to load this sprite buffer to your program.
Call TinyDrawer(hex_string, buffer_w, buffer_h, display_w, display_h, zoom)
to create the TinyDrawer object
import tinydrawer
# Initialize TinyDrawer with the hex string from the Editor
td = TinyDrawer("000877004fff94ff...") # <- arg: your hex string
You can change the zoom level and display's width and height
td = TinyDrawer("000877004fff94ff...", display_w = 240, display_h = 135, zoom = 5)
You can later change the sprite buffer size by calling set_buffer_hex(hex_string, buffer_w, buffer_h)
.
# change buffer size to 12 x 2
td.set_buffer_hex("000877004fff94ff...", buffer_w = 12, buffer_h = 2)
The sprite index n
indicates which sprite from the Sprite Buffer should be drawn. The top-left sprite has an index of n = 0
, while the first sprite in the second row has an index of n = 8
.
Use spr(fb, n, x, y)
to draw a sprite at index n
to the framebuf.FrameBuffer fb
at x
, y
position.
# spr(fb, n, x, y, w = 1, h = 1, flip_x = False, flip_y = False)
# draw a 8x8 sprite 0 at (20, 10)
td.spr(fb, 0, 20, 10)
# draw a 16x16 sprite 1 at (120, 30)
td.spr(fb, 1, 120, 30, w = 2, h = 2)
# draw a 8x8 sprite 8 but flipping the sprite horizontally
td.spr(fb, 8, 0, 0, flip_x = True)
TinyDrawer comes with 16 colors:
To use a color on the framebuf, call color(index)
to get the int number in RGB565 color format.
# fill the entire display with black color
fbuff.fill(td.color(0))
# draw an orange rectangle
fbuff.fill_rect(0, 0, 240, 100, td.color(9))
By default, the black color 0
on the Sprite Buffer is considered as a transparent color when drawing. Use pal(c0, c1)
to swap colors before drawing.
For example, to draw the black color pixels on the framebuf:
- On the Editor, replace black color with white color
0
or any other color - Optional: Call
pal()
to reset the palette - Call
pal(7, 0)
to replace white7
with black0
when drawing - Call
str(fb, n, x, y)
to draw - Optional: Call
pal()
to clear the color replacement
Another example, we can turn Mario into Luigi by swapping colors at sprite index 0
# replace any red with green
td.pal(8, 11)
# draw mario sprite
td.spr(fb, 0, 100, 100)
# reset the color replacement
td.pal()
In this demo, we will use Pi Pico W and Waveshare's Pico LCD 1.14 which has joystick controller and buttons. We will run example_mario.py on the Pico. You can use any device and any display screen as long as they meet the following requirements
- Have a Raspberry Pi Pico device or Pico compatible device
- Have a SPI ST7789 display connected to Pi Pico
- Make sure the display color format is set to RGB565
- Have a code that can send framebuf.FrameBuffer to the display
- Go to Tools -> Manage Packages. Then search for tinydrawer and install it to the Pi Pico
- Upload
lc_1inch14.py
to the Pi Pico. This is a demo file from Waveshare's Pico LCD 1.14 tutorial. We modified it to be used on different screen sizes and orientations. If you use a different display, use the demo file from your manufacturer, make sure that the class is a child offramebuf.FrameBuffer
class LCD_1inch14(framebuf.FrameBuffer):
...
- Upload
example_mario.py
to the Pi Pico - Open
example_mario.py
on Thonny, and check the parameters on the TinyDrawer
display_w = 240
display_h = 135
td = TinyDrawer("000877004fff94ff...", display_w = display_w, display_h = display_h)
...
- Run the
example_mario.py
on the Pi Pico. On Waveshare's Pico LCD 1.14, press the B button to turn off the Mario's autorun mode. Then you can move the player using left stick, right stick and the A button.
Upload example_snake.py
and run it
Updating more pixels means a drop in framerate since we have to constantly run spr()
.
Comment on the example_mario.py
- Since the camera does not move, the floor of the level and the background above the coin are drawn before entering the game loop. It won't send the updated pixels to the framebuf to save the computation time.
We will keep optimizing the drawing functions. Feel free to contribute to the project.
The source code for the site is licensed under the MIT license, which you can find in the LICENSE file.
All graphical assets are licensed under the Creative Commons Attribution 4.0 International License.