Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Nero Game Engine  (Read 134390 times)

0 Members and 1 Guest are viewing this topic.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Re: Nero Game Engine
« Reply #45 on: March 12, 2018, 08:30:32 am »
You should definitely think about putting together an SDK that interested users can just download and which can be used to start developing right away.

NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #46 on: March 13, 2018, 02:20:33 pm »
Hi @Tank, thank for your reply.

I know the build and installation process maybe challenging, this is why I decided to add a scripting language at the final stage of the project. I didn't thought about a SDK, it's a great idea you have here. thank you !

By the end of the week, I'll provide a Kit fully Setup, the Kit will contains a CodeBlocks installation and a MinGW compiler fully configure.

NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #47 on: March 19, 2018, 02:05:46 pm »
Nero Game Engine Startup Kit

Hi every how are you doing !

The kit is now ready, you can download it with the link bellow. The kit works like a Codeblocks standalone installation. you can carry it in a USB key and launch it wherever you want. It uses a 32 bits MinGW compiler, so it should run on any Windows System.

Downlaod Nero Game Engine Kit

The Kit already contains two projects. One call "Test" that you can use as you want, and another call "Kero", I will talk about this one later.

The content of the Kit is as bellow

CodeBlocks/                  CodeBlocks and MinGW installation
Library/                  All the necessary headers, dlls and libs
Projects/                  All your projects should be created in this folder
Resource Pack/               A set of Textures and Fonts
Readme                     A readme file
Start                     Double click on this one to start CodeBlock;

There is nothing to configure, every new project has automatically access to the engine API

When you create a new project, there is only one thing to do. The Engine expect the "config/" and "Resource/" directories to be availabed. So don't forget to add them. You can simply copy the ones in the "Test" project in your New project directory.
« Last Edit: May 06, 2022, 04:18:03 pm by NeroGames »

NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #48 on: March 24, 2018, 08:48:19 am »
Developing Games with the Engine 101

Hi everyone how are you doing :), In this post we'll see how to start programming with the Engine

1- Create a new Scene

In order to create a new Scene, you simply have to create a new Class inherating from nero::Scene. After that you can add  your scene to the Engine with the method [ addScene<Scene_Class>("scene_name") ]. you can add any number of Scenes.

Pay attention to the scene name, the name will be used to generate a directory for your scene, So the characters you can enter there depends on your Operating System rules in term of Folder and File Name.

The Engine Instantiate your Scene each time you click on the Play_Button.

#include <NERO/engine/DevEngine.h>

class MyScene : public nero::Scene
{
    public:
        MyScene(nero::Scene::Context context):
            nero::Scene(context)
        {
            nero_log("Hello bodies");
        }
};

int main()
{
    nero_log("Nero Game Engine Hello World");

    nero::DevEngine engine;
    engine.addScene<MyScene>("My Scene");
    engine.run();
}
 

2- The init() method

The init() method is called automaticlly after the constructor of your Scene, This method exist in order to allow doing stuff that can't be done in the construstor. It's in this method that you can retrieve objects, preconfigure your player, your scene logic etc.

Using the Dev_Engine Interface, first create an Object named "test" before to run the bellow code.

#include <NERO/engine/DevEngine.h>

class MyScene : public nero::Scene
{
    public:
        MyScene(nero::Scene::Context context):
            nero::Scene(context)
        {
            nero_log("Hello bodies");
        }

        void init()
        {
            nero_log("the init() method is called automatically after the constructor");

            //Create a mesh object and give it the name "test" before to run this code
                auto object = m_ObjectManager.findObject("test");

                nero_log(_sn(object));

            // the little "_sn" is a toString method; the "s" is for String, the "n" is for Nero Object
        }
};

int main()
{
    nero_log("Nero Game Engine Hello World");

    nero::DevEngine engine;
    engine.addScene<MyScene>("My Scene");
    engine.run();
}
 

3- Run the Render_Engine

