A Rayve program consists of objects for the engine, scenes, overlays and entities. Example code for each is given below as a starting point. See the reference section for documentation of individual objects and methods used in the examples.
PO2B = Rayve's power-of-2 buffered memory.
// Create the windows main entry point function.
void WinMain()
{
// The API must be created first.
API api(L"Raylogic", L"Lab");
// Exit codes control the program flow between scenes.
int exitCode = 2;
// Create the engine after the API is created.
Engine engine;
// Set any desired engine parameters before the engine is started.
engine.SetWindow(L"Lab", .5f, 0, 0, EngCfg::WINDOW_BORDERLESS);
engine.SetProbeMode(EngCfg::ProbeMode::METRICS);
engine.SetNormMapRange(30);
// Start the engine. The main window should open if the engine started successfully.
engine.Start();
// The exit code directs the engine to the next scene or to the end the program.
while (exitCode > 0)
switch (exitCode)
{
case 1:
// Create a scene using PO2B syntax.
new (engine.AllocScene()) Title::Scene;
// Access the created scene using the predfined global SCN().
// When a scene is run, the engine has control of execution until a non-zero exit code is set.
exitCode = SCN().Run();
break;
case 2:
// A new scene was requested by the previous scene.
new (engine.AllocScene()) GameLevel::Scene;
// Run the new scene
exitCode = SCN().Run();
break;
}
// A negative exit code was received and the program exits.
// C++ will release the Rayve objects declared in this function in
// the reverse order they were created, enabling a clean shutdown.
}
// Recommend keeping all objects related to a game level in their own namespace.
namespace MyGameLevel
{
// Define a scene class for the game level by subclassing the Ravye scene class.
class Scene : public Rayve::Scene
{
public:
// Constructor for the scene.
Scene();
// Destructor for the scene. Override the base Rayve scene class destructor.
~Scene() override;
protected:
// OnBgnUpd() is called each frame before entity updates begin.
void OnBgnUpd() override;
// OnEndUpd() is called each frame after entity updates end.
void OnEndUpd() override;
private:
// This scene class is using logic states.
RVSTATEFUNCS(Scene);
// A state used by the scene to wait on the title overlay.
void OnWaitTitle();
// A state used by the scene for normal scene processing.
void OnDefault();
};
}
// The namespace this scene belongs to.
namespace MyGameLevel
{
// Scene calls this for each entity during first update pass.
void Scene::OnBgnUpd()
{
// Any global logic outside of states can go here.
// Run current state.
RVBGNUPDSTATE;
}
// This state waits on the title overlay to exit.
void Scene::OnWaitTitle()
{
// Wait until overlay indicates an exit.
if (OVL().GetExitCode() > 0)
{
// Delete the title overlay and create the game overlay using PO2B syntax.
new (AllocOverlay()) Overlay();
// Redirect updates to the OnDefault() state.
SetBgnUpdState(&Scene::OnDefault);
// Don't show the cursor in the game scene.
Input::ShowCursor(false);
// Want to see probe metrics.
EnableProbe();
}
}
// Normal game scene logic.
void Scene::OnDefault()
{
// If escape is pressed, switch to title overlay.
if (Input::PopKey(Key::ESCAPE))
{
// Show cursor in overlay.
Input::ShowCursor();
// Don't show probe in overlay.
EnableProbe(false);
// Create title overlay using PO2B syntax.
new (AllocOverlay()) Title::Overlay(true);
// Redirect updates to OnWaitTitle() state.
SetBgnUpdState(&Scene::OnWaitTitle);
}
}
// Scene constructor.
Scene::Scene()
// Set parameters for the static and dynamic entity lists provided by the scene.
: Rayve::Scene(640, 64, 1024, 16)
{
// Clear all current assets. Don't clear if assets are shared between scenes.
Assets::Clear();
// Synchronously load assets from specific directories in the data folder.
// For big scenes with longer load times, asset loading can be done in an
// overlay prior to creating a scene. The overlay can be coded to load
// assets asynchronously while showing progress to the player, then start
// the scene using an exit code.
Assets::Load(L"common");
Assets::Load(L"title");
Assets::Load(L"gamestuff");
// This must always be called after assets are loaded. Don't forget :)
Finalize();
// Create the game overlay using PO2B syntax.
new (AllocOverlay()) Overlay;
// Want to see probe metrics in game.
EnableProbe();
// Don't show the cursor.
Input::ShowCursor(false);
// Using lights in the scene, so need to create the light grid.
SetLightGrid(100, 30, 100, 10, 1, 10, 0, 25, 0);
// Load the background sky box.
ShowSkybox(L"thesky");
// Create an entity that contains a camera using PO2B syntax.
new (GetDynamicEntities().Add()) Base::Camera(M4fTrans(0, 2, 9));
// Create an entity that contains a light using PO2B syntax.
new (GetStaticEntities().Add()) Base::Light(M4fTrans(20, 20, 20));
// Create an entity that contains a character mesh and a sound using PO2B syntax.
new (GetStaticEntities().Add()) Player(M4fIdent());
// Direct updates to the OnDefault() state.
SetBgnUpdState(&Scene::OnDefault);
}
// Destructor for the scene.
Scene::~Scene()
{
}
}
// The namespace this overlay belongs to.
namespace MyOverlayNamespace
{
// Derive an overlay class from the Rayve overlay class.
class Overlay : public Rayve::Overlay
{
public:
// Constructor.
Overlay();
// Override destructor from base class.
~Overlay() override;
protected:
// OnBgnUpd() is called in the first update pass when display is opened or resized.
void OnBgnUpd();
// OnEndUpd() is called in the second update pass in reverse entity order.
void OnEndUpd();
private:
// This overlay class is using logic states.
RVSTATEFUNCS(Overlay);
// A state reserved for future use.
void OnBgnUpdDefault();
// Declare state for future use.
void OnEndUpdDefault();
};
}
// The namespace this overlay belongs to.
namespace MyOverlayNamespace
{
// Called on first pass of overlay update. This only gets called when scene needs to be redrawn.
// Put drawing logic here.
void Overlay::OnBgnUpd()
{
// Any global logic outside of states can go here.
// Run current state.
RVBGNUPDSTATE;
}
// Called on second pass of overlay update. This gets called every frame. Put UI event handling logic here.
// OnEndUpd is called in reverse entity order. This causes sub entities to be updated before super entities,
// which causes overlaying UI entities to be updated before underlying UI entities.
void Overlay::OnEndUpd()
{
if (Input::PopKey(Key::ESCAPE))
SetExitCode(1);
// Run current state.
RVENDUPDSTATE;
}
// State not implemented yet.
void Overlay::OnBgnUpdDefault() {}
// State not implemented yet.
void Overlay::OnEndUpdDefault() {}
// Constructor.
Overlay::Overlay()
// Set parameters for the dynamic entity list provided by the overlay.
: Rayve::Overlay(512, 8)
{
// Create an entity that contains multiple resolution independent background images using PO2B syntax.
new (GetEntities().Add()) Backdrop;
// Create an entity using PO2B syntax that manages custom menus.
new (GetEntities().Add()) Menus(S2f(.86f, .57f), L"fontname", escape);
// Call BgnUpd() on this overlay to force a redraw of the overlay elements after they have been added.
BgnUpd();
}
// Destructor.
Overlay::~Overlay()
{
// This overlay changes display visuals, so the visual changes
// need to be invoked before the overlay object is destroyed.
Visuals::Invoke();
}
}
// The namespace this entity belongs to.
namespace MyGameLevel
{
// Derive player class from Rayve entity class.
class Player : public Rayve::Entity
{
public:
// Expecting collision shape so this function was created to receive collsion shape.
void AddCollShape(const CollShape &shape) { body.AddCollShape(shape); }
// Constructor.
Player(wcstr name, const M4f &pos);
// Override destructor from base class.
~Player();
protected:
// OnBgnUpd() is called each frame before forward iteration through the entities begins.
void OnBgnUpd() override;
private:
// This entity class is using logic states.
RVSTATEFUNCS(Player);
// Mesh component.
Mesh mesh;
// Physics component.
Body body;
};
}
// The namespace this entity belongs to.
namespace MyGameLevel
{
// Called by scene each frame on first update pass. Not the way a player would normally be moved,
// but is just a contrived example to show basic entity logic.
void Player::OnBgnUpd()
{
Move player forward.
if (Input::IsKey(Key::UP))
body.ApplyForce(S3f(0, 0, -5000));
Move player backward.
if (Input::IsKey(Key::DOWN))
body.ApplyForce(S3f(0, 0, 5000));
Move player left.
if (Input::IsKey(Key::LEFT))
body.ApplyForce(S3f(5000, 0, 0));
Move player right.
if (Input::IsKey(Key::RIGHT))
body.ApplyForce(S3f(-5000, 0, 0));
// This code is a very important example to show that components do not automatically work together.
// All components must be managed through connecting logic as the code below shows.
// Set the mesh position to the body position. Body position is automatically updated each frame.
mesh.SetPos(body.GetPos());
// Update the mesh position in the scene using the scene global SCN().
SCN<GameScene>().UpdateGeometry(mesh);
// This normally calls current forward state, but no state is defined, so call is ignored.
RVBGNUPDSTATE;
}
// Constructor.
Player::Player(wcstr name, const M4f &pos)
// Component parameters are given here.
: mesh(GetKey(), name, pos), body(GetKey(), Body::Type::DYNAMIC, pos)
{
// Set mass.
body.SetProps(.25f);
// Set linear damping.
body.SetLinDamp(S3f(2));
// Important! Components are not automatically added to the scene.
SCN().AddGeometry(mesh);
}
// Destructor.
Player::~Player()
{
// Important! Components are not automatcally removed from the scene.
SCN().RemoveGeometry(mesh);
}
}