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

25.12.2015, 23:25

C++ friend class Problem

Hallo :)

Ich habe ein kleines Problem ich möchte in einer Enemy.cpp die koordinaten von einer Ball.hpp getn habe es schon mit friend class versucht bin aber am verzweifeln :(

Ich poste mal alle meine .hpp und .cpp Dateien.

Framework.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
40
41
#pragma once

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

#include "Player.hpp"
#include "Enemy.hpp"
#include "Ball.hpp"

using namespace sf;

class CFramework {

    friend class CEnemy;

public:
    CFramework              ();
    ~CFramework             ();

    void Run                ();

private:
    void Update             (float fElapsedTime);
    void Render             ();
    void HandleEvents       ();
    void Quit               ();

    float GetElapsedTime    ();

    RenderWindow            *m_pWindow;
    Event                   *m_pEvent;
    Clock                   *m_pClock;

    CPlayer                 *m_pPlayer;
    CEnemy                  *m_pEnemy;
    CBall                   *m_pBall;

    float                   m_fElapsedTime;
    bool                    m_bRunning;

};


Framework.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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "Framework.hpp"

CFramework::CFramework() {

    m_bRunning = true;

    m_pWindow   = new RenderWindow(VideoMode(800, 600), "Pong", Style::Titlebar | Style::Close);
    m_pEvent    = new Event;
    m_pClock    = new Clock;

    m_pPlayer   = new CPlayer(String("Assets/Pong.png"), Vector2f(30, 300));
    m_pEnemy    = new CEnemy(String("Assets/Pong.png"), Vector2f(770, 300));
    m_pBall     = new CBall(String("Assets/Ball.png"), Vector2f(400, 300));

}

CFramework::~CFramework() {

    delete m_pWindow;
    delete m_pEvent;
    delete m_pClock;
    delete m_pPlayer;
    delete m_pEnemy;
    delete m_pBall;

    m_pWindow   = nullptr;
    m_pEvent    = nullptr;
    m_pClock    = nullptr;
    m_pPlayer   = nullptr;
    m_pEnemy    = nullptr;
    m_pBall     = nullptr;

}

void CFramework::Run() {

    while (m_bRunning) {

        Update(m_fElapsedTime);
        Render();
        HandleEvents();
        GetElapsedTime();
        Quit();

    }

}

void CFramework::Update(float fElapsedTime) {

    m_pPlayer->Update(fElapsedTime);
    m_pEnemy->Update(fElapsedTime);
    m_pBall->Update(fElapsedTime);

}

void CFramework::Render() {

    m_pWindow->clear();

    m_pPlayer->Render(m_pWindow);
    m_pEnemy->Render(m_pWindow);
    m_pBall->Render(m_pWindow);

    m_pWindow->display();

}

void CFramework::HandleEvents() {

    while (m_pWindow->pollEvent(*m_pEvent)) {

        if (m_pEvent->type == m_pEvent->Closed) {

            m_bRunning = false;

        }

    }

}

void CFramework::Quit() {

    if (m_bRunning == false) {

        m_pWindow->close();

    }

}

float CFramework::GetElapsedTime() {

    m_fElapsedTime = m_pClock->getElapsedTime().asSeconds();
    m_pClock->restart();

    return m_fElapsedTime;
}


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
#pragma once

#include <SFML\Graphics.hpp>

using namespace sf;
using namespace std;

class CPlayer {

public:
    CPlayer         (string sTexture, Vector2f vPosition);
    ~CPlayer        ();

    void Update     (float fElapsedTime);
    void Render     (RenderWindow *pWindow);

private:
    Texture         *m_pTexture;
    Sprite          *m_pSprite;

    float m_fSpeed;

};


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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include "Player.hpp"

CPlayer::CPlayer(string sTexture, Vector2f vPosition) {

    m_pTexture  = new Texture;
    m_pSprite   = new Sprite;

    m_pTexture->loadFromFile(sTexture.c_str());
    m_pSprite->setTexture(*m_pTexture);
    m_pSprite->setOrigin(static_cast<float>(m_pTexture->getSize().x / 2), static_cast<float>(m_pTexture->getSize().y / 2));
    m_pSprite->setPosition(vPosition);

    m_fSpeed = 300.0f;

}

CPlayer::~CPlayer() {

    delete m_pTexture;
    delete m_pSprite;
    
    m_pTexture  = nullptr;
    m_pSprite   = nullptr;

}

void CPlayer::Update(float fElapsedTime) {

    if (Keyboard::isKeyPressed(Keyboard::Key::W) && m_pSprite->getPosition().y - m_pTexture->getSize().y / 2 >= 0) {

        m_pSprite->move(0, -m_fSpeed * fElapsedTime);

    }

    if (Keyboard::isKeyPressed(Keyboard::Key::S) && m_pSprite->getPosition().y + m_pTexture->getSize().y / 2 <= 600) {

        m_pSprite->move(0, m_fSpeed * fElapsedTime);

    }

}

void CPlayer::Render(RenderWindow *pWindow) {

    pWindow->draw(*m_pSprite);

}


Enemy.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
#pragma once

#include <SFML\Graphics.hpp>

#include "Framework.hpp"

using namespace sf;
using namespace std;

class CEnemy {

public:
    CEnemy          (string sTexture, Vector2f vPosition);
    ~CEnemy         ();

    void Update     (float fElapsedTime);
    void Render     (RenderWindow *pWindow);

private:
    Texture         *m_pTexture;
    Sprite          *m_pSprite;

};


Enemy.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
#include "Enemy.hpp"

CEnemy::CEnemy(string sTexture, Vector2f vPosition) {

    m_pTexture  = new Texture;
    m_pSprite   = new Sprite;

    m_pTexture->loadFromFile(sTexture.c_str());
    m_pSprite->setTexture(*m_pTexture);
    m_pSprite->setOrigin(static_cast<float>(m_pTexture->getSize().x / 2), static_cast<float>(m_pTexture->getSize().y / 2));
    m_pSprite->setPosition(vPosition);

}

CEnemy::~CEnemy() {

    delete m_pTexture;
    delete m_pSprite;

    m_pTexture  = nullptr;
    m_pSprite   = nullptr;

}

void CEnemy::Update(float fElapsedTime) {

    

}

void CEnemy::Render(RenderWindow *pWindow) {

    pWindow->draw(*m_pSprite);

}


Ball.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
#pragma once

#include <SFML\Graphics.hpp>

using namespace sf;
using namespace std;

class CBall {

public:
    CBall           (string sTexture, Vector2f vPosition);
    ~CBall          ();

    void Update     (float fElapsedTime);
    void Render     (RenderWindow *pWindow);

private:
    Texture         *m_pTexture;
    Sprite          *m_pSprite;

};


Ball.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
#include "Ball.hpp"

CBall::CBall(string sTexture, Vector2f vPosition) {

    m_pTexture  = new Texture;
    m_pSprite   = new Sprite;

    m_pTexture->loadFromFile(sTexture.c_str());
    m_pSprite->setTexture(*m_pTexture);
    m_pSprite->setOrigin(static_cast<float>(m_pTexture->getSize().x / 2), static_cast<float>(m_pTexture->getSize().y / 2));
    m_pSprite->setPosition(vPosition);

}

CBall::~CBall() {

    delete m_pTexture;
    delete m_pSprite;

    m_pTexture  = nullptr;
    m_pSprite   = nullptr;

}

void CBall::Update(float fElapsedTime) {

    if (Keyboard::isKeyPressed(Keyboard::Key::Up)) {

        m_pSprite->move(0, -300.0f * fElapsedTime);

    }

    if (Keyboard::isKeyPressed(Keyboard::Key::Down)) {

        m_pSprite->move(0, 300.0f * fElapsedTime);

    }

    if (Keyboard::isKeyPressed(Keyboard::Key::Left)) {

        m_pSprite->move(-300.0f * fElapsedTime, 0);

    }

    if (Keyboard::isKeyPressed(Keyboard::Key::Right)) {

        m_pSprite->move(300.0f * fElapsedTime, 0);

    }

}

void CBall::Render(RenderWindow *pWindow) {

    pWindow->draw(*m_pSprite);

}


Hoffe jemand kann mir helfen :) Und danke in voraus.

