Hallo liebe Spieleprogrammierer
Ich versuche mich gerade an einem Partikel System in der SFML.
Die Klasse funktioniert einwandfrei aber wenn ich sie zb. in einem Gamestate aufrufe kriege ich den Fehler.
error C2259: 'ParticleSystem' : cannot instantiate abstract class e:\daten\visual studio 2013\vc\include\Memory
Ich weiss, dass es etwas mit meinem sf::RenderTarget zu tun hat aber ich weiss nicht wie ich es sonst aufrufen könnte.
ParticleSystem.hpp
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#pragma once
#include <SFML\Graphics.hpp>
class ParticleSystem : public sf::Drawable, public sf::Transformable
{
public:
ParticleSystem(unsigned int count);
void Update(sf::Time deltatime);
// setter
void setEmitter(sf::Vector2f position);
private:
virtual void Render(sf::RenderTarget& target, sf::RenderStates states) const;
void resetParticle(std::size_t index);
private:
struct Particle
{
sf::Vector2f velocity;
sf::Time lifetime;
};
std::vector<Particle> m_particles;
sf::VertexArray m_vertices;
sf::Time m_lifetime;
sf::Vector2f m_emitter;
sf::Color m_color;
};
|
ParticleSystem.cpp
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
#include "include\ParticleSystem.hpp"
ParticleSystem::ParticleSystem(unsigned int count) :
m_particles(count),
m_vertices(sf::Points, count),
m_lifetime(sf::seconds(3)),
m_emitter(0, 0)
{
}
void ParticleSystem::Update(sf::Time deltatime)
{
for (std::size_t i = 0; i < m_particles.size(); ++i)
{
// Die Lebenszeit der Partikel erneuen
Particle& p = m_particles[i];
p.lifetime -= deltatime;
// Wenn die Partikel sterben, sollen neue spawnen
if (p.lifetime <= sf::Time::Zero)
resetParticle(i);
// Die Position vom Vertex updaten
m_vertices[i].position += p.velocity * deltatime.asSeconds();
// Farbe:
// Das Alpha(transparent) vom Partikel updaten mit der Lebenszeit
float ratio = p.lifetime.asSeconds() / m_lifetime.asSeconds();
m_vertices[i].color.a = static_cast<sf::Uint8>(ratio * 255);
}
}
void ParticleSystem::Render(sf::RenderTarget& target, sf::RenderStates states) const
{
// Anwenden der Transformation
states.transform *= getTransform();
// Unsere Partikel benutzen keine Textur
states.texture = NULL;
// Den Vertex Array zeichnen
target.draw(m_vertices, states);
}
void ParticleSystem::resetParticle(std::size_t index)
{
// Eine zufällige Geschwindigkeit und Lebenszeit unseren Partikeln geben
float angle = (std::rand() % 1000) * 3.14f / 180.f;
float speed = (std::rand() % 50) + 50.f;
m_particles[index].velocity = sf::Vector2f(std::cos(angle) * speed, std::sin(angle) * speed);
m_particles[index].lifetime = sf::milliseconds((std::rand() % 2000) + 1000);
m_vertices[index].position = m_emitter;
}
void ParticleSystem::setEmitter(sf::Vector2f position)
{
m_emitter = position;
}
|
MainMenuState.cpp
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
#include "include\MainMenuState.hpp"
MainMenuState::MainMenuState()
: startClicked(false)
, exitClicked(false)
{
mButtonStart = std::make_shared<Button>("Start", sf::Vector2f(440.f, 200.f));
mParticles = std::make_unique<ParticleSystem>(1000);
}
MainMenuState::~MainMenuState()
{
}
void MainMenuState::Update(Game &game, sf::Time deltatime)
{
// start
mButtonStart->onHover(game[0]);
startClicked = mButtonStart->onClick(game[0]);
// Die Partikel sollen von der Maus kommen
sf::Vector2i mouse = sf::Mouse::getPosition(game[0]);
mParticles->setEmitter(game[0].mapPixelToCoords(mouse));
mParticles->Update(deltatime);
}
void MainMenuState::ProcessEvents(Game &game)
{
if (startClicked)
game.changeState(Game::gameStates::PLAY);
}
void MainMenuState::Render(sf::RenderWindow &App)
{
mButtonStart->Render(App);
App.draw(*mParticles);
}
|
Gibt es eine Methode, eine abstrakte Klasse zu includieren, ohne dass der Fehler kommt?