SFML community forums

General => SFML projects => Topic started by: sparkon on October 06, 2012, 10:22:00 pm

Title: Spartickes Engine
Post by: sparkon on October 06, 2012, 10:22:00 pm
Sparticles Engine : Particle engine developed by sparkon

LINKS TO IMAGES
http://postimage.org/image/mm3mbwy69/]http://postimage.org/image/mm3mbwy69/]http://postimage.org/image/mm3mbwy69/ (http://postimage.org/image/mm3mbwy69/)
http://postimage.org/image/q3fx7zj85/ (http://postimage.org/image/q3fx7zj85/)

( don't blame me for imagination )
Hello guys! this is my first "big" project with SFML, it maybe stupid for most of you, but for me it's really important. I was coding my game when i felt the need to create a particle engine, but i didn't want a costum-made one just for my game so i wrote this. It's a simple particle engine based on SFML 2.0 and nothing else.
As soon as i'll post this i'll write a couple of tutorials on how to use it, even though it will become clear while reading its features.


FEATURES

The library is composed by two main classes :

-> DirectionalEmitter
-> ExplosionEmitter

as the names suggest they have been create with two different purposes, even though if you work out your directionalemitter you can achieve pretty much ( not exactly) the same effect of the explosionemitter.
Since for the two emitters there are a lot of data that you need ( position, heading,speed,blending etc.....) i've created two costum structs to make the construction easier :

-> DirectionalEmitterMode
-> ExplosionEmitterMode

They work the same way of sf::VideoMode :

-> you initialize them
-> you choose your values
-> you put it in the Emitter constructor


Since there are a lot of variables, you can choose to initialize it with pre-defined values and tweak them later or hardcode them directly in the constructor. To make the whole thing working there is just 1 thing that you absolutely have to do before constructing the emitter, and it is :

CHOOSING THE PARTICLE
Sparticles emitter allows you to use 4 different kinds of "look" for your particles :

1  - TEXTURE                Use your asset - fast,but not the fastest
2  - CONVEX SHAPE      choose your cool shape - slowest one
3  - CIRCLE SHAPE
4  - PIXEL ARRAY          Just pass the size of the screen and the color you want! easiest and fastest


Everything it's really straighforward. For the Pixel array i've added a few modes ( more will come in the future ) to make the effect really cool :

-> Color Range   Avaiable for both emitters
-> Rainbow Mode  DirectionalEmitter
-> RandomColor   ExplosionEmitter


Again.. as the names suggest you can choose a random color within a predefined range, rainbow mode starting from a predefined range.
Color Range in my opinion is the best one, the particle will start from color A (you choose it ) and will change color ( based on lifetime ) til dying with color B ( you choose it ofc).

ENGINE

The last class you need to be aware of is the ParticleEngine that is nothing else than a higher-level wrapper to manage all your emitters. Every emitter has got his own ID you can access from. You add an emitter by passing its pointer and then place an Update in your main loop.

LINKS

The project is hosted on GitHub, but i've also added a link to mediafire.
In the ZIP file you'll find :
-> compiled headers (debug and release)
-> source code
-> include ( with headers file )
-> Tutorial ( not yet, i'll post it as soon as i can )

P.S : Excuse my english please.

MEDIAFIRE
http://www.mediafire.com/?1bben2471vl229c

GITHUB PROJECT
https://github.com/sparkon/Sparticles (https://github.com/sparkon/Sparticles)

CODE SAMPLES
Sample Explosion with pixels
Code: [Select]
#include "sparticles.h"
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>


int main()
{

sf::RenderWindow Window(sf::VideoMode(800,600,32),"PARTICLE SYSTEM TEST");
sp::ParticleEngine Engine;

Window.setFramerateLimit(120);
sp::ExplosionEmitterMode dmode(sp::Vector2D(400,300));
dmode.set_pixel_array(sf::Color(255,0,0),sf::Color(255,255,0));
dmode.n_of_particles_ = 6000;
dmode.life_time_ = 100;
dmode.blend_mode_ = sf::BlendAdd;
dmode.random_speed_ = 1;
sp::ExplosionEmitter* emitt = new sp::ExplosionEmitter(Window,dmode);
unsigned int ID = Engine.NewEmitter(emitt);


sf::Clock clock;
while ( Window.isOpen())
{
sf::Event Event;
while ( Window.pollEvent(Event))
{
switch(Event.type)
{
case sf::Event::Closed :
Window.close();
break;
default :
break;
}
}
Window.clear(sf::Color(0,0,0));
sf::Time dt = clock.restart();
Engine.Update(dt);
Window.display();
}
return 0;
}

Directional emitter sample
Code: [Select]
#include "sparticles.h"
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>


int main()
{

sf::RenderWindow Window(sf::VideoMode(800,600,32),"PARTICLE SYSTEM TEST");
sp::ParticleEngine Engine;

Window.setFramerateLimit(120);
sp::DirectionalEmitterMode dmode(sp::Vector2D(0,0));
dmode.set_texture("Particle0.png");
dmode.n_of_particles_ = 10000;
dmode.burst_rate = 0.001;
dmode.life_time_ = 150;
dmode.reuse_ = true;
dmode.blend_mode_ = sf::BlendAdd;
sp::DirectionalEmitter* emitt = new sp::DirectionalEmitter(Window,dmode);
unsigned int ID = Engine.NewEmitter(emitt);


sf::Clock clock;
while ( Window.isOpen())
{
sf::Event Event;
while ( Window.pollEvent(Event))
{
switch(Event.type)
{
case sf::Event::Closed :
Window.close();
break;
default :
break;
}
}
Window.clear(sf::Color(0,0,0));
sf::Time dt = clock.restart();
Engine.Update(dt);
Window.display();
}
return 0;
}
Title: Re: Spartickes Engine
Post by: FRex on October 06, 2012, 10:47:45 pm
Images link's broken.
You can do namespace sp {} around everything in your cpp files too.
Don't put h files into both include and src folder, include sfml with <> instead of "".
Every header should do
#ifndef smt
#define smt
//code
#endif
Instead of what you're doing now with some of them:
#ifndef UTILITIES_INCLUDE_H
#define UTILITIES_INCLUDE_H
#include "utilities.h"
#endif // utilities included

Title: Re: Spartickes Engine
Post by: sparkon on October 06, 2012, 10:51:19 pm
Posting more images. Thanks for reply
Title: Re: Spartickes Engine
Post by: eXpl0it3r on October 06, 2012, 10:54:25 pm
Well your images are still not what one would want, like this:

(http://s18.postimage.org/wh50b8o47/SC02.png) (http://postimage.org/image/q3fx7zj85/)

Also it would've been interesting if you had added an example to your code, so we could actually be able to test it, without having to go through the code and figure out how things work...
Title: Re: Spartickes Engine
Post by: FRex on October 06, 2012, 11:03:00 pm
The Vector2D is weird.. ???
What's the point of it since this is exclusivly for sfml you could use sf vectors and define bunch of functions to do what you do with your vector.
        // Deconstructor
~Vector2D(){};
That's destructor. But that's not that important.
        Vector2D operator+(Vector2D& right)
{
return (Vector2D(x_ * right.x_,y_ * right.y_));
}

Vector2D operator-(Vector2D& right)
{
return (Vector2D(x_ * right.x_,y_ * right.y_));
}

Vector2D operator*(Vector2D& right)
{
return (Vector2D(x_ * right.x_,y_ * right.y_));
}
Why three operators do the same and not take const reference to right?
        Vector2D Scale(double S)
{
x_ /= S;
y_ /= S;
return *this;
}
Why doesn't that do *= instead of /= and return temp copy instead of reference?
        double  x_;
double  y_;
Public vars with trailing underscores are.. weird?
Title: Re: Spartickes Engine
Post by: sparkon on October 06, 2012, 11:05:43 pm
Also it would've been interesting if you had added an example to your code, so we could actually be able to test it, without having to go through the code and figure out how things work...

Adding some code samples!
Title: Re: Spartickes Engine
Post by: sparkon on October 06, 2012, 11:07:05 pm
The Vector2D is weird.. ???
What's the point of it since this is exclusivly for sfml you could use sf vectors and define bunch of functions to do what you do with your vector.
        // Deconstructor
~Vector2D(){};
That's destructor. But that's not that important.
        Vector2D operator+(Vector2D& right)
{
return (Vector2D(x_ * right.x_,y_ * right.y_));
}

Vector2D operator-(Vector2D& right)
{
return (Vector2D(x_ * right.x_,y_ * right.y_));
}

Vector2D operator*(Vector2D& right)
{
return (Vector2D(x_ * right.x_,y_ * right.y_));
}
Why three operators do the same and not take const reference to right?
        Vector2D Scale(double S)
{
x_ /= S;
y_ /= S;
return *this;
}
Why doesn't that do *= instead of /= and return temp copy instead of reference?
        double  x_;
double  y_;
Public vars with trailing underscores are.. weird?

yes.. i know i was gonna replace that class with sf::Vector2f asap. Thanks for the hint!
Title: Re: Spartickes Engine
Post by: FRex on October 06, 2012, 11:12:02 pm
void sp::ParticleEngine::DestroyAll()
{
for ( int i = 0; i < active_emitters_.size(); i++)
{
active_emitters_.erase(active_emitters_.begin() +i);
}
}
That loop looks dangerous. It'll only delete half of contents(every element with even index) of active_emitters. Is that intended?
Title: Re: Spartickes Engine
Post by: sparkon on October 06, 2012, 11:14:17 pm
void sp::ParticleEngine::DestroyAll()
{
for ( int i = 0; i < active_emitters_.size(); i++)
{
active_emitters_.erase(active_emitters_.begin() +i);
}
}
That loop looks dangerous. It'll only delete half of contents(every element with even index) of active_emitters. Is that intended?

I'm sorry but i don't get it. why even index? are you referring to "+i"?
Title: Re: Spartickes Engine
Post by: FRex on October 06, 2012, 11:22:39 pm
int main()
{
        std::vector<int> test;
        for(int i=0;i<15;++i)test.push_back(i);

        for ( int i = 0; i < test.size(); i++)
        {
                test.erase(test.begin() +i);
        }

        for(int i=0;i<test.size();++i)
                std::cout<<test[i]<<std::endl;

}
Run that to see what happens, also, int should be unsigned int or unsigned or vectors sizetype to silence compiler warnings. Vector emptying should be done by clear() call on it.

If you're desperate for double precision the use sf::Vector<double> and typedef it in your namespace.

unsigned int sp::ParticleEngine::NewEmitter(BaseEmitter* Emitter)
{
// Adding it to the list
active_emitters_.push_back(Emitter);

// Adding ID TO EMITTER
Emitter->set_id(m_next_valid_id_);
// Returning the ID
return m_next_valid_id_;
// Increasing ID
m_next_valid_id_ += 1;
}
The last line of this code will not execute... ever..

What's the point of get by index instead of get by id?

Much of things there could be improved. Many inefficient loops, inconsistent passing of things: references/pointers. What's the point of engine if you have to manage lifetime of emiters yourself anyway. Maybe create factory functions that take some definition struct and create apropriate emitter from it(like box2d api). Missing consts ect.
I'm sorry but this code is full of errors.
Title: Re: Spartickes Engine
Post by: Nexus on October 06, 2012, 11:32:18 pm
You should really work on your code, there are many mistakes and questionable style. To name some:
There are many more. I don't want to offend you, but it looks like you are lacking important C++ knowledge. Maybe you could read a good book like the C++ Primer in parallel to development...?
Title: Re: Spartickes Engine
Post by: sparkon on October 06, 2012, 11:38:36 pm
Nexus you are not offending me :) you're just helping! thanks for all the hints. I'm gonna study more and will retry later!. Thanks to FRex too.
Title: Re: Spartickes Engine
Post by: Qix on October 08, 2012, 07:30:10 pm
Nexus you are not offending me :) you're just helping! thanks for all the hints. I'm gonna study more and will retry later!. Thanks to FRex too.

Woah, someone who doesn't get upset when they're given C++ criticism?

Faith in humanity is restored just a little...