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

05.01.2010, 14:07

[GELÖST][C++] List-Funktion nimt klasse nur einmal auf

Hi leute habe mal versucht das spiel was bei buch dabei war von Heiko Kalista nach zu programmieren aber auf eigenen wege und bin da leider an ein Problem mit der list Funktion gestoßen.

sie nimt eine klasse nur einmal auf und arbeitet auch nur mit der.
die klaksse soll einen schuß verwalten und somit müste ich sie ja halt mehrfach da haben.

hier mal der source code:

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
 #include <iostream>
 #include <stdlib.h>
 #include <windows.h>
 #include <SDL/SDL.h>
 #include <time.h>
 #include <list.h>

 using namespace std;

float time3 = 0;
int shotzahl = 0;
float shottime = 0;

SDL_Surface *shot;
SDL_Rect shotrec;

 class cShot
{
    public:
    bool live;

    cShot (int x)
    {
        shotrec.x = x;
        live = true;
    }

    void update ()
    {
        shotrec.y -= 150.0f * time3;
        if (shotrec.y == 0)
        {
          shot = NULL;
          live = false;
        }
    }
};


 int main(int argc, char *argv[])
 {
    //var

    SDL_Surface *screen, *image, *bgimg;
    SDL_Rect dst, dstblue, drect, srect;
    SDL_Event event;
    Uint8 *keys;
    int tuxX = 288, tuxY = 416;
    int done = 0;
    //zeit

    float time1 = 0, time2 = 0;

    //klasse shot

    list<cShot*> lShot;
    list<cShot*>::iterator i;
    cShot *Temp = NULL;

        shot = SDL_LoadBMP("Laser.bmp");
        if (shot == NULL)
        {
            MessageBoxA(NULL,"Can't load image of Shot","",0);
        }
        SDL_SetColorKey(shot, SDL_SRCCOLORKEY, SDL_MapRGB(shot->format, 255, 0, 255));

        shotrec.y = 512;
        shotrec.h = shot->h;
        shotrec.w = shot->w;


    time1 = SDL_GetTicks() / 1000.0f;

     if (SDL_Init(SDL_INIT_VIDEO) == -1)
     {
         MessageBoxA(NULL,"Can't init SDL","",0);
         return 0;
     }
     atexit(SDL_Quit);

     screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
     SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 255));
     if (screen == NULL)
     {
         MessageBoxA(NULL,"Can't set video mode","",0);
         return 0;
     }

     bgimg = SDL_LoadBMP("bg.bmp");
     if (image == NULL)
     {
         MessageBoxA(NULL,"Can't load image of BG","",0);
         return 0;
     }

     image = SDL_LoadBMP("Player.bmp");
     if (image == NULL)
     {
         MessageBoxA(NULL,"Can't load image of Player","",0);
         return 0;
     }
     dst.w = image->w;
     dst.h = image->h;
     dstblue.w = image->w + 1;
     dstblue.h = image->h + 1;
     SDL_SetColorKey(image, SDL_SRCCOLORKEY, SDL_MapRGB(image->format, 255, 0, 255));


    // Setzen des Quellbereichs

    srect.x = 320;
    srect.y = 0;
    srect.w = 64;  // das halbe Bild

    srect.h = image->h;   // das gesamte Bild


     while (!done)
     {
         while (SDL_PollEvent(&event))
         {
             switch(event.type)
             {
             case SDL_QUIT:
                 done = 1;
                 break;
             }
         }
        dstblue.x = tuxX;
        dstblue.y = tuxY;
        keys = SDL_GetKeyState(NULL);
        /*if (keys[SDLK_UP])
        {
            if (tuxY > 10)
            {
                tuxY--;
            }
        }
        if (keys[SDLK_DOWN]) {
            if (tuxY < 470 - image->h)
            {
                tuxY++;
            }
        }*/

        if (keys[SDLK_RIGHT])
        {
            if(tuxX < 640 - 64)
            {
                tuxX += 230.0f * time3;
                if (srect.x < 640)
                {
                    srect.x += 64.0f;
                }
            }
        }
        else if (keys[SDLK_LEFT])
        {
            if (tuxX > 10)
            {
                tuxX -= 150.0f * time3;
                if (srect.x > 0)
                {
                    srect.x -= 64.0f;
                }
            }
        }
        else
        {
            srect.x = 320;
        }

        if (keys[SDLK_ESCAPE])
        {
            done = 1;
        }

        //schießen wuhaaa

        if (keys[SDLK_SPACE])
        {
            shottime += time3;
            if (shottime >= 0.2f)
            {
                shotzahl++;
                Temp = new cShot (tuxX);
                lShot.push_back (Temp);
                shottime = 0;
            }

        }

        // Setzen des Zielbereichs

        drect.x = tuxX;
        drect.y = tuxY;
        drect.w = 64;
        drect.h = image->h;

        dst.x = tuxX;
        dst.y = tuxY;
        SDL_FillRect(screen, &dstblue, SDL_MapRGB(screen->format, 0, 0, 255));
        SDL_BlitSurface(bgimg, NULL, screen, NULL);
        //SDL_BlitSurface(image, NULL, screen, &dst);

        SDL_BlitSurface(image, &srect, screen, &drect);

        //für shoot

        for (i=lShot.begin(); i!=lShot.end(); ++i)
        {
            (*i)->update ();
            SDL_BlitSurface(shot, NULL, screen, &shotrec);

        }

        SDL_UpdateRects(screen,1,&drect);

        SDL_Flip(screen);
        time2 = SDL_GetTicks() / 1000.0f;
        time3 = time2 - time1;
        time1 = time2;
     }
     SDL_FreeSurface(image);
     SDL_FreeSurface(bgimg);
     SDL_QUIT;
     return 0;
 }


