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

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

11

25.10.2013, 22:00

Ich glaube noch immer nicht, dass ein Template hier die richtige Lösung ist. Sinnvoller klingt für mich eher ein Interface und polymorphe Typen.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

12

25.10.2013, 22:01

Ich würde soweit gehen, zu sagen, dass diese Liste von Shots in der Weapon Klasse rein prinzipiell schon völlig fehl am Platz ist... ;)

13

25.10.2013, 22:03

Die Klasse Weapon beinhaltet nur alle Schüsse, die Instanzen der Schüsse sind von der Klasse Shot.hpp und werden in der Klasse Weapon erstellt, wenn Space gedrückt wurde.

Ich Poste mal die Weapon.hpp und Weapon.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
#ifndef WEAPON_HPP
#define WEAPON_HPP
#include"Weapon/DarkPoulder.hpp"
#include"Weapon/PurpleEnergy.hpp"
#include "../LXMRox/Sprite/Includes/Sprite.hpp"Sprite.hpp"
#include<list>

class Weapon{

public:
    Weapon();
    ~Weapon();
    void Shot();
    void InitAllWeapon();
    void Update(float x, float y);
    void Check();
    void Render();
template<typename T>
list<T> *GetShotList()
{

    list<T> *m_ShotList;
    m_ShotList=&m_Poulder;
return m_ShotList;
}
    //list<DPoulder> *GetShotList () {return &m_Poulder;}
    //list<PurpleE> *GetShotList1(){return &m_Purple;}

private:
    list<DPoulder> m_Poulder; //Schussliste von DPoulder
    list<PurpleE> m_Purple;   //Schussliste von Purple
    list<CSprite*> m_Weaps;    //Sprites der Waffen
    CSprite *m_wBorder;
    CSprite *m_pExplode;
    bool m_bShotLock;         // Darf der nächste Schuss raus?
    int Weapons;
    int ActivWeapon;
    float m_fXPos;
    float m_fYPos;


};
#endif // WEAPON_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
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#include"Weapon.hpp"
#include<fstream>
using namespace std;

Weapon::Weapon()
{
  m_wBorder=new CSprite;
  m_wBorder->LoadPNG("../Data/Game/Weapons/Border.png",0,72,72,"Weapon_Border");
  m_wBorder->SetPos(650,84);

  m_pExplode=new CSprite;
  m_pExplode->LoadPNG("../Data/Game/Weapons/ExplodeBlue.png", 4, 72, 72,"BlueExplode");
  Weapons=0;
  ActivWeapon=1;
}
Weapon::~Weapon()
{
   if(m_wBorder!=NULL)
   {
       delete(m_wBorder);
       m_wBorder=NULL;
   }

  if(m_pExplode!=NULL)
  {
      delete(m_pExplode);
      m_pExplode=NULL;
  }
                // Iterator für Schussliste
                list<CSprite*>::iterator it = m_Weaps.begin ();

                // Schussliste durchlaufen
                while (it != m_Weaps.end ())
                {


                        delete(*it);

                    it++;
                }
}

