Skip to content

Your First Project

This guide will walk you through creating and running your first PixelRoot32 project step by step. By the end, you'll have a working project that displays a simple scene on both ESP32 and PC.

Prerequisites

Required Software

  • PlatformIO: Install the PlatformIO IDE extension in VS Code
  • Open VS Code
  • Go to Extensions (Ctrl+Shift+X)
  • Search for "PlatformIO IDE"
  • Install and restart VS Code

  • Python 3.8+: Required for PlatformIO (usually installed automatically)

For ESP32 Development

  • ESP32 Board: Any ESP32 development board (ESP32-WROOM, ESP32-WROVER, etc.)
  • USB Cable: To connect and program your ESP32
  • TFT Display: Compatible display (ST7735, ST7789, ILI9341, etc.)
  • Buttons: 5-6 digital buttons for input (optional for first project)
  • Audio Hardware (optional): Speaker + amplifier (PAM8302A) or I2S DAC (MAX98357A)

For Native (PC) Development

  • SDL2: Development libraries
  • Windows (MSYS2): pacman -S mingw-w64-x86_64-SDL2
  • Linux: sudo apt-get install libsdl2-dev
  • macOS: brew install sdl2

Step 1: Create a New PlatformIO Project

  1. Open VS Code with PlatformIO installed

  2. Create New Project:

  3. Click on the PlatformIO icon in the sidebar
  4. Click "New Project"
  5. Name: my-first-pixelroot32-game
  6. Board: Select "ESP32 Dev Module" (or your specific board)
  7. Framework: Arduino
  8. Location: Choose your workspace folder
  9. Click "Finish"

  10. Project Structure: Your project should now have this structure:

    my-first-pixelroot32-game/
    ├── .pio/
    ├── include/
    ├── lib/
    ├── src/
    │   └── main.cpp
    ├── test/
    └── platformio.ini
    

Step 2: Install PixelRoot32 Engine

  1. Open platformio.ini

  2. Add the library dependency:

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps = 
    gperez88/PixelRoot32-Game-Engine@0.2.0-dev

⚠️ IMPORTANT: Use the exact version 0.2.0-dev. Do NOT use ^ or fuzzy versioning.

  1. Save the file. PlatformIO will automatically download the library.

Option B: Git Submodule

  1. Open terminal in your project root

  2. Add as submodule:

    git submodule add https://github.com/Gperez88/PixelRoot32-Game-Engine.git lib/PixelRoot32-Game-Engine
    

  3. Update platformio.ini:

    lib_extra_dirs = lib
    

Step 3: Configure Hardware (ESP32)

Configure TFT_eSPI Display

Edit platformio.ini and add build flags for your display. Here are two common configurations:

For ST7789 (240x240):

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps = 
    gperez88/PixelRoot32-Game-Engine@0.2.0-dev
    bodmer/TFT_eSPI@^2.5.43

build_flags = 
    -D ST7789_DRIVER
    -D TFT_WIDTH=240
    -D TFT_HEIGHT=240
    -D TFT_MOSI=23
    -D TFT_SCLK=18
    -D TFT_DC=2
    -D TFT_RST=4
    -D TFT_CS=-1
    -D LOAD_GLCD
    -D LOAD_FONT2
    -D LOAD_FONT4
    -D LOAD_FONT6
    -D LOAD_FONT7
    -D LOAD_FONT8
    -D LOAD_GFXFF
    -D SMOOTH_FONT
    -D SPI_FREQUENCY=40000000
    -D SPI_READ_FREQUENCY=20000000

For ST7735 (128x128):

build_flags = 
    -D ST7735_DRIVER
    -D ST7735_GREENTAB3
    -D TFT_WIDTH=128
    -D TFT_HEIGHT=128
    -D TFT_MOSI=23
    -D TFT_SCLK=18
    -D TFT_DC=2
    -D TFT_RST=4
    -D TFT_CS=-1
    -D LOAD_GLCD
    -D LOAD_FONT2
    -D LOAD_FONT4
    -D LOAD_FONT6
    -D LOAD_FONT7
    -D LOAD_FONT8
    -D LOAD_GFXFF
    -D SMOOTH_FONT
    -D SPI_FREQUENCY=27000000
    -D SPI_READ_FREQUENCY=20000000

