Implementing particles in Mach5

Now that we know what particles are, let's put them into Mach5 so we can get an example of how they work. We will be creating particles to follow our ship while it moves in a similar fashion to a smoke trail. This will be a great way to show an example of particles on the screen but, to have something to show, we will first need to bring a new archetype into the game.

To do that, open up the Example Code folder for this chapter and bring the particle.tga file into the EngineTest/Textures folder of your Visual Studio project.

After that, open up the EngineTest/ArcheTypes folder, create a new text file called Particle.ini, and fill it with the following info:

posX   = 0 
posY = 0
velX = 0
velY = 0
scaleX = 2.5
scaleY = 2.5
rot = 0
rotVel = 0
components = GfxComponent ParticleComponent

[GfxComponent]
texture = particle.tga
drawSpace = world

After that, we need the Mach5 engine to support our new object, so go to the EngineTest folder and then double-click on the PreBuild.bat file. The M5ArcheTypes.h file will be updated to include our particle:

//! AutoGenerated enum based on archetype ini file names   
enum M5ArcheTypes {
AT_Bullet,
AT_Particle,
AT_Player,
AT_Raider,
AT_Splash,
AT_INVALID
};

Nice! Now that we have the object in the game, there's still the issue of putting in the Particle component. Since this component is not exclusive to our game, let's move over to the Core/Components filter and create a new filter called ParticleComp. From there, create two new files, ParticleComponent.h and ParticleComponent.cpp, making sure their locations are set to the Mach5-masterEngineTestEngineTestSource folder.

In the .h file, use the following code:

/******************************************************************************/ 
/*!
file ParticleComponent.h
author John Doran
par email: [email protected]
par Mach5 Game Engine
date 2016/12/06

Used to display a single particle on the screen.
*/
/******************************************************************************/
#ifndef PARTICLE_COMPONENT_H
#define PARTICLE_COMPONENT_H

#include "CoreM5Component.h"
#include "CoreM5Vec2.h"


class ParticleComponent : public M5Component
{
public:
ParticleComponent();
virtual void Update(float dt);
virtual M5Component* Clone(void);
virtual void FromFile(M5IniFile& iniFile);
bool activated;
float lifeTime;
float endScale;
private:
M5Vec2 startScale;
float lifeLeft;
float Lerp(float start, float end, float fraction);
};

#endif // !PARTICLE_COMPONENT_H

This class looks similar to other components that we've added in the past, but this time we've added a startScale property to keep track of what scale our object had at the start of its life, and an endScale property to be a modifier on how to change the scale. We also have lifeTime, which will be how long this object should live before we remove it, and lifeLeft, which will be how much longer this object has to live. Finally, since we are going to change our scale, we added another function, Lerp, to linearly interpolate between a starting and ending value.

In the .cpp file, use the following code:

/******************************************************************************/ 
/*!
file ParticleComponent.cpp
author John Doran
par email: [email protected]
par Mach5 Game Engine
date 2016/12/06

Particle system component. Allows you to draw many particles on the screen.
*/
/******************************************************************************/
#include "ParticleComponent.h"
#include "CoreM5Gfx.h"
#include "CoreM5Math.h"
#include "CoreM5Object.h"
#include "EngineTestM5ObjectPool.h"
#include "CoreGfxComponent.h"
#include "CoreM5IniFile.h"

/******************************************************************************/
/*!
Construtor for ParticleSystem component. Sets default values
*/
/******************************************************************************/
ParticleComponent::ParticleComponent() :
M5Component(CT_ParticleComponent)
{
}

/******************************************************************************/
/*!
Takes care of the particle system, decrease lifetime and adjust scaling.
Will mark for destruction if needed.

param [in] dt
The time in seconds since the last frame.
*/
/******************************************************************************/
void ParticleComponent::Update(float dt)
{
// Decrease our life by the change in time this frame
// (dt stands for delta time)
lifeLeft -= dt;

// Change our size based on where we want it to be
float currentPercentage = 1 - (lifeLeft / lifeTime);
m_pObj->scale.x = Lerp(startScale.x,
startScale.x * endScale, currentPercentage);

m_pObj->scale.y = Lerp(startScale.y,
startScale.y * endScale, currentPercentage);

// If there is no life left, destroy our object
if (lifeLeft <= 0)
{
m_pObj->isDead = true;
}

}

This code will modify the object's scale by using the Lerp function to interpolate between the starting and ending scale. We also will modify how much life the particle has left, and if it has none, mark the particle for deletion:

/******************************************************************************/ 
/*!
Will give you the percentage of the fraction from start to end

param [in] start
What value to start from

param [in] end
What value to end from

param [in] fraction
What percentage of the way are we are from start to finish

*/
/******************************************************************************/
float ParticleComponent::Lerp(float start, float end, float fraction)
{
return start + fraction * (end - start);
}

Linear interpolation (Lerp) allows us to obtain a value between start and end using the fraction property for how far along the transition it should be. If fraction is 0, we would get the value of start. If we give 1, we will get the value of end. If it's .5, then we would get the half-way point between start and end.

For more information on interpolation including linear interpolation, check out Keith Maggio's notes on the topic at https://keithmaggio.wordpress.com/2011/02/15/math-magician-lerp-slerp-and-nlerp/.
/******************************************************************************/ 
/*!
Clones the current component and updates it with the correct information.

eturn
A new component that is a clone of this one
*/
/******************************************************************************/
M5Component * ParticleComponent::Clone(void)
{
ParticleComponent * pNew = new ParticleComponent;
pNew->m_pObj = m_pObj;
pNew->startScale = m_pObj->scale;
pNew->lifeTime = lifeTime;
pNew->lifeLeft = lifeTime;
pNew->endScale = endScale;
return pNew;
}

The Clone function allows us to create a copy of this object. It will create a new version of this component, and we will initialize the values of the new component with the values we currently have. This is used by the Mach5 engine in the creation of new game objects:

/******************************************************************************/ 
/*!
Reads in data from a preloaded ini file.

param [in] iniFile
The preloaded inifile to read from.
*/
/******************************************************************************/
void ParticleComponent::FromFile(M5IniFile& iniFile)
{
// Get our life time value
std::string lifeTimeText;
iniFile.SetToSection("ParticleComponent");
iniFile.GetValue("lifeTime", lifeTimeText);

// Convert the string into a float
lifeTime = std::stof(lifeTimeText);
lifeLeft = lifeTime;

// Then do the same for endScale
std::string endScaleText;
iniFile.GetValue("endScale", endScaleText);
endScale = std::stof(endScaleText);

}

Just like before, the FromFile function will read in our ini file we created previously and will use the values from it to set the properties of this component. In our case, here we set lifeTime, lifeLeft, and endScale.

Finally, let's start putting these objects into our game. Open up the PlayerInputComponent.cpp file and add the following to the top of the Update function:

M5Object* particle = M5ObjectManager::CreateObject(AT_Particle); 

particle->pos = m_pObj->pos;

This will cause a particle to get spawned in every single frame and have the same position as our ship. Now, if we run the game, we should see some cool stuff! We can see this in the following screenshot:

As you can see, our ship now has a trail following behind it. Each part is a particle!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.97.75