void Weapon::InitAllWeapon()
{
    //Vorbereitungen Daten Laden
ifstream InitWeapon;
string LoadingFiles;
int X;
int Y;
int W;
int H;
int NumAnim=0;
InitWeapon.open("../Data/Game/Weapons/Weapon.txt");
InitWeapon>>Weapons;
for(int i=0; i<Weapons; i++)
{
 InitWeapon>>LoadingFiles;
 InitWeapon>>W;
 InitWeapon>>H;
 InitWeapon>>X;
 InitWeapon>>Y;
 InitWeapon>>NumAnim;
 CSprite *Weap;
 Weap=new CSprite;
 Weap->Load(LoadingFiles.c_str(),NumAnim,W,H,LoadingFiles.c_str());
 Weap->SetPos(X,Y);
 Weap->SetColorKey(255,0,255);
 m_Weaps.push_back(Weap);
}
InitWeapon.close();
cout <<m_Weaps.size();
}
void Weapon::Shot()
{
    freopen( "CON", "wt", stdout );
freopen( "CON", "wt", stderr );
  // Wurde Space gedrückt und darf geschossen werden?
  if (g_pFramework->KeyDown (SDLK_SPACE) && m_bShotLock == false)
  {
    // Neuen Schuss erzeugen und initialisieren

    switch(ActivWeapon)
    {
    case(0):
        {
                DPoulder Hannel;
                list<CSprite*>::iterator henga;
                henga=m_Weaps.begin();




                Hannel.Init (*henga, m_fXPos, m_fYPos);
                Hannel.ExplodeInit(m_pExplode);

                // Schuss in Liste einfügen
                m_Poulder.push_back (Hannel);
        }break;
    case(1):
        {
            DPoulder Hannel;
                list<CSprite*>::iterator henga;
                henga=m_Weaps.begin();
                henga++;



                Hannel.Init (*henga, m_fXPos, m_fYPos);
                Hannel.ExplodeInit(m_pExplode);

                // Schuss in Liste einfügen
                m_Poulder.push_back (Hannel);


        }break;
    }

    // Schießen erst wieder erlaubt, wenn Space losgelassen
    m_bShotLock = true;

  }

  // Ist die Leertaste nicht mehr gedrückt, schießen wieder erlaubt
  if (g_pFramework->KeyDown (SDLK_SPACE) == false)
    m_bShotLock = false;
}
void Weapon::Update(float x, float y)
{
    m_fXPos=x;
    m_fYPos=y;
    //Wurde Geschossen?
    Shot();
}
void Weapon::Check()
{

}
void Weapon::Render()
{
    int i=0;
    while(i<Weapons)
    {
        switch(i)
        {
        case(0):
            {
                if(m_Poulder.size()>0)
                {
                // Iterator für Schussliste
                list<DPoulder>::iterator it = m_Poulder.begin ();

                // Schussliste durchlaufen
                while (it != m_Poulder.end ())
                {


                // Ist der Schuss noch aktiv?
                    if (it->GetIsFly())
                    {
                    // Schuss updaten
                    it->Update ();
                    // Ja, dann rendern
                    it->Render ();

                    }

                    else
                    {

                        it->UpdateExplode();


                    }
                    if(it->IsAlive()==false)
                    {
                        it = m_Poulder.erase (it);
                    }
   it++;
  }
  }
            }break;
        case(1):
            {
                if(m_Purple.size()>0)
                {
                // Iterator für Schussliste
                list<PurpleE>::iterator it = m_Purple.begin();

                // Schussliste durchlaufen
                while (it != m_Purple.end())
                {


                // Ist der Schuss noch aktiv?
                    if (it->GetIsFly())
                    {
                    // Schuss updaten
                    it->Update ();
                    // Ja, dann rendern
                    it->Render ();

                    }

                    else
                    {

                        it->UpdateExplode();


                    }
                    if(it->IsAlive()==false)
                    {
                        it = m_Purple.erase (it);
                    }
   it++;
  }
  }

            }break;
        }
        i++;
    }
    m_wBorder->Render();
}



Die Schüsse zu erstellen, war vorher in der Spielerklasse integriert, ich habe diese dann in die Klasse Weapon gepackt, um die Schüsse zu erzeugen.
In der Klasse Weapon sollen später alle Schüsse vorhanden sein, logischerweise, muss ich auch dort dann die Instanzen der Schüsse erzeugen.
Die Klasse ist dafür zuständig, welcher Schuss abgegeben wird also sprich, welche Schuss Instanz erzeugt wird.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

14

25.10.2013, 22:07

Die Schüsse zu erstellen, war vorher in der Spielerklasse integriert, ich habe diese dann in die Klasse Weapon gepackt, um die Schüsse zu erzeugen.

klingt sinnvoll

Die Klasse ist dafür zuständig, welcher Schuss abgegeben wird also sprich, welche Schuss Instanz erzeugt wird.

Da stimme ich zu.

In der Klasse Weapon sollen später alle Schüsse vorhanden sein, logischerweise, muss ich auch dort dann die Instanzen der Schüsse erzeugen.