mfg N4SONIC ;)

2

25.12.2015, 23:57

Habe ich jetzt gemacht aber jetzt kommt dieser Error: Schweregrad Code Beschreibung Projekt Datei Zeile Unterdrückungszustand
Fehler C2061 Syntaxfehler: Bezeichner "CBall" Pong c:\users\n4son\dropbox\programming\c++ projekte\pong\pong\enemy.hpp 16

Und ja ich habe mir das von Heiko Kalistas Buch angewöhnt :D Was für ein still wäre denn eine saubere art zu Programmieren ?

Ball.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
#pragma once

#include <SFML\Graphics.hpp>

#include "Enemy.hpp"

using namespace sf;
using namespace std;

class CBall {

    friend class CEnemy;

public:
    CBall           (string sTexture, Vector2f vPosition);
    ~CBall          ();

    void Update     (float fElapsedTime);
    void Render     (RenderWindow *pWindow);

private:
    Texture         *m_pTexture;
    Sprite          *m_pSprite;

};


Enemy.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
#pragma once

#include <SFML\Graphics.hpp>

#include "Ball.hpp"

using namespace sf;
using namespace std;

class CEnemy {

public:
    CEnemy          (string sTexture, Vector2f vPosition);
    ~CEnemy         ();

    void Update     (float fElapsedTime, CBall *pBall);
    void Render     (RenderWindow *pWindow);

private:
    Texture         *m_pTexture;
    Sprite          *m_pSprite;

};