In order to launch the Render_Engine, simply replace the DevEngine header by the RenderEngine one [ #include <NERO/engine/RenderEngine.h> ], and then change the code in the main like bellow.

The Render_Engine takes only one Scene, so it use the method [ setScene<Scene_Calss>("scene_name") ]

The Render_Engine run a 800 x 600 window by default, you can change that by modifying its constructor like that
[ nero::RenderEngine engine("default name", 1024.f, 600.f) ]

#include <NERO/engine/RenderEngine.h>

class MyScene : public nero::Scene
{
    public:
        MyScene(nero::Scene::Context context):
            nero::Scene(context)
        {
            nero_log("Hello bodies");
        }

        void init()
        {
            nero_log("the init() method is called automatically after the constructor");

            //Create a mesh object and give it the name test "test" before to run this code
                auto object = m_ObjectManager.findObject("test");

                nero_log(_sn(object));

            // the little "_sn" is a toString method; the "s" is for String, the "n" is for Nero Object
        }
};

int main()
{
    nero_log("Nero Game Engine Hello World");

    nero::RenderEngine engine;
    engine.setScene<MyScene>("My Scene");
    engine.run();
}
 

4- No More DevScene

In some previous posts you may saw that a Scene could be created by inheriting from a nero::DevScene, this is no longer the case.
The DevEngine is only able to manage some nero::DevScene, so in principle you should only add DevScenes to it. In contrast the RenderEngine is only able to manage some nero::Scene. Switching between the DevScene engine and the RenderEngine, was requiring to manually change the inheratance of a Scene every time. I founded that combersome so, I made some changes.

Now only nero::Scenes are added to the DevEngine, and it is its responsibility to automatically generate a DevScene that will encapsulate the nero::Scene. With that, there is no change to made in a Scene when moving from the DevEngine to the RenderEngine and vis versa.

5- The  nero::GameEngine

You never heard about this Class. The reason is simply because it doesn't exist yet. The Nero project is based on three seperated Engines.
  • a Dev Engine, its role is to accelerate the development of a Game scene.
  • a Render Engine, its role is to facilitate Scene distribution, if you want a friend or a colleage to test a particular scene, put it in the RenderEngine and share it.
  • a Game Engine, its role is to hold a entire Game, a Game with multiple Scenes and  Menus. Its particularity is to have a Scene_Stack and a way to switch between Scenes and Menus easly.
A this stage of the project, the GameEngine is not a requirement, so I put it away for now.

That's all for this 101, the true tutorial will begin later on

NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #49 on: March 24, 2018, 09:15:38 am »
How to code with the Engine Series

Hi everyone, after the 101 (see the above post), we can now move further and see how to code with the engine.

As I made with the DevEngine Interface, I will made a series of posts to show how to develop a Game with the Engine.

In the Engine Kit there is the project Kero. this project is my game prototype, more exactly the quater of it. I design the prototype in four parts. You can take a look at the code to see how it works. The 3 others parts of the prototype will be part of this tutorial.

bellow you can see the outline of this new series of posts

Part 1: Let's begin slowly

   1/ The nero logger
   2/ Use constants
   3/ Check Objects
   4/ Retrieve objects
   5/ Create a simple Player
   6/ Create a moving platform
   7/ Handle Collisions
   8/ Analyse of the Kero Scene code

Part 2 : Let's finish that Prototype

   1/ the Second part
   2/ The Third part
   3/ The Last part
« Last Edit: May 06, 2022, 04:18:13 pm by NeroGames »

NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #50 on: March 26, 2018, 10:56:50 pm »
How to code with the Engine Part 1-1 : The nero logger

Log things is pretty useful when programming, this is why I wanted to start this series of Howtos with the logger.
The Engine use the Easyloggingcpp library for logging. the default synthax look like this 
[ LOG(INFO) << "log message here, this goes to the console" ]
If you ever used that library and are familiar with it, you can still use its default synthax.

I prefer function-like synthax, this is why I design the [ nero_log() ] and [ nero_log_if() ] functions to replace the original synthax. Those functions are in fact Macros, this is why they don't use the nero namepsace.

Here is a overview of these two functions
nero_log(message)
nero_log(message, level)
nero_log_if(message, boolean)
nero_log_if(message, boolean, level)
 

Two levels are availabled. Not specifing a level is equivalent to use the logger in INFO level
nero::Debug
nero::Warning

//The Debug and Warning level will give the File, the Line and the Method where the log has been called
[DEBUG | main.cpp | Line 21 | virtual void MyScene::init() ] --> Hello world
 

In addition to the logger Macros, you also got some toString Macros
_s(value)        
//equivalent to nero::toString(value), it automatically add a space at the end.

_sn(object)    
 //call the toString method of the object, equtivalent to object->toString()
 

Things  are always more easy with examples, so here are some
x = 5;
auto myPlayer = m_ObjectManager.findObject("player");

nero_log("whatever");
nero_log("whatever", nero::Warning);
nero_log_if("whatever", x < 10);
nero_log_if("whatever", x > 0, nero::Debug);
nero_log("step : " + _s(10) + "the winner is : " + _sn(myPlayer), nero::Debug);
 
« Last Edit: May 06, 2022, 04:18:24 pm by NeroGames »

NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #51 on: March 26, 2018, 11:06:59 pm »
How to code with the Engine Part 1-2 :  Use constants

The Engine use a lot of Strings to do its stuffs. Objects in a Scene are identified by they Name and they Category. The Names and Categories are used everywhere and many time in the code, writting them every time is error prone, so as a good practice, this Strings should be declared as constants and maintained in one place. Also notice that Names and Categories should be unique.

As an example the kero project defined several constants in the Kero_utility.h file like this.

struct _NamePool
{
    const sf::String start_ground       = "start_ground";
    const sf::String player             = "kero";
    const sf::String jump_power         = "jump_power";
    const sf::String start_platform     = "start_platform";
    const sf::String start_end          = "start_end";

};

struct _CategoryPool
{
    const sf::String ground             = "ground";
    const sf::String wall               = "wall";
    const sf::String player             = "player";
    const sf::String power              = "power";
    const sf::String platform           = "platform";
};

struct _PlayerActionPool
{
    const sf::String move_left         = "move_left";
    const sf::String move_right        = "move_right";
    const sf::String move_none         = "move_none";
    const sf::String jump              = "jump";
    const sf::String dash_left         = "dash_left";
    const sf::String dash_right        = "dash_right";
};

const _NamePool             NamePool;
const _CategoryPool         CategoryPool;
const _PlayerActionPool     PlayerActionPool;
 

NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #52 on: March 26, 2018, 11:21:18 pm »
How to code with the Engine Part 1-3 :  Check Objects

Any Object can be retrieved at any moment with a  [ m_ObjectManager.findObject("object_name") ] . The thing to know is that the Object_Manager return a Null_Ptr when it does not found a Object. The reasons the Object_Manager does not found a object may be because the Object simply does not exist, may be you misspelled the Object_Name, or you simply forget to assign the name with the Dev_Engine Interface. So in principle you should test any returned object before to use it like that.

auto object = m_ObjectManager.findObject("oject_name")
if(object)
{
        //do something
}

This is pretty combersome. In order to reduce the risk of using unexisting Objects, you can check them all at the beginning of the init() method.
the method [ m_ObjectManger.checkAllObject(std::vector<sf::String>) ] is there for that. you can give it all the Object_Names you will be using. If it found that a object does not exist, it throws a exception and give you the culprit, I means the Object_Name, that refer to nothing.

void init()
{
    //Test that all objects exist before to continue
    m_ObjectManager.checkAllObject(
    {
        NamePool.start_ground,
        NamePool.jump_power,
        NamePool.player,
        NamePool.start_platform,
        NamePool.start_end,
    });


    // Everything fine here, we can continue safely

}
« Last Edit: May 06, 2022, 04:18:35 pm by NeroGames »

NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #53 on: March 26, 2018, 11:54:10 pm »
How to code with the Engine Part 1-4 :  Retrieve objects

1- Find Objects

The findObject() method, run other the whole Object_Tree_Node to find an Object. This may be resource and time consuming if your Scene contains too many Objects. You can optimize the research if you know the nature of the Object you are looking up for.

If the Object is a Physic_Object by example, use the findPhysicObject() method, This method will skip all layer that does not contain Physic Objects during its look up process.

There are a list of methods you can use to retrieve Object more efficiently
Object::Ptr     findObject(sf::String name);
Object::Ptr     findLayerObject(sf::String layer_name);
Object::Ptr     findObjectInLayer(sf::String name, sf::String layer_name);
Object::Ptr     findSpriteObject(sf::String name);
Object::Ptr     findPhysicObject(sf::String name);
Object::Ptr     findSolidObject(sf::String name);
 

2- Move Objects

The Move methods, cut the Objects you are looking up for from the Object_Tree_Node. So you can re-attach them somewhere else in the Tree.

Object::Ptr     moveObject(sf::String name);
Object::Ptr     movePhysicObject(sf::String name);
Object::Ptr     moveSpriteObject(sf::String name);
Object::Ptr     moveSolidObject(sf::String name);
 

3- Remove Objects

The Remove methods, will destroy complety an object. If the Remove methods do not find the object you want to remove they return false

bool            removeObject(Object::Ptr object);
bool            removeObject(sf::String name);
 

4- Objects Casting

The Find and Move methods always return a generic nero::Object, if you want to perform object specific tasks, you will have to cast the returned Object first. All Object Type have a static Cast() method for that.

nero::Object::Cast()
nero::LayerObject::Cast()
nero::SpriteObject::Cast()
nero::PhysicObject::Cast()
 

Example
auto my_cloud_sprite    = m_ObjectManager.findObject("cloud_sprite");
auto my_ground          = m_ObjectManager.findObject("ground_01");

nero::SpriteObject::Ptr sprite_object = nero::SptriteObject::Cast(my_cloud_sprite);
nero::PhysicObject::Ptr physic_object = nero::PhysicObject::Cast(my_ground);
 

A Solid_Object is a Physic_Object with a Sprite_Object as a child. So a Solid_Object is casted to a Physic_Object

auto object = m_ObjectManager.findSolidObject("object_name");

nero::PhysicObject::Ptr physic_object = nero::PhysicObject::Cast(object);
nero::SpriteObject::Ptr sprite_object = nero::SptriteObject::Cast(object->getFirstChild());
 
« Last Edit: May 06, 2022, 04:18:47 pm by NeroGames »

NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #54 on: April 14, 2018, 03:40:45 pm »
How to code with the Engine Part 1-5 :  Create Moving Objects and Platforms

Hi everyone! how are you doing :). I've been busy the last weeks so I couldn't pursue the series, but here I am.
In this post I'll present a custom PhysicActionObject called SimpleMovingObject. This ActionObject can be used to create moving platorm or to make move any PhysicObject.

