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

18.08.2013, 17:46

SDL Kollisions Berechnung Programm stürzt ab

Hallo Miteinander!
Ich hab schon länger das Problem, dass mein Programm abstürzt sobald ich auf Kollision überprüfen will. Wenn ich die Funktion rausnehme ist alles Super (abgesehen, dass es keine Kollision gibt). Sobald ich sie wieder einfüge. Batz! Abgeschmiert.
Der Spieler sollte.. ehm.. Süßigkeiten aufsammeln. Damit ihr beim Quellcode wegen der Benennung nicht blöd guckt xp

Die Klasse für die Süßigkeiten:

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
#pragma once
#include "SDL.h"
#include "Sprite.hpp"

class CSprite;

class CCandy
{
public:
    void Init (CSprite *pSpriteCandy, float fXPos, float fYPos);
    void Render ();
    bool IsAlive () {return m_bIsAlive;}
    void SetAlive (bool bIsAlive) {m_bIsAlive = bIsAlive;}
    SDL_Rect GetRect () {return m_Rect;}

private:
    CSprite *m_pSpriteCandy;
    float m_fXPos;
    float m_fYPos;
    int FrameRect;
    bool m_bIsAlive;
    SDL_Rect m_Rect;
};


#include "Candy.hpp"


void CCandy::Init (CSprite *pSpriteCandy, float fXPos, float fYPos)
{
    m_pSpriteCandy = pSpriteCandy;
    m_fXPos = fXPos;
    m_fYPos = fYPos;

    FrameRect = rand()%3;

    m_Rect.x = static_cast<int>(fXPos);
    m_Rect.y = static_cast<int>(fYPos);
    m_Rect.w = 32;
    m_Rect.h = 32;

    m_bIsAlive = true;
}

void CCandy::Render ()
{
    m_pSpriteCandy->SetPos (m_fXPos, m_fYPos);
    m_pSpriteCandy->Render (static_cast<float>(FrameRect));
}


Und die Klasse für die Spiellogik:

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
#pragma once
#include "SDL.h"
#include "Player.hpp"
#include "Sprite.hpp"
#include "Candy.hpp"
#include <list>

class CCandy;
class CSprite;
class CPlayer;

class CGame
{
public:
    CGame ();
    void Init ();
    void Run ();
    void Quit ();

private:
    void ProcessEvents ();
    void SpawnCandy ();
    void RenderCandy ();
    void CheckCollision ();

    CPlayer *m_pPlayer;
    CSprite *m_pSpriteBackground;
    CSprite *m_pSpriteCandy;
    float m_fCandyTimer;
    bool m_bGameRun;
    list<CCandy> m_CandyList;
};


#include "game.hpp"
#include <time.h>

CGame::CGame ()
{
    m_pPlayer = NULL;
    m_pSpriteBackground = NULL;
    m_pSpriteCandy = NULL;

    srand((unsigned)time(NULL));
}

void CGame::Init ()
{
    m_pPlayer = new CPlayer;
    m_pPlayer->Init ();
    m_pPlayer->Reset ();

    m_pSpriteBackground = new CSprite ();
    m_pSpriteBackground->Load ("Background.bmp");

    m_pSpriteCandy = new CSprite ();
    m_pSpriteCandy->Load ("Candy.bmp", 2, 32, 32);
    m_pSpriteCandy->SetColorKey (255, 255, 255);

    m_fCandyTimer = 4.0f;

    m_bGameRun = true;
}

void CGame::Quit ()
{
    if (m_pPlayer != NULL)
    {
        delete (m_pPlayer);
        m_pPlayer = NULL;
    }

    if (m_pSpriteBackground != NULL)
    {
        delete (m_pSpriteBackground);
        m_pSpriteBackground = NULL;
    }

    if (m_pSpriteCandy != NULL)
    {
        delete (m_pSpriteCandy);
        m_pSpriteCandy = NULL;
    }
}

void CGame::Run ()
{
    while (m_bGameRun == true)
    {
        ProcessEvents ();

        g_pFramework->Update ();

        m_pSpriteBackground->Render ();

        m_pPlayer->Update ();

        CheckCollision ();

        SpawnCandy ();

        RenderCandy ();

        m_pPlayer->Render ();

        g_pFramework->Flip ();
    }
}