Enemy.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
#include "Enemy.hpp"

CEnemy::CEnemy(string sTexture, Vector2f vPosition) {

    m_pTexture  = new Texture;
    m_pSprite   = new Sprite;

    m_pTexture->loadFromFile(sTexture.c_str());
    m_pSprite->setTexture(*m_pTexture);
    m_pSprite->setOrigin(static_cast<float>(m_pTexture->getSize().x / 2), static_cast<float>(m_pTexture->getSize().y / 2));
    m_pSprite->setPosition(vPosition);

}

CEnemy::~CEnemy() {

    delete m_pTexture;
    delete m_pSprite;

    m_pTexture  = nullptr;
    m_pSprite   = nullptr;

}

void CEnemy::Update(float fElapsedTime, CBall *pBall) {

    m_pSprite->setPosition(pBall->m_pSprite->getPosition().x, 0);

}

void CEnemy::Render(RenderWindow *pWindow) {

    pWindow->draw(*m_pSprite);

}

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »N4SONIC« (26.12.2015, 00:14)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

26.12.2015, 08:55

Wieso genau muss ein Enemy auf die Koordinaten innerhalb eines Ball Objektes zugreifen?

Abgesehen davon: Wieso erzeugst du Objekte überall new? Wenn schon, dann besser std::unique_ptr verwenden. Die Pointer nach dem delete im Destruktor zu nullen, ist völlig überflüssig.

4

26.12.2015, 12:20

Damit ich die Collision abfragen kann :o

Also soll ich anstatt std::unique_ptr benutzen ? Und im Destruktor die pointer nicht mehr auf null setzten ?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

26.12.2015, 12:25

Damit ich die Collision abfragen kann :o

Na gib dem Ball doch einfach eine checkCollision() Methode!? ;)

Also soll ich anstatt std::unique_ptr benutzen ? Und im Destruktor die pointer nicht mehr auf null setzten ?

Naja, was genau hast du denn für einen Grund, diese Objekte alle per new anzulegen? Sollen diese Objekte dynamische Lebensdauer haben? Was genau ist der Sinn, den du im Null-setzen der Pointer siehst?

Btw: Um Member zu initialisieren, verwendet man die Initialisierungsliste im Constructor.

6

26.12.2015, 12:29

Zitat

Na gib dem Ball doch einfach eine checkCollision() Methode!? ;)


Ok. Aber ich muss doch dann in der Parameterliste die CEnemy Klasse übergebn oder nicht ? :o

Zitat

Naja, was genau hast du denn für einen Grund, diese Objekte alle per new anzulegen? Sollen diese Objekte dynamische Lebensdauer haben? Was genau ist der Sinn, den du im Null-setzen der Pointer siehst?


Von Tutorials habe ich das ^^

Wie sollte ich das den am besten machen könntest du mir ein beispiel schreiben ? :D

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

26.12.2015, 12:34

Ok. Aber ich muss doch dann in der Parameterliste die CEnemy Klasse übergebn oder nicht ? :o

Ich würde sagen, du musst übergeben, was auch immer für die Kollisionsabfrage relevant ist. Vermutlich also eher einfach das Rechteck, das getestet werden soll, dem Ball kann ja völlig egal sein, ob er jetzt gegen einen Enemy oder was auch immer sonst getestet werden soll...

Von Tutorials habe ich das ^^

Wie sollte ich das den am besten machen könntest du mir ein beispiel schreiben ? :D

Was genau ist unklar? Und diese Tutorials machen einfach, ohne zu erklären, wieso? In dem Fall, würde ich empfehlen, sich bessere Quellen zum Lernen zu beschaffen. Ein gutes Buch zum Beispiel... ;)

8

26.12.2015, 12:42

Was mir noch unklar ist wie ich das std::unique_ptr einsetzten soll ?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

9

26.12.2015, 12:45

Nun, vermutlich solltest du das auch gar nicht. Nur rohes new und delete sollte man in C++ Code eigentlich niemals sehen, wenn dann eher unique_ptr. Im konkreten Fall ist aber vermutlich das new überhaupt gänzlich unangebracht. Daher nochmal die Frage: Wieso erzeugst du diese Objekte alle per new, anstatt die Dinger einfach direkt zu Membern zu machen?

10

26.12.2015, 12:47

Aso. Ich benutze es weil ich denn speicher reservieren muss oder nicht ? :o

Werbeanzeige