vielleicht kann mir einer von euch sagen was ich falsch mache bez wie ich es richtig machen sollte damit es so geht wie ich es möchte

gruß
Mitsuomi-san

ChrisJ

Alter Hase

Beiträge: 487

Wohnort: Schweich

Beruf: Schüler

  • Private Nachricht senden

2

05.01.2010, 14:15

1. shotrec ist global,
2. shot wird auf NULL gesetzt, sobal ein schuss aus dem bild ist
"Don't trust your eyes: They are a hell of a lot smarter than you are"

3

05.01.2010, 14:27

Zitat von »"ChrisJ"«

1. shotrec ist global,
2. shot wird auf NULL gesetzt, sobal ein schuss aus dem bild ist


zu 1. ja habe ich absichtlich hängt aber nicht mit mein problem zusammen

2. hilft auch nicht bei mein problem haber ich aber geändert!^^

edit:
achjaa und eine frage ist mir auf gekommen wie kann ich von klassen die in list eingetragen sind eine bestimme variable abfrage die sie enthält??

4

05.01.2010, 14:33

C-/C++-Quelltext

1
cShot *Temp = NULL; 

Wenn du das Löscht, und dann bei

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
        //schießen wuhaaa

        if (keys[SDLK_SPACE])
        {
            shottime += time3;
            if (shottime >= 0.2f)
            {
                shotzahl++;
                cShot* Temp = new cShot (tuxX);
                lShot.push_back (Temp);
                shottime = 0;
            }

        } 
[/quote]

the[V]oid

Alter Hase

Beiträge: 775

Wohnort: Aachen

  • Private Nachricht senden

5

05.01.2010, 14:33

1. Es ist keine List-Funktion, sondern eine List-Klasse(ntemplate)!
2. Dieses nimmt keine Klassen auf, sondern nur Objekte!

Hab grad leider keine Zeit mal drüber zu gucken, aber mir ist folgendes direkt ins Auge gesprungen:

Wenn du schon C++ codest (was du offensichtlich tust, da du Klassen verwendest), solltest du auch die C++-Versionen der Standardheader benutzen:

#include <list>
an Stelle von
#include <list.h>

und

#include <cstdlib>
an Stelle von
#include <stdlib.h>
<< an dieser Stelle ist eine Signatur verstorben >>

6

05.01.2010, 14:51

danke @E122 & the[V]oid aber hat mir leider immernoch kein stück geholfen >.<

GR-PA

Treue Seele

Beiträge: 326

Wohnort: Daheim

Beruf: Faulenzer

  • Private Nachricht senden

7

05.01.2010, 16:41

Eine kurze Zusammenfassung dessen, was dein Code macht:

1. Du erstellst eine Liste von Zeigern auf Objekte der Klasse cShot

