42 The Artist’s Tools: Drawing Primitives and Shapes
In our previous lessons, we’ve set up Pyxel and learned about colors and coordinates. Today, we’ll explore the fundamental building blocks of any game’s visuals: drawing primitives and shapes. Much like a painter needs brushes, pens, and various tools to create art, a game developer needs different drawing functions to create game elements.
42.1 What are Drawing Primitives?
Drawing primitives are the basic shapes and elements that can be combined to create complex images. In Pyxel, these include points, lines, rectangles, circles, triangles, and text. These simple shapes are the foundation of everything you’ll draw in your games - from characters and obstacles to user interfaces and backgrounds.
Let’s explore each of these magical drawing tools and learn how to wield them effectively!
42.2 The Point: The Smallest Unit of Art
A point is the simplest drawing primitive - just a single pixel on the screen. In Pyxel, we use the pset()
function to draw a point:
pyxel.pset(x, y, col)
x
andy
are the coordinates where you want to draw the pointcol
is the color number (0-15)
Let’s create a simple example that draws a few stars in the night sky:
import pyxel
class PointsExample:
def __init__(self):
160, 120, title="Drawing Points")
pyxel.init(self.update, self.draw)
pyxel.run(
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
1) # Clear screen with dark blue
pyxel.cls(
# Draw some stars as individual points
20, 20, 7) # White star
pyxel.pset(40, 15, 7)
pyxel.pset(60, 25, 7)
pyxel.pset(100, 10, 7)
pyxel.pset(120, 30, 7)
pyxel.pset(
5, 5, "Stars drawn with pset()", 7)
pyxel.text(
PointsExample()
This simple example creates a dark blue background with five white stars drawn as individual points.
42.3 The Line: Connecting the Dots
Lines allow us to connect two points. In Pyxel, we use the line()
function:
pyxel.line(x1, y1, x2, y2, col)
x1
andy1
are the coordinates of the starting pointx2
andy2
are the coordinates of the ending pointcol
is the color number
Let’s create a simple house outline with lines:
import pyxel
class LineExample:
def __init__(self):
160, 120, title="Drawing Lines")
pyxel.init(self.update, self.draw)
pyxel.run(
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
1) # Clear screen with dark blue
pyxel.cls(
# Draw a house outline with lines
# Base of the house
40, 80, 80, 80, 7) # Bottom
pyxel.line(40, 80, 40, 50, 7) # Left wall
pyxel.line(80, 80, 80, 50, 7) # Right wall
pyxel.line(
# Roof
40, 50, 60, 30, 7) # Left roof
pyxel.line(60, 30, 80, 50, 7) # Right roof
pyxel.line(
# Door
55, 80, 55, 65, 7) # Left of door
pyxel.line(65, 80, 65, 65, 7) # Right of door
pyxel.line(55, 65, 65, 65, 7) # Top of door
pyxel.line(
5, 5, "House drawn with line()", 7) pyxel.text(
This code creates a simple house outline using lines to connect various points.
42.4 The Rectangle: Building Blocks of Games
Rectangles are perhaps the most commonly used shape in games. They’re perfect for buildings, platforms, buttons, and more. Pyxel offers two rectangle functions:
rect()
: Draws a filled rectanglerectb()
: Draws just the outline of a rectangle
# Filled rectangle
pyxel.rect(x, y, w, h, col) # Rectangle outline pyxel.rectb(x, y, w, h, col)
x
andy
are the coordinates of the top-left cornerw
andh
are the width and height of the rectanglecol
is the color number
Let’s draw some rectangles:
import pyxel
class RectangleExample:
def __init__(self):
160, 120, title="Drawing Rectangles")
pyxel.init(self.update, self.draw)
pyxel.run(
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
1) # Clear screen with dark blue
pyxel.cls(
# Draw a filled rectangle (building)
40, 40, 80, 70, 5) # Gray building
pyxel.rect(
# Draw rectangle outlines (windows)
50, 50, 15, 15, 7) # White window outline
pyxel.rectb(95, 50, 15, 15, 7) # White window outline
pyxel.rectb(50, 75, 15, 15, 7) # White window outline
pyxel.rectb(95, 75, 15, 15, 7) # White window outline
pyxel.rectb(
# Draw a filled rectangle (door)
75, 80, 10, 30, 4) # Brown door
pyxel.rect(
5, 5, "Building drawn with rect() and rectb()", 7) pyxel.text(
This code creates a building using a filled rectangle, with door and windows drawn using a combination of filled and outlined rectangles.
42.5 The Circle: Perfect Rounds
Circles are ideal for many game elements like balls, planets, and coins. Pyxel offers two circle functions:
circ()
: Draws a filled circlecircb()
: Draws just the outline of a circle
# Filled circle
pyxel.circ(x, y, r, col) # Circle outline pyxel.circb(x, y, r, col)
x
andy
are the coordinates of the center of the circler
is the radius of the circlecol
is the color number
Let’s create a simple solar system with circles:
import pyxel
class CircleExample:
def __init__(self):
160, 120, title="Drawing Circles")
pyxel.init(self.update, self.draw)
pyxel.run(
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
1) # Clear screen with dark blue
pyxel.cls(
# Draw the sun (filled circle)
80, 60, 15, 10) # Yellow sun
pyxel.circ(
# Draw planet orbits (circle outlines)
80, 60, 30, 13) # Light blue orbit
pyxel.circb(80, 60, 50, 13) # Light blue orbit
pyxel.circb(
# Draw planets (filled circles)
80, 30, 5, 11) # Green planet
pyxel.circ(130, 60, 8, 8) # Red planet
pyxel.circ(
5, 5, "Solar system drawn with circ() and circb()", 7) pyxel.text(
This code creates a simple solar system with a sun, planets, and orbits, all using circles.
42.6 The Triangle: Adding Dimension
Triangles are versatile shapes that can be used for a variety of game elements, from mountain ranges to decoration. Pyxel offers two triangle functions:
tri()
: Draws a filled triangletrib()
: Draws just the outline of a triangle
# Filled triangle
pyxel.tri(x1, y1, x2, y2, x3, y3, col) # Triangle outline pyxel.trib(x1, y1, x2, y2, x3, y3, col)
x1
,y1
,x2
,y2
,x3
,y3
are the coordinates of the three corners of the trianglecol
is the color number
Let’s draw some mountains with triangles:
import pyxel
class TriangleExample:
def __init__(self):
160, 120, title="Drawing Triangles")
pyxel.init(self.update, self.draw)
pyxel.run(
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
1) # Clear screen with dark blue
pyxel.cls(
# Draw a sky
0, 0, 160, 80, 12) # Light blue sky
pyxel.rect(
# Draw mountains with filled triangles
0, 80, 50, 30, 100, 80, 13) # Gray mountain
pyxel.tri(80, 80, 130, 25, 160, 80, 13) # Gray mountain
pyxel.tri(
# Draw a simple pine tree with a triangle and rectangle
70, 80, 6, 10, 4) # Brown trunk
pyxel.rect(63, 80, 73, 60, 83, 80, 3) # Green triangle for leaves
pyxel.tri(
5, 5, "Mountains drawn with tri()", 7) pyxel.text(
This code creates a simple mountain landscape using triangles, with a sky drawn as a rectangle and a small pine tree made from a rectangle (trunk) and a triangle (foliage).
42.7 Text: The Power of Words
Text is essential for displaying information to the player, such as scores, instructions, or dialog. In Pyxel, we use the text()
function:
pyxel.text(x, y, text, col)
x
andy
are the coordinates of the top-left corner of the texttext
is the string to displaycol
is the color number
Let’s explore different ways to use text:
import pyxel
class TextExample:
def __init__(self):
160, 120, title="Drawing Text")
pyxel.init(self.score = 12550
self.update, self.draw)
pyxel.run(
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
1) # Clear screen with dark blue
pyxel.cls(
# Draw a simple title
40, 10, "SPACE ADVENTURE", 7)
pyxel.text(
# Draw game stats with different colors
10, 30, "SCORE:", 7)
pyxel.text(50, 30, str(self.score), 10) # Yellow for the score
pyxel.text(
10, 40, "LEVEL:", 7)
pyxel.text(50, 40, "5", 11) # Green for the level
pyxel.text(
10, 50, "LIVES:", 7)
pyxel.text(50, 50, "3", 8) # Red for lives
pyxel.text(
# Draw instructions
10, 100, "Press Z to shoot", 13)
pyxel.text(10, 110, "Press Q to quit", 13) pyxel.text(
This example shows how to display different types of text on the screen with various colors.
42.8 Creating a Simple UI with Shapes and Text
Now, let’s combine what we’ve learned to create a simple game UI that shows health, score, and a mini-map:
import pyxel
class GameUI:
def __init__(self):
160, 120, title="Game UI Example")
pyxel.init(self.health = 70 # Percentage
self.score = 3500
self.update, self.draw)
pyxel.run(
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
1) # Clear screen with dark blue
pyxel.cls(
# Draw game title
60, 5, "DUNGEON QUEST", 7)
pyxel.text(
# Draw health bar
10, 20, "HEALTH:", 7)
pyxel.text(60, 20, 52, 7, 7) # Health bar outline
pyxel.rectb(61, 21, int(self.health / 2), 5, 8) # Red health bar
pyxel.rect(
# Draw score
10, 35, "SCORE:", 7)
pyxel.text(60, 35, str(self.score), 10)
pyxel.text(
# Draw a mini-map in the corner
116, 10, 40, 40, 7) # Mini-map border
pyxel.rectb(
# Draw some elements on the mini-map
125, 25, 4, 4, 11) # Player position (green)
pyxel.rect(140, 20, 2, 8) # Enemy position (red)
pyxel.circ(120, 30, 10) # Item position (yellow)
pyxel.pset(
# Draw instructions
10, 100, "Use arrow keys to play", 13)
pyxel.text(10, 110, "Q: Quit", 13) pyxel.text(
This example demonstrates how to create a simple game UI using various drawing primitives together.
42.9 Practice Time: Your Drawing Primitive Quest
Now it’s your turn to create a Pyxel application using the drawing primitives you’ve learned. Complete these challenges:
Create a scene that uses at least one of each drawing primitive: point, line, rectangle, circle, triangle, and text.
Include at least three different colors in your scene.
Use at least one filled shape and one outline shape.
Here’s a starting point for your quest:
import pyxel
class MyDrawingApp:
def __init__(self):
160, 120, title="My Drawing App")
pyxel.init(self.update, self.draw)
pyxel.run(
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
0) # Clear screen with black
pyxel.cls(
# Draw your scene using different primitives
# Use at least one point (pset)
# Use at least one line
# Use at least one rectangle (rect or rectb)
# Use at least one circle (circ or circb)
# Use at least one triangle (tri or trib)
# Use at least one text element
# Don't forget to use different colors!
42.10 Common Bugs to Watch Out For
As you experiment with drawing primitives in Pyxel, watch out for these common issues:
Coordinate System: Remember that the origin (0,0) is at the top-left corner, with y-values increasing downward. This can be confusing if you’re used to other coordinate systems.
Coordinate Order: For shapes with multiple points (lines, triangles), make sure you’re providing the coordinates in the correct order.
Off-by-one Errors: When drawing shapes, remember that the specified coordinates are for the top-left corner (for rectangles) or exact points (for lines and triangles), not the center.
Missing Parameters: Each drawing function requires a specific number of parameters. Be sure to provide all of them, including the color.
Drawing Order: Elements are drawn in the order your code executes them. If something appears “behind” another element when it should be in front, try changing the order of your drawing commands.
Text Positioning: Text is drawn from the top-left corner. If text appears cut off, make sure it has enough space to be displayed.
Color Numbers: Pyxel uses color numbers 0-15. If you provide a color number outside this range, it will be wrapped around (e.g., color 16 becomes color 0).
42.11 Conclusion and Resources for Further Mastery
You’ve now mastered the fundamental drawing primitives in Pyxel. With these tools, you can create virtually any 2D visual you might need for your games, from simple shapes to complex scenes.
To further enhance your artistic skills in game development, check out these resources:
Pyxel Drawing Functions Documentation - Detailed information about all drawing functions in Pyxel.
Pixel Art Techniques - Learn techniques for creating effective pixel art, which pairs perfectly with Pyxel’s retro aesthetic.
Game Art Tips for Beginners - Tips for creating effective game art, even if you’re not an artist.
Retro Game Graphics Guide - A guide to creating retro-style game graphics.
In our next lesson, we’ll explore loading and using sprites/images in Pyxel, which will allow us to create even more sophisticated and detailed visuals for our games. Keep practicing with drawing primitives – they’ll form the foundation of your game development toolkit!