There is little change in the schedule, the HowTo on the Player will come after the one on Collision. That said, let's begin.

1- Include the NERO\gamelib.h header

#include <NERO/gamelib.h>

The Nero Game Lib library  defined some custom Actions and ActionObjects. This library is not part of The Engine Core, currently it is provided as a header only library. You can find it in the package in : Library\gamelib\NERO\gamelib.h
Further in the tutorial I will show How to create custom Actions and ActionObjects. For now let's use the ones provided in the gamelib library.

2- SimpleMovingObject, the constructor

nero::SimpleMovingObject(direction, velocity, maxOne, maxTwo);

direction    : [right_left , up_down]    // the direction of the movement
velocity     : [float]                   // the speed of the movement
maxOne       : [float]            // the distance to cover in the first direction (right or up)
maxTwo       : [float]            // the distance to cover in the second direction (left or down)

3- Example

nero::SimpleMovingObject(nero::SimpleMovingObject::Right_Left, 20.f, 100.f, 150.f)

//In the following example, the targeted object will move right and left at a speed of 20 float;
//The object will first move 100 float to the right, then it will come back to its initial position before
//to move 150 float to the left. the total distance of the movement it's therefore 350 float

4- A little trick

If you want the object to move Left_Right, instead of Right_Left, just set maxOne to Zero (0.f)