C-/C++-Quelltext

1
list<cShot*> lShot; 


2. Wenn ein neuer Schuss abgefeuert werden soll, dann erstellst du ein Objekt von cShot im Freispeicher, und überschreibst dabei den Zeiger auf das zuvor erstellte Objekt:

C-/C++-Quelltext

1
Temp = new cShot (tuxX);

delete ist übrigens auch ganz sinnvoll...

3. Du fügst am Ende der Liste den Zeiger auf den allokierten Speicher hinzu.

C-/C++-Quelltext

1
lShot.push_back (Temp);


Eine sinnvollere Lösung:

C-/C++-Quelltext

1
2
3
4
5
6
list<cShot> lShot; // eine Liste von Objekten der Klasse cShot erstellen


// ...


// Hinzufügen eines neuen Schusses:

lShot.push_back(cShot(tuxX));

Und fertig...
Einfach und effizient

Achja:
Du verwendest die STL => du programmierst in C++ (und nicht in C) => du musst Variablen auch nicht am Anfang einer Funktion definieren => gewöhne dir das am besten so schnell wie möglich ab, da das leicht zu unübersichtlichem, schlecht erweiterbarem, schlecht änderbarem und somit fehleranfälligem Code führt.
Signaturen werden überbewertet

8

05.01.2010, 16:51

Zitat von »"GR-PA"«

Eine kurze Zusammenfassung dessen, was dein Code macht:

1. Du erstellst eine Liste von Zeigern auf Objekte der Klasse cShot

C-/C++-Quelltext

1
list<cShot*> lShot; 


2. Wenn ein neuer Schuss abgefeuert werden soll, dann erstellst du ein Objekt von cShot im Freispeicher, und überschreibst dabei den Zeiger auf das zuvor erstellte Objekt:

C-/C++-Quelltext

1
Temp = new cShot (tuxX);

delete ist übrigens auch ganz sinnvoll...

3. Du fügst am Ende der Liste den Zeiger auf den allokierten Speicher hinzu.

C-/C++-Quelltext

1
lShot.push_back (Temp);


Eine sinnvollere Lösung:

C-/C++-Quelltext

1
2
3
4
5
6
list<cShot> lShot; // eine Liste von Objekten der Klasse cShot erstellen


// ...


// Hinzufügen eines neuen Schusses:

lShot.push_back(cShot(tuxX));

Und fertig...
Einfach und effizient

Achja:
Du verwendest die STL => du programmierst in C++ (und nicht in C) => du musst Variablen auch nicht am Anfang einer Funktion definieren => gewöhne dir das am besten so schnell wie möglich ab, da das leicht zu unübersichtlichem, schlecht erweiterbarem, schlecht änderbarem und somit fehleranfälligem Code führt.


das ich die STL verwände war mir schon klar ;) plos im buch wird diese funktion meiner meinung nach nicht richtig erklärt! und somit habe ich noch probleme mit ihr :(

und leider hat dein tip mir auch nicht viel geholfen das problem besteht immer noch!

er erstellt nur ein schuß und das wars dan auch schon!

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

9

05.01.2010, 16:58

du hast ja auch nur ein rect für die schüsse: SDL_Rect shotrec; (wurde schon gesagt und es hängt ganz bestimmt mit dem problem zusammen)
das gehört in die klasse cShot und du solltest eine renderfunktion für cShot schreiben.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

10

05.01.2010, 17:36

Zitat von »"NachoMan"«

du hast ja auch nur ein rect für die schüsse: SDL_Rect shotrec; (wurde schon gesagt und es hängt ganz bestimmt mit dem problem zusammen)
das gehört in die klasse cShot und du solltest eine renderfunktion für cShot schreiben.


ach herlich,
danke

nun habe ich nur noch das problem das ich die klasse nicht delete mehr löschen kann weil er ja eine pointer auf der klasse erwartet

mein befehl ist delete (*i); und die fehlermelung die ich bekomme ist:

Quellcode

1
C:\Users\Neofox\Desktop\sdl_trash\main.cpp|208|error: type `class cShot' argument given to `delete', expected pointer|


bitte was mach ich falsch O.o
wen ich die klasse nicht delete hängt sich das spiel auf so gehe ich zu mindestens mal von aus das es sich deswegen aufhängt

Werbeanzeige