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

wluc-16

Treue Seele

  • »wluc-16« ist der Autor dieses Themas

Beiträge: 212

Wohnort: in der Nähe von Bielefeld :D

Beruf: Schüler

  • Private Nachricht senden

1

16.08.2013, 23:36

Problem mit zufälligem Positionieren

Hallöle :)
Ich sitze nun schon länger vor einem Problem, das mir vollkommen unlogisch vorkommt:
Bei einem einfachen Pong Spiel mit jeweils zwei Schlägern auf einer Seite und auch zwei Bällen möchte ich die Bälle beim Start zufällig positionieren, was ja ziemlich einfach zu implementieren ist.
Dies passiert einmal nach dem Start im Konstruktor von Ball und nachdem ein Punkt gefallen ist mit der Funktion Ball::reset(). Hier schonmal der Code der beiden Funktionen:

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
// Ball: Konstruktor
Ball::Ball(SDL_Surface* img, vector<Paddle>* vec, int s, Mix_Chunk* snd)
{   
    // ...
    
    reset();
    
    // ...
}

// Ball: reset
void Ball::reset()
{
    // ...
    
    const int X_MIN = 200;
    const int X_MAX = SDL_GetVideoSurface()->clip_rect.w - X_MIN - rect.w;
    const int Y_MIN = 200;
    const int Y_MAX = SDL_GetVideoSurface()->clip_rect.h - Y_MIN - rect.h;
    
    rect.x = X_MIN + rand() % (X_MAX - X_MIN + 1);
    rect.y = Y_MIN + rand() % (Y_MAX - Y_MIN + 1);
}


Jetzt das Problem:
Wenn das Spiel startet, sehe ich vorab schonmal nur einen der beiden Bälle und sobald ich die Leertaste(Taste zum starten (= die Bälle werden geupdatet)) drücke, dann ertönt der Sound, der mir sagt das ein Punkt gefallen ist und einer der beiden Spieler bekommt ihn dann gutgeschrieben :thumbdown:

btw: Ich habe die Werte auch mal in eine Datei schreiben lassen und es scheint als würde der Compiler das Ganze als einfacher rand()-Aufruf ohne jegliche Filterungen via Modulo und so weiter ausführen.

Danach läuft aber alles wie geplant ab!
Heißt: Die Bälle werden innerhalb des Bereiches aus Ball::reset() gerendert und verhalten sich wie erwartet, wenn ich die Leertaste drücke. Das gilt auch für die Eingabetaste(= Punkte und Bälle zurücksetzen).

Ich werd' noch verrückt :dash:

Wäre sehr dankbar für jede Hilfe :D

PS: Ach ja, ich initialisiere den Zufallsgenerator mit SDL_GetTicks(), bevor ich die beiden Ball-Objekte erselle, aber eigentlich ist das ja egal.

2

17.08.2013, 07:37

Edit: Vergiss was vorher hier stand habe die MAXs und MINs verwechselt.

Hast du mal debugt und geschaut wie groß die MAX's und MIN's sind?

Die Berechnung solltest dir nochmal anschauen, ich glaub die macht nicht das was du möchtest das sie macht.

Grruß Koschi
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Koschi« (17.08.2013, 08:16)


3

17.08.2013, 08:26

Wäre es möglich, dass die Bälle vor SDL initialisiert werden? In diesem Fall würde in SDL_GetVideoSurface()->clip_rect noch kein vernünftiger Wert stehen, d.h. der Ball kann praktisch überall landen.
Lieber dumm fragen, als dumm bleiben!

wluc-16

Treue Seele

  • »wluc-16« ist der Autor dieses Themas

Beiträge: 212

Wohnort: in der Nähe von Bielefeld :D

Beruf: Schüler

  • Private Nachricht senden

4

17.08.2013, 09:47

Danke schon mal für eure Hilfer
@Koschi
Hab ich und die sind vollkommen korrekt also 200-560 bzw. 200-360.
Auch der Algorithmus stimmt, denn, wie ich geschrieben habe, geht nach dem Starten alles.
Übrigens hier hab ich den her: http://forum .chip.de/c-c/zufallszahlen-intervall-617368.html
@Jonathan_Klein
Wäre schön, aber die Konstanten waren ja korrekt :D

:dash: Das Buch häl das nicht mehr lange aus :D

PS: Sorry, dass ich nicht die Link-Tags verwende. Auf Android ist das nicht ganz so einfach ;)

