First GameObject
This page walks you through creating your first moving, visible game object from scratch in WolfEngine.
If you want a quick overview of the folder layout, main.cpp, and the startup sequence before diving into code, see Engine Basics.
The Basics
Every game entity in WolfEngine is a GameObject. You create one by inheriting from it and overriding Start() and Update():
#include "WolfEngine/WolfEngine.hpp"
class MyObject : public GameObject {
public:
void Start() override {
// called once when the object is created
transform.position = { 64, 64 };
}
void Update() override {
// called every frame
}
};
Then create it in app_main() before StartGame():
Engine().StartEngine();
GameObject::Create<MyObject>();
Engine().StartGame();
That's it â the engine handles the rest.
Tip: Refer to GameObject to better understand how GameObjects work.
Tip: Refer to Engine to better understand engine initialization.
Adding Movement
Get a controller reference in Start() and read input in Update():
class MyObject : public GameObject {
public:
Controller* controller = nullptr;
void Start() override {
controller = Input().getController(0); // player 1
}
void Update() override {
if (!controller) return;
if (controller->getButton<Button::A>()) transform.position.x += 1;
if (controller->getButton<Button::B>()) transform.position.x -= 1;
if (controller->getButton<Button::C>()) transform.position.y -= 1;
if (controller->getButton<Button::D>()) transform.position.y += 1;
}
};
Or use the joystick for analog movement:
void Update() override {
if (!controller) return;
transform.position.x += controller->getAxis(JoyAxis::X) * 2.0f;
transform.position.y += controller->getAxis(JoyAxis::Y) * 2.0f;
}
Tip: Refer to Input to better understand how input handling works.
Adding a Sprite
First define pixel data and create a Sprite asset in flash, then attach a SpriteRenderer component. If you are using the asset pipeline, you can skip the manual pixel array and include the generated GeneratedAssets/WE_Assets.hpp header instead.
Sprite pixel arrays use [H][W] shape (rows à columns). W and H can be different, and each must be in 1..96.
Pixel data must be declared as a separate constexpr array â inline initializer lists are not supported.
#include "WolfEngine/WolfEngine.hpp"
constexpr uint8_t myPixels[7][7] = {
{0, 0, 1, 1, 1, 0, 0},
{0, 1, 1, 1, 1, 1, 0},
{0, 1, 2, 1, 2, 1, 0},
{0, 1, 1, 1, 1, 1, 0},
{0, 1, 2, 1, 2, 1, 0},
{0, 1, 1, 2, 1, 1, 0},
{0, 0, 1, 1, 1, 0, 0},
};
constexpr Sprite MY_SPRITE = Sprite::Create(myPixels, PALETTE_WARM);
class MyObject : public GameObject {
public:
SpriteRenderer spriteRenderer = SpriteRenderer(this, &MY_SPRITE, RenderLayer::Player);
Controller* controller = nullptr;
void Start() override {
transform.position = { 64, 64 };
controller = Input().getController(0);
}
void Update() override {
if (!controller) return;
if (controller->getButton<Button::A>()) transform.position.x += 1;
if (controller->getButton<Button::B>()) transform.position.x -= 1;
}
};
The sprite anchor draws at transform.position every frame automatically. By default this anchor is centered (W/2, H/2).
0 in pixel data is always transparent. Indices 1â31 map to palette colors. Generated sprites follow the same rule, so the Assets namespace produced by the converter is drop-in compatible with manual Sprite::Create() usage.
Tip: Refer to Sprite Renderer to better understand how sprites work.
Full Example â A Moving Player
#include "WolfEngine/WolfEngine.hpp"
constexpr uint8_t playerPixels[7][7] = {
{0, 0, 1, 1, 1, 0, 0},
{0, 1, 1, 1, 1, 1, 0},
{0, 1, 2, 1, 2, 1, 0},
{0, 1, 1, 1, 1, 1, 0},
{0, 1, 2, 1, 2, 1, 0},
{0, 1, 1, 2, 1, 1, 0},
{0, 0, 1, 1, 1, 0, 0},
};
constexpr Sprite SPRITE_PLAYER = Sprite::Create(playerPixels, PALETTE_GRAYSCALE);
class Player : public GameObject {
public:
SpriteRenderer spriteRenderer = SpriteRenderer(this, &SPRITE_PLAYER, RenderLayer::Player);
Controller* controller = nullptr;
void Start() override {
transform.position = { 64, 64 };
controller = Input().getController(0);
}
void Update() override {
if (!controller) return;
float speed = 2.0f;
transform.position.x += controller->getAxis(JoyAxis::X) * speed;
transform.position.y += controller->getAxis(JoyAxis::Y) * speed;
}
};
extern "C" void app_main() {
Engine().StartEngine();
GameObject::Create<Player>();
Engine().StartGame();
}
What's Next
| ⊠Engine Settings | Configure frame rate, background color, and UI region |
| đ Pin Setup | Set up your GPIO and SPI wiring |
| đ°ī¸ About GameObjects | Learn everything about GameObjects |
| đŽ Inputs! | How to get inputs from the controllers? |
| đ Your First Game Object! | Learn how to create and move objects |
| đ¨ How To Set Up Graphics? | Get graphics on screen |
| đ How to pew pew? | Make the buzzer go brr |