nero::SimpleMovingObject(nero::SimpleMovingObject::Right_Left, 20.f, 0.f, 250.f)

//Since the object should move 0 float to the right before to go left,
//the object will go left first, what's give you a left_right movement. this work also for the up_down movement.

5- Add the SimpleMovingObject to the Object Tree

The role of an ActionObject is to provide a behavior to another Object (the Target). As we want our ActionObject to have full control of the target, we will first remove the target from the Object Tree, and then give it to the ActionObject. Only after that we can add the ActionObject to the Object Tree

We create the ActionObject as a Pointer since it will be added to the Object_Tree

nero::SimpleMovingObject::Ptr my_Platform;
my_Platform(new nero::SimpleMovingObject(nero::SimpleMovingObject::Right_Left, 20.f, 0.f, 250.f));

We remove the Target from the Object Tree and give it to the ActionObject.
the Object_Manager MoveObject method, cut the target from the Tree and return it

auto target = m_ObjectManager.moveObject("my_platform");
my_Platform->setObject(target);

The Object_Manager will add the ActionObject to the Object Tree

m_ObjectManager.addObject(my_Platform);

6- Some reminders

The SimpleMovingObject is a PhysicActionObject, currently it's the only ActionObject in the gamelib library. As a PhysicActionObject, it handles only PhysicObjects (SolidObjects are also PhysicObjects).