Wieso? Die Weapon Klasse erzeugt Schüsse, aber wieso muss sie auch der Container aller von ihr erzeugten Schüsse sein? Die Tatsache, dass du dann einen Getter brauchst, zeigt imo bereits, dass die Daten rein logisch eigentlich wo anders hingehören... ;)

15

25.10.2013, 22:07

Wie würdet ihr das ganze denn nun angehen?

polymorphie?

Ich könnte theoretisch, die BasisKlasse nehmen, diese beinhaltet alle Wichtigen Elemente für die Kollision, bloss wäre dann das problem, das die abgeleiteten Klassen, noch eine Explosion verursachen, wenn eine Kollision stattgefunden hat.

Würde ich die Klasse auf die Basisklasse wieder beschränken und so die Kollision prüfen, so könnte ich ja nicht das Event für die Explosion auslösen, weil die Funktion dafür nur in der abgeleiteten Klasse vorhanden ist:


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
void CGame::CheckCollisions ()
{

  // Schussliste des Spielers holen
  list<DPoulder> *ShotList = m_pPlayer->GetShotList ();

  // Iteratoren für Asteroiden- und Schussliste
  list<CAsteroid>::iterator ItAsteroid = m_AsteroidList.begin ();
  list<DPoulder>::iterator ItShot;

  // Rects für Asteroiden und Schüsse
  SDL_Rect RectAsteroid;
  SDL_Rect RectShot;

  // Alle Asteroiden durchlaufen
  while (ItAsteroid != m_AsteroidList.end () )
  {
    // Rect des Asteroiden holen
    RectAsteroid = ItAsteroid->GetRect ();

    // Alle Schüsse durchlaufen
    for (ItShot = ShotList->begin ();
         ItShot != ShotList->end ();
         ++ItShot)
    {
      // Rect des Schusses holen
      RectShot = ItShot->GetRect ();


      // Überschneiden sich die Rects?
      if (RectShot.y < RectAsteroid.y + RectAsteroid.h &&
          RectShot.y + RectShot.h > RectAsteroid.y &&
          RectShot.x < RectAsteroid.x + RectAsteroid.w &&
          RectShot.x + RectShot.w > RectAsteroid.x)
      {
        // Ja, also gab es eine Kollision. Somit Schuss und
        // Asteroid deaktivieren
        ItAsteroid->SetAlive (false);

        ItShot->SetIsFly();                                                        //Funktion um die Explosion auszulösen
        ItShot->GetKoordinates(RectAsteroid.x, RectAsteroid.y); //Funktion um die Koordinaten der Explosion zu setzen

      }

    }

    // Asteroid löschen, falls deaktiviert
    if (ItAsteroid->IsAlive () )
      ItAsteroid++;
    else
      ItAsteroid = m_AsteroidList.erase (ItAsteroid);

  }

} // CheckCollision

16

25.10.2013, 22:10

Ich habe ja meine abfrage, ob Space gedrückt wurde in der Weapon Klassen, diese hat ja auch die Daten, welche Waffe jetzt gerade Aktiv ist, und somit dann auch die richtige Instanz des richtigen Schusses erzeugt.

Jetzt würde ich mich fragen, wie sollte ich das ganze in die Game Klasse verlegen, das wären ja auch rein logisch mehr abfragen, als eine Getter Abfrage oder nicht?
Vielleicht hänge ich bei der Lösung gerade auf dem Schlauch ^^

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

17

25.10.2013, 22:18

Ich habe ja meine abfrage, ob Space gedrückt wurde in der Weapon Klassen, diese hat ja auch die Daten, welche Waffe jetzt gerade Aktiv ist [...]

Wieso? Sollte nicht eher der Besitzer der Weapons wissen, welche Waffe er gerade verwendet!?

[...], und somit dann auch die richtige Instanz des richtigen Schusses erzeugt.

Repräsentiert eine Instanz deiner Weapon Klasse eine Waffe oder alle Waffen eines Spielers?

Schau dir mal das Double Dispatch Pattern an. ;)

