Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

10.08.2015, 16:33

C++ SFML Partikel System

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?

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

2

10.08.2015, 16:41

Du erbst von sf::Drawable, implementierst aber nicht ihre abstrakte Funktion virtual void draw(RenderTarget& target, RenderStates states) const = 0;. Dementsprechend ist deine Klasse auch abstrakt.
Lösung: Statt "Render" deine Funktion "draw" nennen.
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

3

10.08.2015, 16:54

Danke viel mals
Hat geklappt :thumbsup:

Werbeanzeige