This ActionObject should be used on Kinematic PhysicObject.

Static Objects are not meant to move and Dynamic Objects are meant to be affected by a lot of things (gravity, collisions) what is not ideal for this ActionObject.

7- A full example

First create a Kinematic PhysicObject (Kinematic Mesh) named "my_platform" before to run this code

#include <NERO/engine/DevEngine.h>
#include <NERO/gamelib.h>

class MyScene : public nero::Scene
{
    public:
        MyScene(nero::Scene::Context context):
         nero::Scene(context)
         ,my_Platform(new nero::SimpleMovingObject(nero::SimpleMovingObject::Right_Left, 50.f, 100.f, 100.f))

        {

        }

        void init()
        {
            //First create a Kinematic PhysicObject (Kinematic Mesh) before to run this code

            m_ObjectManager.checkAllObject(
            {
                "my_platform",
            });

            auto target = m_ObjectManager.moveObject("my_platform");
            my_Platform->setObject(target);

            m_ObjectManager.addObject(my_Platform);

        }

        nero::SimpleMovingObject::Ptr my_Platform;
};

int main()
{
    nero::DevEngine engine;
    engine.addScene<MyScene>("My Scene");
    engine.run();
}

« Last Edit: May 06, 2022, 04:19:01 pm by NeroGames »

NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #55 on: April 16, 2018, 09:17:38 pm »
How to code with the Engine Part 1-6 : Handle Collisions

Hi everyone, hope you are doing great. Let's continue this series with Collisons processing

1- Setup the collision rules

Let's consider the following Object Categories (ground, platform, cirlce, cube) and the following rules
  • circles and cubes can collide with ground
  • only circles can collide with platforms
  • circles cannot collide with circles
  • cubes can collide with cubes
  • circles and cubes cannot collide
using a nero::CollisionRule object you can configure this setup with the code bellow

nero::CollisionRule collisionRule;
           
collisionRule.canCollide("circle", "ground");
collisionRule.canCollide("cube", "ground");
collisionRule.canCollide("circle", "platform");
collisionRule.canCollide("cube", "cube");

collisionRule.apply(m_RootObject);

When the apply() method is called, the collisionRule object first remove all previous collision configuration by calling the noCollision() method. When this method is called, no object can collide with any other object, this is why you only have to tell which Category should collide with which one when setting up the rules.

2- Print the collision rule

if you want to see the collision rules in a more readable way, you can called the print() method

collisionRule.print();

3- Process collisions

when a collision occur, the handleCollisionContactBegin() method is called first. The collision is represented as a nero::Collision Object

void handleCollisionContactBegin(nero::Collision collision)
{
    if(collision.isCollising("ground", "cube"))
    {
        nero_log("ground-cube collision detected");

        auto object_1 = collision.getObject("ground");
        auto object_2 = collision.getObject("cube");

        nero_log(_sn(object_1));
        nero_log(_sn(object_2));
    }

    if(collision.isObjectCollising("platform_1", "circle_1"))
    {
        nero_log("platform_1 and circle_1 just collided");

        auto object_1 = collision.getObject("platform_1");
        auto object_2 = collision.getObject("circle_1");

        nero_log(_sn(object_1));
        nero_log(_sn(object_2));
    }
}