void CGame::ProcessEvents ()
{
    SDL_Event Event;

    if (SDL_PollEvent (&Event))
    {
        switch (Event.type)
        {
        case (SDL_QUIT):
            {
                m_bGameRun = false;
            } break;


        case(SDL_KEYDOWN):
            {
                switch (Event.key.keysym.sym)
                {
                case (SDLK_ESCAPE):
                    {
                        m_bGameRun = false;
                    } break;
                }
            } break;
        }
    }
}

void CGame::SpawnCandy ()
{
    m_fCandyTimer += g_pTimer->GetElapsed ();

    if (m_fCandyTimer >= 4.0f)
    {
        CCandy Candy;

        int XPos = rand()%610;
        int YPos = rand()%448;

        Candy.Init (m_pSpriteCandy, static_cast<float>(XPos), static_cast<float>(YPos));

        m_CandyList.push_back (Candy);

        m_fCandyTimer = 0.0f;
    }
}


void CGame::CheckCollision ()
{
    list<CCandy>::iterator ItCandy = m_CandyList.begin ();

    SDL_Rect RectCandy;
    SDL_Rect RectPlayer;

    while (ItCandy != m_CandyList.end () )
    {
        RectCandy = ItCandy->GetRect ();

        RectPlayer = m_pPlayer->GetRect ();

        if (RectPlayer.y < RectCandy.y + RectCandy.h &&
            RectPlayer.y + RectPlayer.h > RectCandy.y &&
            RectPlayer.x < RectCandy.x + RectCandy.w &&
            RectPlayer.x + RectPlayer.w > RectCandy.x)
        {
            ItCandy->SetAlive (false);
        }
    }
    if (ItCandy->IsAlive () )
        ItCandy++;
    else
        ItCandy = m_CandyList.erase (ItCandy);

}


void CGame::RenderCandy ()
{
    list<CCandy>::iterator It;

    for (It = m_CandyList.begin (); It != m_CandyList.end (); It++)
    {
        It->Render ();
    }
}


Und Eventuell noch die GetRect funktion von der Spieler Klasse:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
SDL_Rect CPlayer::GetRect ()
{
    SDL_Rect temprect;

    temprect.x = m_fXPos;
    temprect.y = m_fYPos;
    temprect.w = 50;
    temprect.h = 60;
    
    return temprect;
}



Wie gesagt. Das Problem liegt bei CheckCollision. Ohne Läuft alles Prima.

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

2

18.08.2013, 18:07

Falsche gesetzte geschweifte Klammer. Deine while Schleife läuft endlos und irgendwann schmiert alles ab. ;)

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 CGame::CheckCollision ()
{
    list<CCandy>::iterator ItCandy = m_CandyList.begin ();

    SDL_Rect RectCandy;
    SDL_Rect RectPlayer;

    while (ItCandy != m_CandyList.end () )
    {
        RectCandy = ItCandy->GetRect ();

        RectPlayer = m_pPlayer->GetRect ();

        if (RectPlayer.y < RectCandy.y + RectCandy.h &&
            RectPlayer.y + RectPlayer.h > RectCandy.y &&
            RectPlayer.x < RectCandy.x + RectCandy.w &&
            RectPlayer.x + RectPlayer.w > RectCandy.x)
        {
            ItCandy->SetAlive (false);
        }
    } /// <- Hier endet die while Schleife
    if (ItCandy->IsAlive () )
        ItCandy++;
    else
        ItCandy = m_CandyList.erase (ItCandy);
     /// Hier sollte die while Schleife wohl enden ;)
}
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

3

18.08.2013, 18:20

ARG!!! xDDD Ich könnte meinen Laptop gegen die Wand schmeißen! :'D Heute morgen hatte ich einen ähnlichen Fehler mit einem Semikolon... Ugh...
Aber andere können die eigenen Fehler meißt bessere erkennen als man selbst :D
Danke für die schnelle Antwort! :)

Sp3iky

Treue Seele

Beiträge: 232

Beruf: Entwicklungsingenieur

  • Private Nachricht senden

4

18.08.2013, 19:38

Oder aber man benutzt den Debugger und merkt es spätestens nach dem 2. Schleifendurchlauf ;) Das Ding ist wirklich nützlich und wird viel zu selten benutzt.

Werbeanzeige