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

Rion

Frischling

  • »Rion« ist der Autor dieses Themas

Beiträge: 23

Wohnort: Trier

Beruf: Komponist, Medienassistent

  • Private Nachricht senden

1

04.07.2010, 16:38

Sprite-Bewegung vor Hintergrund

Hi,

bin noch relativ neu in SDL und habe mal wieder ein kleines Problem. Ich möchte gerne ein Sprite über einen vorher geladenen Hintergrund bewegen (Levelboden). Nur habe ich jetzt ein Problem mit dem Aktualisieren und Flippen der Buffer, sodass das Sprite immer eine Spur hinter sich zieht, wenn man es bewegt. Es wird also nicht aktualisiert.

Es funktioniert, wenn ich vorher den Screen schwarz fülle und dann das neue Sprite zeichne, aber dann ist mein Hintergrund ja weg und ich möchte aus Performancegründen nicht bei jeder Bewegung den Hintergrund (Level) neu zeichnen müssen, was mit for-Schleifen realisiert ist. Dann gehts wirklich sehr langsam.

Ich hoffe, ihr könnt mir dabei helfen. Hier mal ein paar Code-Ausschnitte:

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
...
//Header-Dateien
...

//Videodaten definieren
const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 768;
const int SCREEN_DEPTH = 16;

//Hauptprogramm
int main (int argv, char *argc[])
{
    //SDL initialisieren
    SDL_Init (SDL_INIT_EVERYTHING);
    
    //Spielschleife
    bool Schleife = true;
    
    //Instanzen für Objekte erstellen
    SDL_Surface *screen, *Spieler, *Boden;
    
    //Event-Handler
    SDL_Event event;
    
    //Videomodus setzen
    screen = SDL_SetVideoMode (SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_DEPTH,
                            SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN);
                            
    //Grafiken laden (mit SDL_image.h)
    Spieler = IMG_Load ("player.bmp");
    Boden = IMG_Load ("ground.bmp");
    
    //Transparenz für Spieler-Sprite
    SDL_SetColorKey (Spieler, SDL_SRCCOLORKEY, SDL_MapRGB(Spieler->format, 255, 0, 255));
    
    //Rechtecke für Spieler und Boden deklarieren
    SDL_Rect s_dest, rcBoden;
    
    //Startkoordinaten für Bodentextur
    rcBoden.x = 0;
    rcBoden.y = 0;
    
    //Startkoordinaten für Spieler
    s_dest.x = 100;
    s_dest.y = 100;
    s_dest.w = Spieler->w;
    s_dest.h = Spieler->h;
    
    //2D-Boden zeichnen
    for (int x = 0; x < SCREEN_WIDTH; x++) {
        for (int y = 0; y < SCREEN_HEIGHT; y++) {
            rcBoden.x = x * 100;
            rcBoden.y = y * 100;
            
            //Boden zeichnen
            SDL_BlitSurface (Boden, NULL, screen, &rcBoden);
        }
    }
    
    //Hauptschleife
    ...
    //Event-Abfrage
    ...
    //Wenn LINKS gedrückt wurde...
    if (event.key.keysym.sym == SDLK_LEFT)
    {
        //...dann bewege Spieler 10 Pixel nach links
        s_dest.x -= 10;
    }
    
    //Spieler-Bild anzeigen
    SDL_BlitSurface (Spieler, NULL, screen, &s_dest);
    
    //Screen aktualisieren
    SDL_UpdateRect (screen, 0, 0, 0, 0);
    
    SDL_Flip (screen);
    SDL_Delay (40);
    }
    //ENDE Hauptschleife
    ...
}


Was mache ich falsch? Wäre dankbar für Hilfe!

2

04.07.2010, 16:48

Du wirst wohl den Hintergrund in jedem Frame zeichnen MÜSSEN ! Wenn der Hintergrund die Bildschirmgröße hat, kannste dir das mit dem Schwarz davor Sparen :)
Das geht nicht anders, sonst gibt es eben diese Spuren, da nur ein kleiner Fleck über das alte Bild gezeichnet wird.

Wenns dir um die Performance geht, nimm gleich SFML.

3

04.07.2010, 17:14

Da hat E122 recht, du kommst nicht drum herum den gesamten Bildschirm immer wieder neu zu zeichnen.

Hab leider gerade keine Zeit mir dein Quellcode genauer anzuschauen, aber solltest du den Hintergrund irgendwie aus Stücken zusammensetzen, dann kannst du den ja auf eine eigene Surface zeichnen und nur die bei jedem Frame auf den Bildschirm zeichen, das geht dann schneller, dabei wir der Hintergrund nicht aktualisiert sondern nur neu gerendert.