4- Test collisions

The collision object offer two methods to test collisions by category or by name

collision.isCollising("object_category_1", "object_category_2");

collision.isObjectCollising("object_name_1", "object_name_2");

The test with a category and a name is not availabled, I will had that for a future release.

5- Retrieve the colliding objects

You can use the getObject() method to retrieve the objects that are colliding, the method takes a category or a name as parameter. The returned object is a nero::PhysicObject

PhysicObject::Ptr collision.getObject(sf::String indicator)

//Example
auto object = collision.getObject("object_category");
//or
auto object = collision.getObject("object_name");


5- Disable collisions

A collision can be easly disabled with the code bellow

collision.setEnabled(false);

6- A full example

You can create the Scene for this example, with this  following json file.

download the scene json

#include <NERO/engine/DevEngine.h>
#include <NERO/scene/CollisionRule.h>

class MyScene : public nero::Scene
{
    public:
        MyScene(nero::Scene::Context context):
            nero::Scene(context)
        {

        }

        void init()
        {
           m_ObjectManager.checkAllObject(
            {
                "platform_1",
                "circle_1",
            });

            nero_log("The collision rules");

            nero::CollisionRule collisionRule;

            collisionRule.canCollide("circle", "ground");
            collisionRule.canCollide("cube", "ground");
            collisionRule.canCollide("circle", "platform");
            collisionRule.canCollide("cube", "cube");

            collisionRule.apply(m_RootObject);

            collisionRule.print();
        }

        void handleCollisionContactBegin(nero::Collision collision)
        {
            //this method is called first when a collision occur;

            if(collision.isCollising("ground", "cube"))
            {
                nero_log("ground-cube collision detected");

                auto object_1 = collision.getObject("ground");
                auto object_2 = collision.getObject("cube");

                //nero_log(_sn(object_1));
                //nero_log(_sn(object_2));
            }

            if(collision.isObjectCollising("platform_1", "circle_1"))
            {
                nero_log("platform_1 and circle_1 just collided");

                auto object_1 = collision.getObject("platform_1");
                auto object_2 = collision.getObject("circle_1");

                //nero_log(_sn(object_1));
                //nero_log(_sn(object_2));
            }


            //If I disabled the collision here, the method (handleCollisionContactEnd) will never be called
            //collision.setEnabled(false);
        }


        void handleCollisionContactEnd(nero::Collision collision)
        {
            //this method is your last change to process a collision
        }
};

int main()
{
    nero::DevEngine engine;
    engine.addScene<MyScene>("My Scene");
    engine.run();
}
 




NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #56 on: April 29, 2018, 04:51:27 pm »
How to code with the engine Part 1-7 : Build a simple player

Hi everyone, hope you are doing great. Let's continue with the series.

In this post I will show how to use an ActionObject and some Actions in order the build a simple player

Step 0 : Include the Nero GameLib header

#include <NERO/gamelib.h>

Step 1 : Create the player object

The first step is to create the object that will be your player using the Dev_Engine_Interface. For this example we can take a simple cube or circle to be the player. So let's create a Physic_Object (Polygon Mesh) with the name "my_player" and the category "player"

step 2 : Use an ActionOject to represent the Player

nero::PhysicActionObject my_Player;
my_Player.setObject(m_ObjectManager.findObject("my_player"));

In the Howto on Moving Objects and Platforms, we used a Custom PhysicActionObject called SimpleMovingObject. The SimpleMovingObject inherit from PhysicActionObject in order to build a more complex interface. But as you can see the default interface of the PhysicActionObject is enough for certain cases. There are many ways to use ActionObject and Action, and for this tutorial we are using the most basic one.

step 3 : Give the player defferent capabilities

Let's say we want our player to be able to move right and left. we also want it to be able to jump.

float move_velocity = 100.f
float jump_force   = 150.f

my_Player.registerAction<MoveAction>("move_left", nero::getMoveLeftAction(move_velocity));
my_Player.registerAction<MoveAction>("move_right", nero::getMoveRightAction(move_velocity));
my_PLayer.registerAction<JumpAction>("jump", nero::getJumpAction(jump_force));

In the code above we've registered three Actions, the player can then perform those actions when ever it want.

