41  Mapping Your Game World: Colors and Coordinates

In our previous lesson, we learned about Pyxel and created our first application. Today, we’ll explore two fundamental aspects of any game world: colors and coordinate systems. Just as a cartographer needs to understand colors and coordinates to create maps, we need these skills to build our game worlds.

41.1 The Magic Palette: Pyxel’s 16 Colors

One of the charming aspects of Pyxel is its fixed 16-color palette, inspired by retro game systems. Like a painter with a limited but carefully chosen set of paints, this constraint encourages creativity and gives your games that authentic retro feel.

Here are Pyxel’s 16 colors, numbered from 0 to 15:

  1. Black
  2. Dark Blue
  3. Purple
  4. Dark Green
  5. Brown
  6. Dark Gray
  7. Light Gray
  8. White
  9. Red
  10. Orange
  11. Yellow
  12. Light Green
  13. Light Blue
  14. Gray
  15. Pink
  16. Peach

Let’s create a simple program to visualize this palette:

import pyxel

class ColorPalette:
    def __init__(self):
        pyxel.init(160, 160, title="Pyxel Color Palette")
        pyxel.run(self.update, self.draw)
    
    def update(self):
        if pyxel.btnp(pyxel.KEY_Q):
            pyxel.quit()
    
    def draw(self):
        pyxel.cls(7)  # Clear screen with white
        
        # Draw color squares and labels
        square_size = 20
        cols = 4
        
        for i in range(16):
            # Calculate position in a 4x4 grid
            x = 20 + (i % cols) * (square_size + 20)
            y = 20 + (i // cols) * (square_size + 20)
            
            # Draw colored square
            pyxel.rect(x, y, square_size, square_size, i)
            
            # Draw color number (black or white depending on color brightness)
            text_color = 7 if i < 6 or i == 8 else 0
            pyxel.text(x + 6, y + 6, str(i), text_color)

ColorPalette()

When you run this code, you’ll see all 16 colors displayed in a grid, each labeled with its color number.

Remember, whenever you need to specify a color in Pyxel (for drawing shapes, text, or clearing the screen), you’ll use these color numbers. For example:

pyxel.cls(0)        # Clear the screen with color 0 (black)
pyxel.rect(10, 10, 20, 30, 8)   # Draw a red rectangle
pyxel.text(40, 40, "Hello", 7)  # Draw white text

41.1.1 Pro Tip: Choosing the Right Color for Text

For text to be readable, it needs good contrast with the background. On dark colors (0-6, 8), use light text (7, 10, 11). On light colors (7, 9-15), use dark text (0, 1, 5).

41.2 The Cartographer’s Grid: Pyxel’s Coordinate System

Just as mapmakers use a grid system to pinpoint locations, Pyxel uses a coordinate system to position elements on the screen. Understanding this system is crucial for placing your game elements exactly where you want them.

In Pyxel (and most computer graphics):

  • The origin (0, 0) is at the top-left corner of the screen
  • The X-coordinate increases as you move to the right
  • The Y-coordinate increases as you move down

This might seem counter-intuitive if you’re used to mathematical coordinates (where Y increases as you go up), but this system is standard in most game and graphics programming.

Let’s create a visual representation of this coordinate system:

import pyxel

class CoordinateSystem:
    def __init__(self):
        pyxel.init(160, 120, title="Coordinate System")
        pyxel.run(self.update, self.draw)
    
    def update(self):
        if pyxel.btnp(pyxel.KEY_Q):
            pyxel.quit()
    
    def draw(self):
        pyxel.cls(6)  # Clear with light gray
        
        # Draw coordinate lines
        pyxel.line(0, 0, 159, 0, 5)  # Top edge
        pyxel.line(0, 0, 0, 119, 5)  # Left edge
        
        # Draw axis labels
        pyxel.text(75, 5, "X increases →", 0)
        pyxel.text(5, 60, "Y increases ↓", 0)
        
        # Draw origin point
        pyxel.circ(0, 0, 3, 8)  # Red circle at origin
        pyxel.text(5, 5, "(0,0)", 0)
        
        # Draw some example points
        points = [(40, 30), (80, 60), (120, 90)]
        
        for x, y in points:
            pyxel.circ(x, y, 3, 11)  # Green circle
            pyxel.text(x + 5, y, f"({x},{y})", 0)
        
        # Show current mouse position
        pyxel.text(5, 110, f"Mouse: ({pyxel.mouse_x},{pyxel.mouse_y})", 8)

CoordinateSystem()

When you run this code, you’ll see:

  • The origin (0,0) marked in the top-left
  • Example points with their coordinates
  • Your mouse position updating in real-time

41.3 Combining Colors and Coordinates: A Simple Drawing

Now, let’s bring our knowledge of colors and coordinates together to create a simple drawing:

import pyxel

class SimpleDrawing:
    def __init__(self):
        pyxel.init(160, 120, title="Simple Drawing")
        self.draw_sun = True
        pyxel.run(self.update, self.draw)
    
    def update(self):
        if pyxel.btnp(pyxel.KEY_Q):
            pyxel.quit()
        
        # Toggle sun/moon with space key
        if pyxel.btnp(pyxel.KEY_SPACE):
            self.draw_sun = not self.draw_sun
    
    def draw(self):
        # Draw sky
        sky_color = 12 if self.draw_sun else 1  # Light blue for day, dark blue for night
        pyxel.cls(sky_color)
        
        # Draw ground
        pyxel.rect(0, 90, 160, 30, 3)  # Dark green ground
        
        # Draw sun or moon
        celestial_color = 10 if self.draw_sun else 7  # Yellow sun, white moon
        pyxel.circ(120, 30, 15, celestial_color)
        
        # If night, add some stars
        if not self.draw_sun:
            for x, y in [(20, 20), (40, 10), (60, 30), (80, 15), (100, 25)]:
                pyxel.pset(x, y, 7)  # White stars
        
        # Draw a house
        pyxel.rect(20, 50, 40, 40, 4)  # Brown house
        pyxel.rect(30, 70, 10, 20, 1)  # Dark blue door
        pyxel.rect(50, 60, 10, 10, 13)  # Gray window
        
        # Draw roof
        pyxel.tri(20, 50, 40, 30, 60, 50, 8)  # Red roof
        
        # Instructions
        pyxel.text(5, 5, "Press SPACE to toggle day/night", 7)
        pyxel.text(5, 15, "Press Q to quit", 7)

SimpleDrawing()

This code creates a simple scene with a house, ground, and either a sun or moon depending on whether it’s day or night. You can toggle between day and night by pressing the space bar.

Notice how we:

  • Use different colors for the sky (12 for day, 1 for night)
  • Position the house using specific x and y coordinates
  • Draw the ground at the bottom of the screen (higher y values)
  • Use a variety of Pyxel’s drawing functions with different colors

41.4 Practice Time: Your Color and Coordinate Quest

Now it’s your turn to create a Pyxel application using your newfound knowledge of colors and coordinates. Complete these challenges:

  1. Create a simple landscape with a sky, ground, sun, and at least three different colored elements (trees, clouds, mountains, etc.).

  2. Add a moving element (like a bird or car) that moves across the screen and wraps around when it reaches the edge.

Here’s a starting point for your quest:

import pyxel

class MyLandscape:
    def __init__(self):
        pyxel.init(160, 120, title="My Landscape")
        
        # Initialize any variables you need
        self.moving_x = 0  # For your moving element
        
        pyxel.run(self.update, self.draw)
    
    def update(self):
        if pyxel.btnp(pyxel.KEY_Q):
            pyxel.quit()
        
        # Update your moving element's position
        self.moving_x = (self.moving_x + 1) % 160
        
        # Check for mouse clicks
        # (We'll add code for this part)
    
    def draw(self):
        # Clear the screen
        pyxel.cls(12)  # Light blue sky
        
        # Draw your landscape elements
        # (You'll add code here)
        
        # Draw your moving element
        # (You'll add code here)
        
        # Draw any interactive elements
        # (You'll add code here)

# Create and start your landscape
MyLandscape()

41.5 Common Bugs to Watch Out For

As you experiment with colors and coordinates in Pyxel, watch out for these common issues:

  1. Using invalid color numbers: Pyxel only supports colors 0-15. Using numbers outside this range will cause errors.

  2. Off-by-one errors in coordinates: Remember that coordinates start at 0, and the maximum coordinate is one less than the dimension (e.g., in a 160x120 window, valid x-coordinates are 0-159 and valid y-coordinates are 0-119).

  3. Drawing outside the screen: Elements drawn outside the visible area won’t cause errors, but they won’t be visible. Use the keep_in_bounds function to prevent this.

  4. Forgetting the coordinate system orientation: Remember that y increases as you go down. If something appears in the wrong place vertically, you might be thinking about y backwards.

  5. Not accounting for element size: When positioning elements, remember to account for their width and height. The position specifies the top-left corner, not the center.

41.6 Conclusion and Resources for Further Exploration

You’ve now mastered two fundamental aspects of game development: colors and coordinate systems. With these tools, you can precisely position and colorize elements in your game world.

To deepen your understanding of colors and coordinates in game development, check out these resources:

  1. Pyxel Color Palette Reference - See the exact RGB values of Pyxel’s 16 colors.

  2. Pixel Art Tutorials - Learn how to create pixel art using limited color palettes.

  3. Coordinate Systems in Game Development - An in-depth exploration of different coordinate systems used in games.

  4. Color Theory for Pixel Art - Learn how to create effective color schemes with limited palettes.

In our next lesson, we’ll explore simple drawing primitives in Pyxel, which will allow us to create more complex and interesting visuals for our games. Keep practicing with colors and coordinates – they’re the foundation upon which your game worlds will be built!