5

17.08.2013, 10:16

Ich hätte jetzt vermutet das die Zufallszahl zwischen dem MIN und MAX liegen soll.

C-/C++-Quelltext

1
    const int X_MAX = SDL_GetVideoSurface()->clip_rect.w - X_MIN - rect.w;

Hier wird der min Wert von Max schon abgezogen.

C-/C++-Quelltext

1
    rect.x = X_MIN + rand() % (X_MAX - X_MIN + 1);

Hier wird nochmal der min wert vom max wert abgezogen, was an dieser stelle für mich unverständlich war, deshalb meine Vermutung das die Funktion nicht 100% das macht was du gerne hättest.

Edit: Vielleicht mal noch die Update Methode zeigen.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Koschi« (17.08.2013, 10:28)


wluc-16

Treue Seele

  • »wluc-16« ist der Autor dieses Themas

Beiträge: 212

Wohnort: in der Nähe von Bielefeld :D

Beruf: Schüler

  • Private Nachricht senden

6

17.08.2013, 10:35

Ich benutze den Algorithmus schon länger und bis jetzt immer erfolgreich :-)
Daher glaube ich nicht, dass der Algorithmus falsch ist.

Die Ball::update-Funktion poste ich gleich mal.

So, hier ist sie:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void Ball::update()
{
    rect.x += xVel;
    rect.y += yVel;
    
    if(rect.x >= SDL_GetVideoSurface()->clip_rect.w - rect.w || rect.x <= 0)
        xVel = -xVel;
    
    if(rect.y >= SDL_GetVideoSurface()->clip_rect.h - rect.h || rect.y <= 0)
        yVel = -yVel;
    
    for(vector<Paddle>::iterator i = paddles->begin(); i != paddles->end(); ++i)
    {
        if(rectVsRect(rect, i->getRect()))
        {
            xVel = -xVel;
            Mix_PlayChannel(-1, sound, 0);
        }
    }
}

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »wluc-16« (17.08.2013, 10:47)


7

17.08.2013, 10:56

Ich benutze den Algorithmus schon länger und bis jetzt immer erfolgreich :-)
Daher glaube ich nicht, dass der Algorithmus falsch ist.


Ja, ich hätte es anders geschrieben darum war ich verwirrt (das Min gleich 2 mal abziehen von max).

Auf den ersten blick sehe ich da auch nichts am code, außer die Frage sind xVel und yVel initialisiert?
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

wluc-16

Treue Seele

  • »wluc-16« ist der Autor dieses Themas

Beiträge: 212

Wohnort: in der Nähe von Bielefeld :D

Beruf: Schüler

  • Private Nachricht senden

8

17.08.2013, 11:15

Ja, das habe ich aber aus dem Konstruktor rasugeschnitten, um den Post nicht zu groß zu machen. Sie werden beide mit einem Parameter des Konstruktors initialisiert und damit der Ball in zufällige Richtungen fliegt, benutze ich auch noch zwei rand()-Aufrufe.

9

17.08.2013, 11:20

In der draw-Methode vom Ball wird dann auch nix mehr drauf addiert oder ähnliches?

Sonst habe ich erst mal keine Idee mehr was da noch im argen liegen könnte.

Edit: Nen Breakpoint hast mal gesetzt in der update Methode und geschaut das auch wirklich alle werte passen?
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

wluc-16

Treue Seele

  • »wluc-16« ist der Autor dieses Themas

Beiträge: 212

Wohnort: in der Nähe von Bielefeld :D

Beruf: Schüler

  • Private Nachricht senden

10

17.08.2013, 11:31

In Ball::render() wird nur SDL_BlitSurface() aufgerufen.

Zum Breakpoint:
Nein, habe ich nicht, weil ich unter Ubuntu mit Texteditor und Konsole arbeite.
In gdb möchte ich mich nur ungern einarbeiten, weil ich morgen für zwei Wochen in den Urlaub fahre und das Spiel vorher fertig haben will :)

Edit: Ich habe aber ein paar Debug-Ausgaben in eine Datei gemacht. Die waren halt alle so weit korrekt bis zu den ersten rand()-Aufrufen.
Edit: gdb sieht doch gar nicht mal so schwer aus, guck ich mir mal an.

Bin dir sehr dankbar für dein Engagement :thumbsup:

Aber das Buch ist fast im Eimer :dash: :D

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »wluc-16« (17.08.2013, 11:43)


Werbeanzeige