Wieso erzeugst du m_wBorder und m_pExplode per new, könnten das nicht einfach normale Member der Klasse sein?
Wenn es tatsächlich new sein muss: Verwend Smartpointer (in dem Fall wohl std::unique_ptr).
In C++ verwendet man nullptr und nicht NULL.
Pointer nach dem delete zu nullen, ist nicht zu empfehlen.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

18

25.10.2013, 22:24

Ich könnte theoretisch, die BasisKlasse nehmen, diese beinhaltet alle Wichtigen Elemente für die Kollision, bloss wäre dann das problem, das die abgeleiteten Klassen, noch eine Explosion verursachen, wenn eine Kollision stattgefunden hat.
Wo genau ist da jetzt das Problem? Einige Unterklassen erzeugen Explosionen, andere nicht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

19

25.10.2013, 22:25

Also, die Weapon Klasse Repräsentiert sozusagen alle Waffen in Form von Listen.
Es wird in der Weapon Klasse abgefragt, ob Space gedrückt wurde, falls ja wird eine Instanz in der Weapon Klasse vom Shot je nachdem mit welcher abgleiteten Klasse erstellt, und in die jeweilige Liste geschoben.

Momentan ist die Weapon Klasse dafür da, um die Instanzen Shot zu erzeugen.

Weapon hpp

C-/C++-Quelltext

1
2
    list<DPoulder> m_Poulder; //Schussliste von DPoulder     //die Eigentliche Shot Instanzen, werden in diese Liste eingefügt
    list<PurpleE> m_Purple;   //Schussliste von Purple


Shot.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
#ifndef SHOT_HPP
#define SHOT_HPP

#include "../../LXMRox/Sprite/Includes/Sprite.hpp"

class CShot
{
  public:
      virtual ~CShot();
    void Init     (CSprite *pSpriteShot, float fXPos, float fYPos);
    void Update   ();
    void Render   ();
    bool IsAlive  () {return m_bIsAlive;}
    void SetAlive (bool bIsAlive) {m_bIsAlive = bIsAlive;}
    void SetIsFly(){m_bIsFly=false;}
    SDL_Rect GetRect () {return m_Rect;}
    bool GetIsFly(){return m_bIsFly;}
    float GetX(){return m_fXPos;}
    float GetY(){return m_fYPos;}
float    m_fXPos;       // X-Position des Schusses
    float    m_fYPos;       // Y-Position des Schusses
  private:
    CSprite *m_pSpriteShot; // Zeiger auf Laser-Sprite

    bool     m_bIsFly;
    bool     m_bIsAlive;    // "Lebt" der Schuss noch?
    SDL_Rect m_Rect;        // Rect des Schusses
};

#endif



Weapon CPP
Erzeugung Schuss

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
void Weapon::Shot()
{

  // Wurde Space gedrückt und darf geschossen werden?
  if (g_pFramework->KeyDown (SDLK_SPACE) && m_bShotLock == false)
  {
    // Neuen Schuss erzeugen und initialisieren

    switch(ActivWeapon)
    {
    case(0):
        {
                DPoulder Hannel;
                list<CSprite*>::iterator henga;
                henga=m_Weaps.begin();




                Hannel.Init (*henga, m_fXPos, m_fYPos);
                Hannel.ExplodeInit(m_pExplode);

                // Schuss in Liste einfügen
                m_Poulder.push_back (Hannel);
        }break;
    case(1):
        {
            DPoulder Hannel;
                list<CSprite*>::iterator henga;
                henga=m_Weaps.begin();
                henga++;



                Hannel.Init (*henga, m_fXPos, m_fYPos);
                Hannel.ExplodeInit(m_pExplode);

                // Schuss in Liste einfügen
                m_Poulder.push_back (Hannel);


        }break;
    }

    // Schießen erst wieder erlaubt, wenn Space losgelassen
    m_bShotLock = true;

  }

  // Ist die Leertaste nicht mehr gedrückt, schießen wieder erlaubt
  if (g_pFramework->KeyDown (SDLK_SPACE) == false)
    m_bShotLock = false;
}

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

20

25.10.2013, 22:27

Je tiefer man bohrt, desto schlimmer wird's. :D
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige