2
\$\begingroup\$

I want to know of some different ways to implement cutscenes in a 2D RPG game with SDL2 and C++.

My current idea is creating different functions in different files for different cutscenes and running them whenever I need to show a cutscene.

However, this doesn't seem like a very easy or simple way to render cutscenes. How would I effeciently implement cutscenes?

\$\endgroup\$
  • \$\begingroup\$ I've removed your second question since it's off-topic here. \$\endgroup\$ – Tyyppi_77 Dec 15 '17 at 14:03
  • 1
    \$\begingroup\$ Asking for "some different ways" is pretty broad. Can you edit your question & try narrowing this down to a particular set of needs & criteria that a proposed solution should meet? \$\endgroup\$ – DMGregory Dec 15 '17 at 15:03
2
\$\begingroup\$

I personally implemented a cutscene "scripting" language for my cutscenes using XML. XML isn't necessarily the best choice, and since it's not a real scripting language with programming language features, it can be a little limiting, but for my needs it worked just fine.

My cutscene definition files look like this:

<CutScene disableBars="1" replayOnRestart="1">
    <Parallel>
        <CameraTarget tag="Bomb" time="1.0"/>
        <DelayExecution time="0.4">
            <CameraZoom zoom="4.0" time="0.6"/>
        </DelayExecution>
    </Parallel>
    <Wait time="5.0"/>
    <WaitForKey/>
</CutScene>

When I want to display a cutscene, I create a cutscene object, that is updated and rendered from my level class.

The cutscene object loads the file, and converts each XML element into an instruction, that gets updated. Only the current instruction gets executed, which is why a Parallel instruction exists. The instructions let the cutscene object know when the next instruction can be executed.

The instruction loading might look something like this (pseudo-C++):

void CutScene::Load()
{
    XMLFile* file = new XMLFile(...);

    for (XMLElement* element : file->GetElement("CutScene")->Children)
    {
        m_Instructions.push_back(InstructionFactory::Create(element));
    }
}

Instruction* InstructionFactory::Create(XMLElement* element)
{
    if (element->Name == "CameraTarget")
    {
        std::string tag = element->GetStringAttribute("tag");
        float time = element->GetFloatAttribute("time");

        return new CameraTargetInstruction(tag, time);
    }

    ...
}

I use tags to reference entities in the level, so I have set the name of the bomb-entity in the level editor to "Bomb", and I use that same string to tell the camera zoom target instruction to center on the correct entity.

Creating cutscenes in a neat way can be a pain and a lot of work, but with a data-based approach like mine, you can improve your content interation speed, since you don't have to recompile every time you want to change the way a cutscene plays out.

You could of course look into integrating something like Lua into your framework/engine, but that can be a lot of work too.

The fastest approach to code might be just pure C++ code, but you'll get faster iteration speed with a data-based approach, and using a full-fledged scripting language will get you fast iteration speed and a lot of flexibility.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I like your approach but since I don't know much about XML, I didn't understand this converts each XML element into an instruction, that gets updated. Only the current instruction gets executed, which is why a Parallel instruction exists. How would I convert it? \$\endgroup\$ – Ashar7 Dec 15 '17 at 14:41
  • \$\begingroup\$ You'd use an XML parser library, line TinyXML or RapidXML. The parser allows you to iterate over the elements in an XML file, and get the element names/parameters. Then I'd convert the parameters to correct types, and construct an instruction element. I'll add some pseudo-code to the answer. \$\endgroup\$ – Tyyppi_77 Dec 15 '17 at 14:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.