Games and Scenes - NocturnalWisp/Tynted-Engine GitHub Wiki

Usage

Both the Game and Scene classes are utilized to organize the game into its various components. The game differs in that it controls the whole game, each scene control "mini" games.

Game

The game class has 4 main functions that you will utilize. The best way to use the game class is to create your own custom class, and inherit directly from it. That way all of the override functions will be available to you.

Run

The run function is used only once in a program. Often placed in the Program.cs file, this function initializes each of the games initial functions, and starts the main loop that will run until the game is closed. The main feature of the game is the RenderWindow from the SFML library. All draw functions, and various other things are built off of the SFML window.

Initialize

The initialize function enables you to run setup for your game. If you need to reset the game, often just calling the initialize should be enough. This is where you create each of the scene, entities, systems, and components.

This function also initializes the input and various other ECSManager functions that require it.

Update

This overridable function is processed each time the loop is iterated over. It happens before the draw, and loops until the game stops. The update function also updates all of the scenes that have been created. It accepts one perimeter being of type GameTime. Game time will help you track the time between frames (elapsedTime.) It will also help with the total game time since starting (totalTime.)

Utilize it when you need to run certain functions ever frame, but it honestly doesn't need to be used with the ECS pattern utilizing systems.

Draw

The draw function, like the update function, is often unimportant unless for quick testing purposes. It takes in one perimeter, the RenderWindow. This allows for drawing directly to the window. It handles drawing scenes and other various drawing methods across the engine.

Suggestions

You should only be utilizing the game class to initialize all the various scenes, entities, systems, and components. Any of the other functions should be used across those various groupings.

I highly recommend running the game this way, as it is this quickest and easiest to setup:

using (YourGameClass game = new YourGameClass(GameOptions.Default))
{
    game.Run();
}

Scene

The scene is technically not needed to create and run a game, but it is highly recommended as the functionality makes the process of iterative design quicker, and easier. To create a scene, you do not need to create a custom class to inherit from it, (though you could if you so required) in fact, the best way to implement a scene is to create a json file in the scene format. This format is outlined later on this page.

Functions

The scene has the 3 main functions the game has, that is Initialize, Update, and Draw. It also has one very important constructor. This constructor accepts 3 arguments:

  1. scene - This is the path or the name of the scene depending on the chosen option of the next argument.
  2. isPath - If this is true, it will search for a json file at the specified path "scene" argument. If false, it will just create a new empty scene with the name of the "scene" argument.
  3. variables - This argument is used only if the isPath argument is true; you can set it to null otherwise. This is where you set the variables that the json can utilize with the "@" sign. You will find out more about it below.

Json Scenes

The best way to start using json files to create a scene is to see an example:

{
    "version": 0.1,
    "name": "Demo",

    "entities": [
        {
            "name": "Test",
            "tag": "",
            "components": {
                "Transform": [ "@pos", 0, "@scale" ]
            }
        },
        {
            "name": "Player",
            "tag": "Player",
            "components": {
                "Transform": [ "@playerPos", 0, "@playerScale" ],
                "SpriteRenderee": [ "@playerTexture" ]
            }
        },
        {
            "name": "Fsh",
            "tag": "",
            "template": {
                "name": "Sprite",
                "args": [ "@fshTexture" ]
            }
        },
        {
            "name": "Player Clone",
            "tag": "Player",
            "clone": "Player"
        }
    ]
}

So there are many things happening here, but there are three main important tags you should pay attention to: version, name, and entities. Each of these tags help to make up the scene.

  • version - the version of the json file, and the engine will determine what values should be in it based on the version of the file, and the engine.
  • name - pretty obvious.
  • entities - The list of entities the scene has.

entities, as said previously, is an array of all the entities you would would like to add to the scene. Arrays in json are denoted by "[]" square brackets. Each entity has two important tags, and one optional.

  • name - The name of the entity.
  • tag - the tag you would like to assign to an entity. Empty for none. Choices:
  • components - This is for specifying which components you would like the entity to start with.
    • components array - specify comma separated arrays which have a name tag as the key, (the name of the component case-sensitive) and an array of parameters.
    • parameters - this array is a list of values of various types that the component accepts in it's constructor. You can have strings, numbers, and variables. Variables are very important for objects, because you cannot place them in the Json. You define variables when you create the scene in the variables parameter. One drawback of using this in a scene, is you must specify all the arguments including the optional ones, otherwise you will get a Could not create entity with component error.
  • template - This is for creating an entity from a pre-made template.
    • name - The name of the template to create from. (look at the link above for specifics) If this is invalid, it won't create an entity.
    • args - This is the specific arguments the template takes in, also look at the link above.
  • clone - This clones an object in the scene referenced by its name.

Scene Manager

In order to actually use a scene, you need to load it into the SceneManager. The SceneManager controls every single scene in various ways.

The Static Scene

The one abstract principle of the SceneManager is the "static scene." The static scene is basically one scene that runs in the background at all points in time that the game is running. All entities that are created without the scene name specified are placed in this "scene." This "scene" is never destroyed, and you can think of it as persistent entities when scenes are destroyed or moved around.

Functions

There are a couple functions to be able to load, unload, and work with scenes:

  • LoadScene - Accepts a scene and loads it, this also unloads every other scene.
  • LoadSceneOnTop - Accepts a scene and loads it, but also keeps all other scenes loaded.
  • UnloadScene - Accepts either a scene object, or a scene name and looks for it to unload it.
  • UnloadAllScenes - Unloads all the scenes.
  • PauseScene - Prevents all systems from running on any entities in that scene.
  • ResumeScene - Resumes any running in that scene.
  • SceneExists - returns if the scene is loaded.
  • GetSceneByName - returns a scene object by its name.