Start

Theory

Reference

Examples

← All examples
Rendering · Input

Moving Box

The smallest playable game

The example linked from the project README's own quick-start: a single WASD-controlled box drawn with IRenderer::DrawRect.

It's deliberately minimal — one entity, no ECS, no assets — to show the shortest path from Application<TGame> to something on screen that responds to a player.

Controls

  • W A S D Move the box
RenderingInput
Moving Box screenshot

Run it yourself

build just this example
cmake --build --preset windows-debug --target moving_box
# binary lands under bin/ (e.g. bin/Debug/moving_box.exe on Windows)

See Installation for the full build setup.

Source

examples/moving_box/MovingBox.hpp
#pragma once

#include <ASGE/ASGE.hpp>

class MovingBox
{
    asge::math::Float2 m_Position{ asge::math::Float2::Zero() };
    asge::math::Float2 m_Dimension{ 50.0f, 50.0f };

    float m_Speed{250.0f};
    bool  m_Up{false};
    bool  m_Down{false};
    bool  m_Left{false};
    bool  m_Right{false};
public:
    void Update(float inDeltaTime);
    void Render(asge::video::IRenderer& inRender);
    void OnKeyboardEvent(asge::event::KeyboardEvent const& inKeyEvent);
};
examples/moving_box/MovingBox.cpp
#include "MovingBox.hpp"

void MovingBox::Update(float inDeltaTime)
{
    auto dir = asge::math::Float2::Zero();

    if (m_Left)  dir.x() -= 1.0f;
    if (m_Right) dir.x() += 1.0f;
    if (m_Up)    dir.y() -= 1.0f;
    if (m_Down)  dir.y() += 1.0f;

    m_Position += dir * m_Speed * inDeltaTime;
}

void MovingBox::Render(asge::video::IRenderer &inRender)
{
    inRender.DrawRect(
        asge::math::Rect{ m_Position.x(), m_Position.y(), m_Dimension.x(), m_Dimension.y() },
        {255, 0, 0, 255},
        true
    );
}

void MovingBox::OnKeyboardEvent(asge::event::KeyboardEvent const &inKeyEvent)
{
    bool pressed = inKeyEvent.s_Type == asge::event::EventType::KEYBOARD_KEY_PRESSED;

    switch (inKeyEvent.s_Keycode)
    {
    case asge::input::Keycode::W: m_Up = pressed; break;
    case asge::input::Keycode::S: m_Down = pressed; break;
    case asge::input::Keycode::A: m_Left = pressed; break;
    case asge::input::Keycode::D: m_Right = pressed; break;
    default: break;
    }
}
examples/moving_box/MovingBoxGame.cpp
#include "MovingBoxGame.hpp"

std::optional<asge::game::state::Transition<int>>
MovingBoxState::Update(float inDeltaTime, [[maybe_unused]] asge::input::InputState const& inInput)
{
    m_Box.Update( inDeltaTime );
    return std::nullopt;
}

void MovingBoxState::Render(asge::video::IRenderer &inRenderer)
{
    inRenderer.Clear({ 0, 0, 0, 255 });
    m_Box.Render( inRenderer );
}

void MovingBoxState::OnSystemEvent(asge::event::SystemEvent const &inSysEvent)
{
    auto const* keyEvent = inSysEvent.TryGet<asge::event::KeyboardEvent>();
    if (!keyEvent) return;
    m_Box.OnKeyboardEvent( *keyEvent );
}

MovingBoxGame::MovingBoxGame(asge::video::IRenderer& inRenderer, asge::audio::AudioDevice& inAudioDev)
: Game(inRenderer, inAudioDev)
{
    SetInitialState(0);
}

std::unique_ptr<MovingBoxGame::StateType> MovingBoxGame::CreateState([[maybe_unused]] int inId)
{
    return std::make_unique<MovingBoxState>();
}

Browse the full example on GitHub →