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)xandyare the coordinates where you want to draw the pointcolis 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):
pyxel.init(160, 120, title="Drawing Points")
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
pyxel.cls(1) # Clear screen with dark blue
# Draw some stars as individual points
pyxel.pset(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.text(5, 5, "Stars drawn with pset()", 7)
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)x1andy1are the coordinates of the starting pointx2andy2are the coordinates of the ending pointcolis the color number
Let’s create a simple house outline with lines:
import pyxel
class LineExample:
def __init__(self):
pyxel.init(160, 120, title="Drawing Lines")
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
pyxel.cls(1) # Clear screen with dark blue
# Draw a house outline with lines
# Base of the house
pyxel.line(40, 80, 80, 80, 7) # Bottom
pyxel.line(40, 80, 40, 50, 7) # Left wall
pyxel.line(80, 80, 80, 50, 7) # Right wall
# Roof
pyxel.line(40, 50, 60, 30, 7) # Left roof
pyxel.line(60, 30, 80, 50, 7) # Right roof
# Door
pyxel.line(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.text(5, 5, "House drawn with line()", 7)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
pyxel.rect(x, y, w, h, col) # Filled rectangle
pyxel.rectb(x, y, w, h, col) # Rectangle outlinexandyare the coordinates of the top-left cornerwandhare the width and height of the rectanglecolis the color number
Let’s draw some rectangles:
import pyxel
class RectangleExample:
def __init__(self):
pyxel.init(160, 120, title="Drawing Rectangles")
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
pyxel.cls(1) # Clear screen with dark blue
# Draw a filled rectangle (building)
pyxel.rect(40, 40, 80, 70, 5) # Gray building
# Draw rectangle outlines (windows)
pyxel.rectb(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
# Draw a filled rectangle (door)
pyxel.rect(75, 80, 10, 30, 4) # Brown door
pyxel.text(5, 5, "Building drawn with rect() and rectb()", 7)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
pyxel.circ(x, y, r, col) # Filled circle
pyxel.circb(x, y, r, col) # Circle outlinexandyare the coordinates of the center of the circleris the radius of the circlecolis the color number
Let’s create a simple solar system with circles:
import pyxel
class CircleExample:
def __init__(self):
pyxel.init(160, 120, title="Drawing Circles")
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
pyxel.cls(1) # Clear screen with dark blue
# Draw the sun (filled circle)
pyxel.circ(80, 60, 15, 10) # Yellow sun
# Draw planet orbits (circle outlines)
pyxel.circb(80, 60, 30, 13) # Light blue orbit
pyxel.circb(80, 60, 50, 13) # Light blue orbit
# Draw planets (filled circles)
pyxel.circ(80, 30, 5, 11) # Green planet
pyxel.circ(130, 60, 8, 8) # Red planet
pyxel.text(5, 5, "Solar system drawn with circ() and circb()", 7)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
pyxel.tri(x1, y1, x2, y2, x3, y3, col) # Filled triangle
pyxel.trib(x1, y1, x2, y2, x3, y3, col) # Triangle outlinex1,y1,x2,y2,x3,y3are the coordinates of the three corners of the trianglecolis the color number
Let’s draw some mountains with triangles:
import pyxel
class TriangleExample:
def __init__(self):
pyxel.init(160, 120, title="Drawing Triangles")
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
pyxel.cls(1) # Clear screen with dark blue
# Draw a sky
pyxel.rect(0, 0, 160, 80, 12) # Light blue sky
# Draw mountains with filled triangles
pyxel.tri(0, 80, 50, 30, 100, 80, 13) # Gray mountain
pyxel.tri(80, 80, 130, 25, 160, 80, 13) # Gray mountain
# Draw a simple pine tree with a triangle and rectangle
pyxel.rect(70, 80, 6, 10, 4) # Brown trunk
pyxel.tri(63, 80, 73, 60, 83, 80, 3) # Green triangle for leaves
pyxel.text(5, 5, "Mountains drawn with tri()", 7)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)xandyare the coordinates of the top-left corner of the texttextis the string to displaycolis the color number
Let’s explore different ways to use text:
import pyxel
class TextExample:
def __init__(self):
pyxel.init(160, 120, title="Drawing Text")
self.score = 12550
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
pyxel.cls(1) # Clear screen with dark blue
# Draw a simple title
pyxel.text(40, 10, "SPACE ADVENTURE", 7)
# Draw game stats with different colors
pyxel.text(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
# Draw instructions
pyxel.text(10, 100, "Press Z to shoot", 13)
pyxel.text(10, 110, "Press Q to quit", 13)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):
pyxel.init(160, 120, title="Game UI Example")
self.health = 70 # Percentage
self.score = 3500
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
pyxel.cls(1) # Clear screen with dark blue
# Draw game title
pyxel.text(60, 5, "DUNGEON QUEST", 7)
# Draw health bar
pyxel.text(10, 20, "HEALTH:", 7)
pyxel.rectb(60, 20, 52, 7, 7) # Health bar outline
pyxel.rect(61, 21, int(self.health / 2), 5, 8) # Red health bar
# Draw score
pyxel.text(10, 35, "SCORE:", 7)
pyxel.text(60, 35, str(self.score), 10)
# Draw a mini-map in the corner
pyxel.rectb(116, 10, 40, 40, 7) # Mini-map border
# Draw some elements on the mini-map
pyxel.rect(125, 25, 4, 4, 11) # Player position (green)
pyxel.circ(140, 20, 2, 8) # Enemy position (red)
pyxel.pset(120, 30, 10) # Item position (yellow)
# Draw instructions
pyxel.text(10, 100, "Use arrow keys to play", 13)
pyxel.text(10, 110, "Q: Quit", 13)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):
pyxel.init(160, 120, title="My Drawing App")
pyxel.run(self.update, self.draw)
def update(self):
if pyxel.btnp(pyxel.KEY_Q):
pyxel.quit()
def draw(self):
pyxel.cls(0) # Clear screen with black
# 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!