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

FLO2

Treue Seele

  • »FLO2« ist der Autor dieses Themas

Beiträge: 221

Beruf: Schüler

  • Private Nachricht senden

1

16.11.2009, 18:19

Problem mit Kollision und Eingaben [SDL]

Hi,
(Hoffe das ist das richtige Forum)
Ich habe jetzt zwei Probleme, mache aber mal nur ein Thread dafür auf.
Ich bin jetzt endlich auch mal beim SDL Game angekommen.
Das hat auch bisher alles gut geklappt, bis ich ein Menü einbauen wollte.

Die main-Funktion habe ich soweit abgeändert, dass statt dem Spiel das Menue aufgerufen wird. Innerhalb der Schleife, in der ProcessEvents-Funktion (des Menüs), wird dann beim klicken auf einen Button das Spiel gestartet, das heißt eine Instanz erstellt, Init,...

Das Problem:
1. Im Menü ist es egal wohin ich klicke das Spiel startet automatisch. Das liegt sehr warscheinlich an der Kollision, habe es mir aber auch schon bildlich vorgestellt und komme nicht auf den Fehler.
Oder es liegt an der Abfrage der Maus...

2. Wenn ich zum Menü zurückkehre(Escape), und öfter Escape drücke, da er beim ersten mal nicht reagiert und wieder Spiel Starten klicke, switcht es ein paar mal zwischen Menü und Spiel hin und her. Oder das Spiel beginnt per Mausklick neu. Das sieht mir so aus als würde es die Tastatur-/Mauseingaben speichern und dann verarbeiten. Warum er allerdings es erst nich reagiert, weiß ich nicht :? .


Code:
Hier ist die Kollisions abfrage:

C-/C++-Quelltext

1
2
3
4
5
6
7
    int Button = SDL_GetMouseState (NULL, NULL);

    if (m_pMMouse->GetRect ().x < m_pMStartGame->GetRect ().x + m_pMStartGame->GetRect ().w &&
        m_pMMouse->GetRect ().x > m_pMStartGame->GetRect ().x &&
        m_pMMouse->GetRect ().y < m_pMStartGame->GetRect ().y + m_pMStartGame->GetRect ().h &&
        m_pMMouse->GetRect ().y > m_pMStartGame->GetRect ().y &&
        Button & SDL_BUTTON (SDL_BUTTON_LEFT))



Die Run-Schleife des Menüs'

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
// Run

//

// Aufgabe: Hauptschleife des Menues

//

void CMenu::Run ()
{

    // Hauptschleife des Spiels durchlaufen

    //

    while (m_bMMenuRun == true)
    {

        // Framework updaten und Buffer löschen

        g_pFramework->Update ();
        g_pFramework->Clear ();

        // Hintergrundbild rendern

        m_pSpriteMBackground->Render ();

        // Button rendern

        m_pMStartGame->Render ();

        /* Text ausgeben
        m_pText->RenderTextColored ("Punkte: ", 312, 515, 473, 0, 0);
        m_pText->RenderInteger (m_pPlayer->m_Points, 312, 515, 473, 140, 0);*/

        // Maus anzeigen

        m_pMMouse->Update ();
        m_pMMouse->Render ();

        // Was macht der Spieler

        if (ProcessEvents () == 1)
        {
            CGame Game;
            Game.Init ();
            Game.Run ();
            Game.Quit ();
        }

        // Buffer flippen

        g_pFramework->Flip ();

    }

}   // Run


Dann die Event abfrage von CGame

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
// ProcessEvents

//

// Aufgabe: Events bearbeiten

//

void CGame::ProcessEvents ()
{
    SDL_Event Event;

    // Gab es einen Event

    if (SDL_PollEvent (&Event))
    {
        // Ja, also schauen welches

        switch (Event.type)
        {
            // Beenden?

            case (SDL_QUIT):
            {
                m_bGameRun = false;

            }   break;

            // Wurde eine Taste gedrückt?

            case (SDL_KEYDOWN):
            {
                switch (Event.key.keysym.sym)
                {
                    case (SDLK_ESCAPE):
                    {
                        // Ja, also Spiel beenden

                        m_bGameRun = false;      // HIER kehrt oder sollte es zumindest zum Menü zurückkehren.


                    } break;
                }
            } break;
        }
    }

}   // ProcessEvents


Vlt. gibt es eine Funktion, welche diese Nachrichtenschleife leert.

Sollte ich das Menü vlt. anders einbauen?

Hoffe ihr könnt mir helfen!
Pi mal Daumen = 18.84955592

CBenni::O

1x Contest-Sieger

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

2

16.11.2009, 18:31

hallo!
IdR. macht man es eher mit einem enum, welches die aktuelle position im programm angibt (Intro, Menü, Spiel, Credits etc.) und arbeitet demnach...
so sollte es aber auch gehen^^ bei einem relativ kleinen projekt...
zu deinem problem... ich denke, dass iwie die rückgabe von CMenu::ProcessEvents Fehlerhaft ist... lass ihn dir irgwndwie (per logfile oder so) ausgeben...

poste mal den Code von CMenu::ProcessEvents...

zu deinem zweiten problem: SDL_PollEvent arbeitet glaub ich, immer nur einen event ab...
am besten ne while() außenrum...
also praktisch

C-/C++-Quelltext

1
2
3
4
while(SDL_PollEvent(&Event))
{
//...

}


mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

carli

unregistriert

3

16.11.2009, 18:42

C-/C++-Quelltext

1
int Button = SDL_GetMouseState (NULL, NULL);

Wo fragst du die Mausposition ab? - du lässt die Mauskoordinaten ins Leere laufen.
Ich empfehle dir eh die MouseButtonDown-Events - die geben dir gleich die Mausposition an.

CBenni::O

1x Contest-Sieger

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

4

16.11.2009, 18:46

uups... das habe ich übersehen...

die doku von der SDL is eig sehr gut...

mit ein wenig englischkenntnis kann man da alles nachlesen

du kannst einfach zwei zeiger an die funktion übergeben, dann kannst du dir den umweg über m_pMMouse sparen^^

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

FLO2

Treue Seele

  • »FLO2« ist der Autor dieses Themas

Beiträge: 221

Beruf: Schüler

  • Private Nachricht senden

5

16.11.2009, 19:02

Danke für eure Antworten!

@CBenni::O
Ne, der Rückgabewert stimmt, aber die if-Abfrage der Kollision zwischen Maus und Button ist irg. fehlerhaft.
Wegen der while-Schleife. Diese Schleife ist ja schon in CMenu::ProcessEvents. Wenn ich dort eine Schleife einbaue, würde das Programm ja solange warten bis etwas passiert.
Hoff ich habe das richtig verstanden :?

CMenu::ProcessEvents:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int CMenu::ProcessEvents ()
{

    int Happened = 0;

    int Button = SDL_GetMouseState (NULL, NULL);

    if (m_pMMouse->GetRect ().x < m_pMStartGame->GetRect ().x + m_pMStartGame->GetRect ().w &&
        m_pMMouse->GetRect ().x > m_pMStartGame->GetRect ().x &&
        m_pMMouse->GetRect ().y < m_pMStartGame->GetRect ().y + m_pMStartGame->GetRect ().h &&
        m_pMMouse->GetRect ().y > m_pMStartGame->GetRect ().y &&
        Button & SDL_BUTTON (SDL_BUTTON_LEFT))
    {
        Happened = 1;
    }

    return Happened;

}   // ProcessEvents


@carli
Ich habe gelesen, dass wenn die Position egal ist man NULL übergeben soll. Es ist ja egal, weil die Koordinaten in m_pMMouse->GetRect ().* gespeichert sind. Vlt. sollte ich sagen das der Cursor ein Sprite ist welches an den Mauskoordinaten gerendert wird.

Danke schonmal!
Pi mal Daumen = 18.84955592

carli

unregistriert

6

16.11.2009, 19:12

Ich bleib dabei:
Bau das Klicken ins MouseButtonDown-Event ein.

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

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

  • Private Nachricht senden

7

16.11.2009, 19:32

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int CMenu::ProcessEvents ()
{
int MouseX, MouseY;

    int Button = SDL_GetMouseState(&MouseX, &MouseY);

    if (Button & SDL_BUTTON (SDL_BUTTON_LEFT) && MouseX < m_pMStartGame->GetRect ().x + m_pMStartGame->GetRect ().w &&
        MouseX > m_pMStartGame->GetRect ().x &&
        MouseX < m_pMStartGame->GetRect ().y + m_pMStartGame->GetRect ().h &&
        MouseX > m_pMStartGame->GetRect ().y)
    {
        return 1;
    }

    return 0;

}   // ProcessEvents

so würd ichs machen.
das ist etwas schneller (es sei denn du hälst die maustaste fast die ganze zeit gedrückt^^)

nur bei einer sache bin ich mir nicht sicher.
das "binäre und" ist da richtig?

Quellcode

1
Button & SDL_BUTTON (SDL_BUTTON_LEFT)
"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?

FLO2

Treue Seele

  • »FLO2« ist der Autor dieses Themas

Beiträge: 221

Beruf: Schüler

  • Private Nachricht senden

8

16.11.2009, 19:49

Hi!
Danke erstmal wieder!

Hmm, die Lösung is auf jeden Fall mal besser, aber es is immer noch egal wohin ich auch klick, das Spiel startet.

Zitat von »"NachoMan"«

nur bei einer sache bin ich mir nicht sicher.
das "binäre und" ist da richtig?

Code:
Button & SDL_BUTTON (SDL_BUTTON_LEFT)

Ich geh mal davon aus so stehts in Wikibooks!

Zitat

knoepfe = SDL_GetMouseState (NULL, NULL);
if (knoepfe & SDL_BUTTON (SDL_BUTTON_LEFT))
/* Linker Mausknopf wurde betätgt */


@carli
Habs mal versucht und habe ne doofe Frage:
Wie fülle ich die Struktur :?
Pi mal Daumen = 18.84955592

carli

unregistriert

9

16.11.2009, 20:16

SDL_PollEvent füllt die Struktur doch schon - du musst sie auslesen!

FLO2

Treue Seele

  • »FLO2« ist der Autor dieses Themas

Beiträge: 221

Beruf: Schüler

  • Private Nachricht senden

10

16.11.2009, 20:41

Danke hat jetzt auch mit SDL_BUTTONDOWN ~funktioniert!
D. h. das Problem besteht immer noch. :?
Hoffe ihr könnt mir weiterhin helfen.
Pi mal Daumen = 18.84955592

Werbeanzeige