Note: Adjust the pin numbers (TFT_MOSI, TFT_SCLK, TFT_DC, TFT_RST) to match your hardware wiring.

Configure Input (Optional for First Project)

If you have buttons connected, note the GPIO pins. For now, we'll create a project that works without input.

Configure Audio (Optional for First Project)

Audio is optional for the first project. We'll add it later.

Step 4: Create Your First Scene

Create a new file src/MyFirstScene.h:

#pragma once
#include <core/Scene.h>
#include <graphics/Renderer.h>
#include <graphics/Color.h>

class MyFirstScene : public pixelroot32::core::Scene {
public:
    void init() override {
        // Called when the scene is initialized
        // Set up your scene here
    }

    void update(unsigned long deltaTime) override {
        // Called every frame
        // Update game logic here
        Scene::update(deltaTime); // Don't forget to call parent update!
    }

    void draw(pixelroot32::graphics::Renderer& renderer) override {
        // Called every frame to draw
        // Draw your scene here

        // Example: Draw a simple rectangle
        renderer.drawFilledRectangle(50, 50, 100, 100, pixelroot32::graphics::Color::Blue);

        // Example: Draw text
        renderer.drawText("Hello PixelRoot32!", 20, 20, pixelroot32::graphics::Color::White, 2);

        // Don't forget to call parent draw to draw all entities!
        Scene::draw(renderer);
    }
};

Step 5: Create Main File (ESP32)

Replace the contents of src/main.cpp with:

#include <Arduino.h>
#include <core/Engine.h>
#include <drivers/esp32/TFT_eSPI_Drawer.h>
#include <drivers/esp32/ESP32_DAC_AudioBackend.h>
#include "MyFirstScene.h"

namespace pr32 = pixelroot32;

// Audio configuration (optional - can be omitted for first project)
const int DAC_PIN = 25; // GPIO 25 or 26
pr32::drivers::esp32::ESP32_DAC_AudioBackend audioBackend(DAC_PIN, 11025);

// Display configuration
// ST7789, rotation 0, 240x240 resolution
pr32::graphics::DisplayConfig displayConfig(
    pr32::graphics::DisplayType::ST7789, 
    0,      // rotation
    240,    // width
    240     // height
);

// Input configuration (6 buttons: UP, DOWN, LEFT, RIGHT, A, B)
// For now, we'll use dummy pins - you can change these later
pr32::input::InputConfig inputConfig(
    6,      // button count
    32,     // UP pin
    27,     // DOWN pin
    33,     // LEFT pin
    14,     // RIGHT pin
    13,     // A button pin
    12      // B button pin
);

// Audio configuration
pr32::audio::AudioConfig audioConfig(&audioBackend, audioBackend.getSampleRate());

// Create the engine
pr32::core::Engine engine(displayConfig, inputConfig, audioConfig);

// Create your scene
MyFirstScene myScene;

void setup() {
    Serial.begin(115200);

    // Initialize the engine
    engine.init();

    // Initialize and set the scene
    myScene.init();
    engine.setScene(&myScene);

    Serial.println("PixelRoot32 initialized!");
}

void loop() {
    // Run the game loop
    engine.run();
}

Step 6: Create Native Version (Optional)

If you want to test on PC first, create src/main_native.cpp:

#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>
#include <core/Engine.h>
#include <drivers/native/SDL2_Drawer.h>
#include <drivers/native/SDL2_AudioBackend.h>
#include "MyFirstScene.h"

namespace pr32 = pixelroot32;

// Audio configuration
pr32::drivers::native::SDL2_AudioBackend audioBackend(22050, 1024);