void handleKeyboardInput(const sf::Keyboard::Key& key, const bool& isPressed)
{
    if(isPressed)  
    {
       switch(key)
       {
       case sf::Keyboard::J:
           {
               my_PLayer.callAction("jump");
           }break;
       }
       
   }  
}

If you want to see how Actions are built, click on the spoiler button.
(click to show/hide)

Step 4 : Make the camera follow your player

The nero::Scene offers a method called setCameratTarget, that you can used to make the camera follow any Physic_Object.

auto player_object    = m_ObjectManager.findObject("my_player"); //retrieve the object to follow
auto target       = nero::PhysicObject::Cast(player_object); // cast the object to a Physic_Object

setCameraTarget(target); // set the target

It's possible to disable and enable this feature at any moment with the following method

setCameraFollowTarget(bool flag);


This post showed how ActionObject and Action could be used to create a simple player, for a complet example you can check the code in the Kero project.

NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #57 on: April 30, 2018, 12:20:10 am »
How to code with the engine Part 1-8 : Anatomy of the Kero Scene

Hi everyone, how are you doing  ;D. I thought to change this post title, but I finally kept it.

A litte story

There is the story of the Kero scene

once upon a time, there was a little cube with the power to move left and right. After a long long run, the little cube find a blue arrow. The arrow was moving up and down. Intrigued by this arrow the little cube decided to touch it, when it did, some thing amazing happened, the little cube get the power to jump. With its new power the little cube continue its aventure, it later found a moving platform, that was a great opportunity to test its new power, It jumped on the platform which carried it to the beginning of a new aventure.



Build a game with the Nero Game Engine

As you may have seen with the Kero Scene, there are basically  two parts when developing a game with the Engine. I called them the Game Scene part and the Game Code part.
  • The Game Scene
