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

cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

1

25.10.2015, 15:49

[C++ | SFML] Logikfehler im Programm?

Hallo Leute,

das Problem mag erstmal recht einfach klingen, aber ich komme trotzdem nicht weiter. Das Problem: Bei meinem Spiel sollen die Asteroiden in der Nähe des Spielers spawnen, d.h. das zu aktuellen Position des Spielers soll ein zufälliger offset addiert werden soll. So habge ich es im Programm gelöst:

Player.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
35
36
37
38
39
#pragma once

#include "core\include\Game.hpp"

#include <memory>
#include <SFML\Graphics.hpp>

class Game;

class Player
{
public:
    Player();

    void Update();
    void ProcessEvents();
    void Render(sf::RenderWindow &App);

    void loadPlayerAssets();

    // getter
    sf::Sprite getSprite() { return mSprite; };
    float getCurrentX() { return m_fCurrentX; };

private:
    sf::Sprite mSprite;
    sf::Texture mTexture;

    float m_fCurrentX = 0.f;

    const float m_fPlayerSpeed;

    const float m_fMaxX = 935.f;
    const float m_fMinX = 20.f;

    const float m_fMaxY = 515.f;
    const float m_fMinY = 25.f;

};


Player.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
// ...

void Player::Update()
{
    // Aktuelle Position einlesen
    m_fCurrentX = mSprite.getPosition().x;

    // Wenn der Spieler außerhalb vom Bildschirm ist, dann stoppen
    //

    // x-Achse
    if (mSprite.getPosition().x < m_fMinX)
        mSprite.setPosition(20.f, mSprite.getPosition().y);

    else if (mSprite.getPosition().x > m_fMaxX)
        mSprite.setPosition(935.f, mSprite.getPosition().y);

    // y-Achse
    if (mSprite.getPosition().y < m_fMinY)
        mSprite.setPosition(mSprite.getPosition().x, 25.f);

    else if (mSprite.getPosition().y > m_fMaxY)
        mSprite.setPosition(mSprite.getPosition().x, 515.f);

}

// ...


Asteroid.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
35
36
37
38
#pragma once

#include "core\include\Game.hpp"

#include <memory>

class Asteroid
{
public:
    Asteroid();

    void Init(Game &game);

    void Update();
    bool CheckCollision(sf::Sprite &sprite);
    void Render(sf::RenderWindow &App);

    // getter
    bool getAlive() { return m_bAlive; };
    sf::Sprite getSprite() { return mSprite; };

private:
    void loadAsteroid(Game &game);

    float randOffset();

private:
    sf::Texture mTexture;
    sf::Sprite  mSprite;

    bool m_bAlive;

    float m_fCurrentXPos;
    float m_fCurrentYPos;

    const float m_fSpeed = 0.07f;

};


Asteroid.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
void Asteroid::loadAsteroid(Game &game)
{
    mTexture.setSmooth(false);

    // Mittelpunkt ist genau in der Mitte der Textur
    mSprite.setOrigin(
        game.mManager->getTexture(RessourcenManager::ASTEROID).getSize().x / 2.f, 
        game.mManager->getTexture(RessourcenManager::ASTEROID).getSize().y / 2.f);

    mSprite.setTexture(game.mManager->getTexture(RessourcenManager::ASTEROID));
    mSprite.setScale(0.5f, 0.5f);   // auf 50% verkleinern

    // Auf die x-Position des Spielers wird ein zufälliger offset addiert. 
    // Die Asteroiden werden außerhalb des Bildschirms gesetzt, 
    // damit keine unschönen Effekte erzeugt werden.
    mSprite.setPosition(
        randOffset() + mPlayer->getCurrentX(),
        -10.f);

    std::cout << "Player: " << mPlayer->getCurrentX() << std::endl;
    std::cout << "Asteroid: " << mSprite.getPosition().x << std::endl << std::endl;

}


float Asteroid::randOffset()
{
    int xOffset = std::rand() % 100 + 2;

    std::cout << "offset: " << xOffset << std::endl;

    return xOffset;
}


Beispiel Ausgabe in der Konsole:
offset: 36
Player: 0
Asteroid: 36

Habe ich irgendwo einen Fehler übersehen?

Danke im Voraus :)

2

25.10.2015, 15:56

Ohne ansatzweise reinzuschauen, nur um nochmal nachzufragen: Du fragst, ob dieses Stück Code funktioniert!?

MfG
Check

cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

3

25.10.2015, 16:00

Ohne ansatzweise reinzuschauen, nur um nochmal nachzufragen: Du fragst, ob dieses Stück Code funktioniert!?

Wenn ich das " + mPlayer->getCurrentX()" weg lasse, dann klappt es.

cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

4

25.10.2015, 16:20

Wo werden die Meteoriten gespawnt wenn überhaupt. Einfach mal spezifizieren wo genau der Fehler liegt, ist schwer das im Kopf nachzuvollziehen auf die Schnelle ...

Die Asteroiden werden "über" dem Bildschrim gespawnt (y = -10), damit die nicht einfach so im Bild erscheinen. Der fehler liegt "im" unique_ptr, weil wenn ich die aktuelle x-Position direkt nach dem einlesen ausgeben lasse (Zeile 6 in Player.cpp), dann stimmt der Wert. Wenn ich diese Position mithilfe des getters "->getCurrentX()" ausgeben lasse, dann wird "0" in der Konsole ausgegeben. Soweit verständlich?

cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

5

25.10.2015, 16:37

Würde sich da was ändern wenn du

C-/C++-Quelltext

1
float getCurrentX() { return mSprite.getPosition().x; };


statt

C-/C++-Quelltext

1
float getCurrentX() { return m_fCurrentX; };


machst?

Es ändert was, aber dann wird die Startposition des Spielers ausgegeben (480) und die ändert sich nicht :dash:

6

25.10.2015, 16:52

Wird wohl eher daran liegen das update noch nicht aufgerufen wurde.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

7

25.10.2015, 17:03

Wird wohl eher daran liegen das update noch nicht aufgerufen wurde.

Die Updatemethode wird in "PlayState.cpp" in "Update" aufgerufen und die wird in "Game.cpp" in "Update" aufgerufen. Daran kann es nicht liegen. Braucht ihr vllt noch irgendwelchen Code?

cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

8

25.10.2015, 17:13

Aus dem bisherigen kann man den Fehler nicht lokalisieren

Das Problem ist ja auch, dass der Debugger keinen aufschluss gibt, da die Spielerposition in Update zwar richtig der Variable zugewiesen wird, aber sobald ein neuer Asteroid erstellt wird, steht die Variable auf 0 :pillepalle:

cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

9

25.10.2015, 17:26

in deiner Update MEthode....führe mal das updaten von m_fCurrentX nach dem Abfragen aus...

Leider kein unterschied...

EDIT: Ja, die Speicheradressen unterscheiden sich :wacko:

cojo2015

Alter Hase

  • »cojo2015« ist der Autor dieses Themas

Beiträge: 516

Wohnort: bei mir zu Hause

Beruf: Schüler

  • Private Nachricht senden

10

25.10.2015, 17:44

Na siehst du da gehts schon los. Ich kenne mich mit SFML nciht aus. Kann an SFML liegen oder allgemein ein Logikfehler...

Und wenn ich den unique_ptr von "Player" aus "PlayState.hpp" einfach public mache und dann in "Asteroid.hpp" einen unqiue_ptr von "PlayState" erstelle, könnte es dann funktionieren?

Werbeanzeige