Gruß
SaRu_

CrazyPlayer

Treue Seele

Beiträge: 109

Wohnort: Mittenwald [Garmischpartenkirchen]

Beruf: Schüler

  • Private Nachricht senden

4

04.07.2010, 18:08

Du lässt es ja nur beim ersten Frame zeichnen. Du musst es in der Hauptschleife vor dem Zeichnen des Spielers stellen. Weil dann wird es bei jedem Frame gezeichnet ;)
Every day is a programming day ;)

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

5

04.07.2010, 18:51

Wenns wirklich zu langsam ist den kompletten Hintergrund zu zeichnen, dann verwirf das was nicht gezeichnet werden soll. Zum Beispiel alles was nicht im Sichtbereich liegt. Oder alles was vor der Spielerbewegung nicht vom Spieler überdeckt war usw...
@D13_Dreinig

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

6

05.07.2010, 08:31

So'n Quatsch. Es reicht voellig den Hintergrund dort zu zeichnen, wo das Sprite in dem Bild davor war. f'`8k


Gruß, TGGC (der kostenlose DMC Download)

7

05.07.2010, 10:36

Es reicht voellig den Hintergrund dort zu zeichnen, wo das Sprite in dem Bild davor war.
Ich frage mich gerade, ob das wirklich (merklich) schneller und vor allem ohne überflüssigen Mehraufwand funktioniert?!

Ich schlepp' doch nicht die ganzen Koordinaten der Sprites (wenn man von mehreren ausgeht, die sich bewegen) mit, von einem zum nächsten Frame, nur um dann die von dir angesprochenen Bereiche zu berechnen und diese alle nach und nach neu zu rendern.

Kommt mir jetzt irgendwie zu aufwendig vor, naja vielleicht irre ich mich... :huh:

Gruß
SaRu_

Tobiking

1x Rätselkönig

  • Private Nachricht senden

8

05.07.2010, 11:18

Bei steigender Sprite Zahl steigt natürlich der Aufwand, während der Gewinn gleichzeitig sinkt. Aber wenn es zu aufwendig ist den Hintergrund immer komplett neu zu zeichnen, dann wird man auch nicht mit vielen Sprites arbeiten können. Ich könnte mir vorstellen das der Mehraufwand für 20-30 Spirtes deutlich kleiner ist als das Zeichnen von mehreren (zehn)tausend Pixeln. Wenn man viele Sprites nutzten will, wird man heutzutage eh auf Hardwarebeschleunigung der Grafikkarte zurückgreifen (siehe Vorschlag SFML).

Rion

Frischling

  • »Rion« ist der Autor dieses Themas

Beiträge: 23

Wohnort: Trier

Beruf: Komponist, Medienassistent

  • Private Nachricht senden

9

05.07.2010, 11:25

Vielen Dank für eure Antworten.

Ich habe es jetzt so gemacht, dass ich den Hintergrund vor der Game-Schleife einmal komplett zeichne und dann bei jedem Frame nur an der Spielerposition.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
//2D-Boden an Spieler-Position zeichnen
for (int x = 0; x < s_dest.w; x++) {
    for (int y = 0; y < s_dest.h; y++) {
        rcBoden.x = x * 100;
        rcBoden.y = y * 90;

        //Bodenmuster an Spieler-Position zeichnen
        SDL_BlitSurface (Boden, NULL, screen, &rcBoden);
    }
}

Die for-Schleife zeichnet also das Bodenmuster nur da, wo der Spieler sich befindet. Das klappt super, ohne den Zeitlupenmodus zu bekommen :)
Danke an david_pb und TGGC für den Tipp!

Wenn es dann mehrere Sprites zu bewegen gibt (z.B. Gegner oder einfach umherlaufende Passanten), wäre es dann besser mit SFML zu arbeiten oder kann ich dieses Prinzip mit der Spieler-Position in SDL beibehalten? Bei 15 Sprites kann das allerdings auch zu Performancebremsen führen...

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

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

  • Private Nachricht senden

10

05.07.2010, 11:28

die kleinste gängigste auflösung ist heute die netbookauflösung von 1024x600 das sind schon 614400pixel^^ also da reichen ein paar "(zehn)tausend pixel" nicht.
ich glaub trotzdem du machst dir da zu viele gedanken. das geht schneller als du denkst. programmier erstmal ein kleines spiel oder wechsel gleich zur sfml.(was wesentlich einfacher und schneller ist)

edit: ahh okay bei tiles macht das natürlich sinn xD
für nen anfänger und die meisten fortgeschrittenen ists immer besser mit der sfml zu arbeiten.
"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?

Werbeanzeige