The game scene is built with the Dev Engine Interface, the game scene can be modified at any time without the need rewrite the code. That is great if you want to tweak the position or the shape of an object. Modifing the Game Scene also don't required to recompile your game program, and since the scene is represented as a simple json file, it's easy to share. If you think you are not good at Scene disign just ask a friend to build the scene for you and send you the json file (and also the sprites, ya don't forget them ).
  • The Game Code
The game code is where the logic is built. In the game code you can retrieve the objects created in the game scene and manage collisions and events. The modification of the game code require the recompilation of the game program. With this series you get a look at the engine API. The API is pretty generic and does not target a game genre. If you like a specific game genre you can build your own API on top of the engine one like I did with the Nero Game Lib. I'm a fan of plaftormers so the Nero Game Lib will focus only on the platformer genre.

Learn more and continue the development

The part 2 of the series is put in stand by. I won't have time to work on that in the following months. In place of that I will focus my time on learning game engine architecture and continue the development of the Engine (I will be working on Sound and Animation objects).

I'm pretty happy with the current state of the project considering that I taught  my self C++ programming, SFML and game programming. I'm not a game engine expert, I came to that stage of the project using my intuition and determination. But I think it's time to learn some key notions on engine development. I came accross that book Game Engine Architecture of Jason gregory and found it pretty amazing. I will gather many others books and learn a lot in order to produce the best engine I can.

Thanks for reading my posts, and see you later ;D.


NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #58 on: July 21, 2018, 10:32:13 am »
Hi everyone ! it's been a long time since my last post. Hope you are doing well  :).

A new logo design

Here is the new design I made for the logo. Let me know what you think.



TexturePacker

Do you know TexturePacker from CodeAndWeb. It's a tool that easy the creation of Sprite Sheet. If you have a bunch of PNG files by example, you can import them in TexturePacker and it will "pack" them into one single PNG file. The geat thing, it's that it also provide you a JSON file (not only, there are other formats) describing the Sheet, so the  Sprite Sheet can be easily "decoded" by a game engine.

As I mention in my last post I'm currently working on Animation. Before I started implementing anything I searched over the internet if I could find a tool that will simplify the creation of animation. That lead me to TexturePacker.

TexturePacker will be integrated in my Engine workflow. I will talk more about that when the integration with the engine it's done. For now you can learn more about TexturePacker here.

Development Progress

The development of the Engine progress very slowly these days since I don't have munch time to work on it. But with a little chance things can change in the upcoming months.

have a good day ;D
« Last Edit: May 06, 2022, 04:20:33 pm by NeroGames »

NeroGames

  • Full Member
  • ***
  • Posts: 101
  • Build games is simple
    • View Profile
    • Nero Game Engine
    • Email
Re: Nero Game Engine
« Reply #59 on: August 31, 2018, 11:57:40 pm »
Hi everyone !, I'm back, how do you do ?

During the last two weeks I got a lot of free time, so I worked on the Engine. The Engine has evolved, I added some new features and fixed some bugs. I've made a review of the features that will be availabled in the Engine first version. The first version will be ready by the end on this year. The integration of Lua as a scripting language will take a lot of time, so for the first version there will only be a very minimalist integration of Lua. C++ will be the main language to use the Engine. Finally I plan to open a website early next year, maybe on Junuary. 

that's said, Let's jump on the new features !!!

Startup Screen

The DevEngine now has a Startup Screen or a Loading Screen if you prefer. The Engine just use two threads on startup. While the main thread render the Loading Screen, a second thread load Resources and build the Engine_UI in background.




Custom Startup Screen

While the DevEngine has a fix Startup Screen, the RenderEngine can take a custom Startup Screen. That allows you to create your own game loading screen. In order to create a Startup Screen you simply have to create a class that henerite from nero::StartupScreen

(click to show/hide)

All the methods in the class are virtual pure; you have to override all of them.
the getBackgroundColor() method return a color to clear the sf::RenderWindow;
the getMintime() method return a time in second. It allows you to choose if the LoadingScreen should last in 5 second or 10 second or whatever you want.

the Custom Startup Screen is given to the RenderEngine via it's constructor.

MyStartupScreen myStartupScreen;

nero::RenderEgine engine(myStartupScreen);
engine.setScene<MyScene>("my scene name");
engine.run();

Sound and Music

The Engine can now load and manage Sound and Music. Like other resources the loading is automatic. Just copy some sounds in the folder "/Resource/Sound" and some musics in the folder "/Resource/Music", the Engine will take care the rest. In your Scene class, there is a instance of the class nero::SoundManager. this class let you play a sound or a music at any time in your game.

The DevEngine allows to quickly access all your Musics and Sounds, so you can enjoy them while building a Scene.




Configuration Files

In order to make the Engine more flexible, many hard coded properties are now made evailable as configurations. Configuration files are JSON files, they are all located in the folder "/config"

As a example, for each resource type (Texture, Sound, Music etc), you can now choose the folder where to put them, you can also choose the extensions you want to handle.

For Fonts, you can choose what Font to use as default.

{
        "font" :
                {
                        "folder" : "Resource/Font",
                        "extension" : ["ttf"],
                        "default" : "Sansation"
                },

        "sound" :
                {
                        "folder" : "Resource/Sound",
                        "extension" : ["wav", "ogg", "flac"]
                },

        "music" :
                {
                        "folder" : "Resource/music",
                        "extension" : ["wav", "ogg", "flac"]
                },

        "texture" :
                {
                        "folder" : "Resource/Texture",
                        "extension" : ["png", "jpg", "bmp", "dds", "tga", "psd"],
                        "separator" : "-"
                },

        "shader" :
                {
                        "folder" : "Resource/Shader",
                        "shader-list" : "Resource/Shader/shader.json",
                        "extension" : ["vert", "frag"]
                },

        "animation" :
                {
                        "folder" : "Resource/Animation",
                        "extension" : ["png", "jpg"]
                },

        "script" :
                {
                        "folder" : "Resource/Script",
                        "extension" : ["lua"]
                }

}


Bug fixed : RenderCanvas glitch

In the version of the Engine provided with the SDK (Startup Kit), there is a glitch on the Canvas when you remove a Layer or when the Redo and Undo buttons are used. It tooks me some time to find the reason of this glitch, but it's now fixed.

that's all for this post, There are other new features like Animation and Grid, they are still in development, I will talk about them another day.

thanks for reading my posts and see you later  :).
« Last Edit: May 06, 2022, 04:20:45 pm by NeroGames »