// Display configuration (NONE defaults to SDL2 on Native)
pr32::graphics::DisplayConfig displayConfig(
    pr32::graphics::DisplayType::NONE,
    0,      // rotation
    240,    // width
    240     // height
);

// Input configuration (SDL scancodes)
pr32::input::InputConfig inputConfig(
    6,                      // button count
    SDL_SCANCODE_UP,        // UP
    SDL_SCANCODE_DOWN,      // DOWN
    SDL_SCANCODE_LEFT,      // LEFT
    SDL_SCANCODE_RIGHT,     // RIGHT
    SDL_SCANCODE_SPACE,     // A button
    SDL_SCANCODE_RETURN     // B button
);

// Audio configuration
pr32::audio::AudioConfig audioConfig(&audioBackend, 22050);

// Create the engine
pr32::core::Engine engine(displayConfig, inputConfig, audioConfig);

// Create your scene
MyFirstScene myScene;

int main(int argc, char* argv[]) {
    (void)argc;
    (void)argv;

    // Initialize the engine
    engine.init();

    // Initialize and set the scene
    myScene.init();
    engine.setScene(&myScene);

    // Run the game loop
    engine.run();

    return 0;
}

Configure Native Build

Add to platformio.ini:

[env:native]
platform = native
build_src_filter = 
    +<*>
    -<main.cpp>
lib_extra_dirs = lib
build_flags = 
    -D PLATFORM_NATIVE
    -Isrc
    -Ilib/PixelRoot32-Game-Engine/include
    -IC:/msys64/mingw64/include/SDL2    # Windows MSYS2 path - adjust for your system
    -LC:/msys64/mingw64/lib             # Windows MSYS2 path - adjust for your system
    -O2
    -Wall
    -Wextra
    -std=c++17
    -lSDL2
    -mconsole

Note: Adjust the SDL2 include and library paths for your system.

Step 7: Build and Run

For ESP32

  1. Connect your ESP32 via USB
  2. Select the environment: Click on the PlatformIO icon → Select env:esp32dev
  3. Build: Click the checkmark icon (✓) or press Ctrl+Alt+B
  4. Upload: Click the arrow icon (→) or press Ctrl+Alt+U
  5. Monitor: Click the plug icon to open serial monitor

You should see "PixelRoot32 initialized!" in the serial monitor and your display should show a blue rectangle and text.

For Native (PC)

  1. Select the environment: Click on the PlatformIO icon → Select env:native
  2. Build and Run: Click the play icon (▶) or press Ctrl+Alt+R

A window should open showing your scene with a blue rectangle and "Hello PixelRoot32!" text.

Step 8: Verify It Works

If everything is set up correctly, you should see:

  • ESP32: Display shows a blue rectangle at (50, 50) and white text "Hello PixelRoot32!" at (20, 20)
  • Native: Window shows the same content

If you see this, congratulations! Your first PixelRoot32 project is working.

Troubleshooting

ESP32 Issues

Display is blank: - Check wiring connections - Verify pin numbers in platformio.ini match your hardware - Check SPI frequency (try lowering it) - Verify display type (ST7789 vs ST7735)

Compilation errors: - Ensure library version is exactly 0.2.0-dev - Check that TFT_eSPI is installed - Verify all include paths are correct

Upload fails: - Check USB cable connection - Try different USB port - Press BOOT button on ESP32 during upload - Check COM port in PlatformIO

Native Issues

SDL2 not found: - Verify SDL2 is installed - Check include/library paths in platformio.ini - On Windows, ensure MSYS2 paths are correct

Window doesn't open: - Check console for error messages - Verify SDL2 is properly linked - Try running from terminal to see errors

Next Steps

Now that you have a working project, you can:

  1. Learn about Scenes and Entities: See how to create game objects
  2. Add Input: Make your scene respond to buttons
  3. Add Sprites: Draw custom graphics
  4. Add Audio: Play sounds and music

Continue with the Development Guide to learn more.


See also: - Fundamental Concepts - Installation - Manual - Scenes and Entities - API Reference