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

Raidenkk

Treue Seele

  • »Raidenkk« ist der Autor dieses Themas

Beiträge: 151

Wohnort: Bergkamen/Oberaden

Beruf: Multimedia Informatik

  • Private Nachricht senden

1

22.05.2011, 07:37

Verschiedene Geschwindigkeiten?

Hey,
ich bin ziemlich neu mit SFML zugange und habe ein kleines Test Spiel Programmiert.
Als ich es bei mir getestet habe war alles OK, dann aber habe ich eine Böse überraschung gehabt.
Ich habe das Spiel auf meinen Dads Rechner getestet und musste leider festellen das das Spiel total langsam abläuft ich denke mal weil er ein langsameren Prozessor als ich hat. Wie löse ich das Problem?

Quellcode

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
// ###########################################
// Name: TakeIt
// Spieler: 1-2 Spieler
// Info: Fange den Ball um Punkte zu bekommen.
// ###########################################

#include <SFML\Graphics.hpp>
#include <iostream>

int main ()
{
    sf::RenderWindow App(sf::VideoMode (800, 600, 32), "Takeit V1");

    // Strukturen
    struct S_Spieler
    {
        float X;
        float Y;
        int Sitz;
        int Punkte;
        int Leben;
    };

    struct S_Ball
    {
        float X;
        float Y;
        bool life;
    };

    // Variablen
    int Spieler_Anzahl = 1;
    S_Spieler Spieler1;
    S_Spieler Spieler2;
    S_Ball Ball1;
    const float Speed = 0.3f;
    bool Spawn = true;

    // Random Seed initialisieren
    srand (time (NULL));

    // Spieler1 initialisieren
    Spieler1.Leben = 3;
    Spieler1.Punkte = 0;
    Spieler1.Sitz = 1;          // 1.Sitz oben - 2.Sitz unten
    Spieler1.X = 350.f;
    Spieler1.Y = 500.f;

    // Spieler2 initialisieren
    Spieler2.Leben = 3;
    Spieler2.Punkte = 0;
    Spieler2.Sitz = 2;          // 1.Sitz oben - 2.Sitz unten
    Spieler2.X = 350.f;
    Spieler2.Y = 550.f;

    // Game Loop
    while (App.IsOpened ())
    {
        // Event
        sf::Event Event;
        while (App.GetEvent (Event))
        {
            // Schließen Button
            if (Event.Type == sf::Event::Closed)
            {
                App.Close ();
                return EXIT_SUCCESS;
            }
        }

        // Ball1 initialisieren
        if (Spawn == true)
        {
            Ball1.X = ((rand()+10)%750);
            Ball1.Y = ((rand()-50)%10);
            Ball1.life = true;
            Spawn = false;
        }

        // Steuerung Spieler1
        if (Spieler1.X >= 5)
        {
            if (App.GetInput().IsKeyDown(sf::Key::Left))  Spieler1.X -= Speed;
        }
        if (Spieler1.X <= 745)
        {
            if (App.GetInput().IsKeyDown(sf::Key::Right)) Spieler1.X += Speed;
        }

        // Spieler1 Zeichnen
        if (Spieler1.Sitz == 1)
        {
            Spieler1.Y = 500;
            App.Draw(sf::Shape::Line (Spieler1.X, Spieler1.Y, Spieler1.X+50, Spieler1.Y, 5, sf::Color::Red));
        }
        else
        {
            Spieler1.Y = 550;
            App.Draw(sf::Shape::Line (Spieler1.X, Spieler1.Y, Spieler1.X+50, Spieler1.Y, 5, sf::Color::Red));
        }

        // Spieler2 Zeichnen
        if (Spieler_Anzahl == 2)
        {
            if (Spieler2.Sitz == 1)
            {
                Spieler2.Y = 500;
                App.Draw(sf::Shape::Line (Spieler2.X, Spieler2.Y, Spieler2.X+50, Spieler2.Y, 5, sf::Color::Blue));
            }
            else
            {
                Spieler2.Y = 550;
                App.Draw(sf::Shape::Line (Spieler2.X, Spieler2.Y, Spieler2.X+50, Spieler2.Y, 5, sf::Color::Blue));
            }
        }

        // Ball Zeichnen
        if (Ball1.life == true)
        {
            App.Draw(sf::Shape::Circle (Ball1.X, Ball1.Y, 5, sf::Color::Green));
        }

        // Ball Gravitation
        Ball1.Y += 0.05f;

        // Ball Kollision mit Spieler1
        if (Ball1.X >= Spieler1.X && Ball1.X <= Spieler1.X+50)
        {
            if (Ball1.Y >= Spieler1.Y-5)
            {
                Ball1.life = false;
                Spawn = true;
            }
        }

        App.Display ();
        App.Clear ();
    }

    return EXIT_SUCCESS;
}

2

22.05.2011, 08:14

Moin,

in deinem Code fehlt etwas entscheidendes, undzwar GetFrameTime().

Das fehlt z.B hier:

C-/C++-Quelltext

1
if (App.GetInput().IsKeyDown(sf::Key::Left))  Spieler1.X -= Speed;


so müsste es aussehen:

C-/C++-Quelltext

1
if (App.GetInput().IsKeyDown(sf::Key::Left))  Spieler1.X -= Speed * App.GetFrameTime();


Auch bei der Ball Gravitation etc.

Danach müsstest du aber die Geschwindigkeiten höher setzen, also

C-/C++-Quelltext

1
2
const float Speed = 200.f;
Ball1.Y += 150.f;

sonst ist es zu langsam.

Raidenkk

Treue Seele

  • »Raidenkk« ist der Autor dieses Themas

Beiträge: 151

Wohnort: Bergkamen/Oberaden

Beruf: Multimedia Informatik

  • Private Nachricht senden

3

22.05.2011, 08:19

Ok Funktioniert ich danke dir :)

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

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

  • Private Nachricht senden

4

22.05.2011, 10:22

Hierbei sollte man erwähnen, dass die Frametime in Sekunden zurückgegeben wird und die Geschwindigkeit deshalb auch in Pixel pro Sekunde angegeben werden muss.
Ausserdem empfiehlt sich VSync anzuschalten oder die Framerate zu begrenzen, damit die Frametimes nicht zu kurz werden.
"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?

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »NachoMan« (22.05.2011, 15:59)


Raidenkk

Treue Seele

  • »Raidenkk« ist der Autor dieses Themas

Beiträge: 151

Wohnort: Bergkamen/Oberaden

Beruf: Multimedia Informatik

  • Private Nachricht senden

5

23.05.2011, 08:12

Danke Natcho für den Tipp mit dem VSync es kommt mir so vor als würde das Programm auch mehr FPS haben auserdem ist nun das Programm auf jedem Rechner gleich schnell ;)

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

6

23.05.2011, 09:37

Nein du bekommst jetzt weniger FPS, dafür aber diese aber konstant (was viel wichtiger ist). VSync sorgt dafür, dass die Grafikkarte auf den Monitor wartet. Die meisten monitor können nur 60 oder 70 Bilder pro Sekunde anzeigen. Ohne VSync feuert die Grafikkarte einfach bilder raus und der Monitor nimmt sich dann die passenden. Mit VSync schickt die Grafikkarte erst dann ein Bild raus, wenn dieses auch vom Monitor angezeigt werden kann.

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

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

  • Private Nachricht senden

7

23.05.2011, 11:12

Ohne VSync feuert die Grafikkarte einfach bilder raus und der Monitor nimmt sich dann die passenden.

Der Monitor Zeichnet, soweit ich das mit bekommen habe, immer das aktuellste Bild, kann aber mitten im bild damit anfangen. Das kann bei schnelleren Bewegungen hässliche Streifen verursachen.

Auf der Wikipediaseite steht auch zum Thema LCD Monitore:

Zitat

Das verhindert, dass die Signale zu schnell an den Monitor gesendet werden, was zu Schwarzem Schirm (Totalversagen der Grafikengine) oder Programm- und Systemabstürzen durch Bufferüberläufe führen kann
wovon aber der Nachweis fehlt und ich noch nie woanders von was gehört habe :/ Vielleicht weiß ja jemand aus dem Forum, was es damit auf sich hat?
"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?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

23.05.2011, 18:17

Das mit dem VSynch ist ganz einfach. Ein Monitor baut ein Bild immer von oben nach unten auf und verwendet zum Bildaufbau die aktuellen Daten der Grafikkarte. Sollte er erst halb fertig sein und danach der nächste Frame (oder ein zusätzliches Polygon oder eine Primitive) in den Buffer geschrieben werden, dann ist die zweite Hälfte des Bilds auf dem Schirm schon das neue Bild, die erste Hälfte (da ja schon dargestellt) noch das alte. Das führt wie NachoMan korrekt sagte zu hässlichen Streifen oder merkwürdigem Flackern (speziell z.B. wenn man in einem Shooter die Kamera schnell rotiert, dann ist oben und unten die Welt gegeneinander verschoben).
Wie Sylence richtig sagte, kann man auf diesen "Vertical Retrace" (im Fall eines Röhrenmonitors der Moment in welchem der Trace, also der Kathodenstrahl, von unten nach oben gejagt wird ohne was zu zeichnen - TFTs haben sowas ähnliches, allerdings ist das mehr virtuell) warten und genau in diesem Moment, in welchem das aktuelle Bild nicht verändert und nicht gelesen wird, dazu nutzen, den Backbuffer und den aktuellen Bildschirmspeicher zu flippen, also den Backbuffer als Bildschirmspeicher aktiv zu schalten, damit der nächste Bildaufbau seine Daten aus diesem bezieht.
Üblicher Weise wird in Spielen auf den Vertical Retrace gewartet, also eine Synchronisation zwischen Grafikkarte und Bildschirm gemacht. Das nennt sich dann VSynch=Vertical Retrace Synchronisation.
Allerdings wird dieses Feature nur zu gern von Gamern abgeschaltet, damit sie mehr als 60 FPS (die übliche Bildschirmfrequenz) haben - warum auch immer, der Grund erschließt sich mir nicht. Mehr FPS sind weder irgendwie notwendig, noch ist der höhere Stromverbrauch und die heißere GPU sonderlich sinnvoll.
Sinnvoll ist es aber eventuell dann, wenn man eine "blöde" Frametime hat. Sprich eine, mit der man nur mit ~55 FPS rendern kann. Dann ist die Zeit zwischen einem VRetrace und dem nächsten zu kurz um einen einzelnen Frame zu berechnen und man wartet nahezu einen kompletten Zyklus lang nur sinnlos rum. Heißt effektiv dann 30 FPS (nur jeder zweite VRetrace wird erwischt).

Edit:
Also sowas wie von Wikipedia hab ich echt noch nicht gehört und halte es für Blödsinn von jemandem ohne Ahnung. Die Hersteller würden ihr Gerät schon gegen sowas absichern. Außerdem werden die Daten doch auch gar nicht aktiv an den Monitor gesendet. Wäre ja auch Quatsch bei z.B. einer Fenster-Anwendung, die nur die Hälfte des Screens einnimmt und mit 700 FPS rendert (hallo Gears). Da müsste ja die zweite Hälfte auch gesendet werden. Also Bullshit. Der Monitor liest die Daten aus der Grafikkarte und dabei jedes Pixel nur genau einmal pro Bildaufbau.
Auch Bufferüberläufe oder Systemabstürze haben wohl eher nichts damit zu tun, dass jemand mit 700 FPS rendert, sondern wohl eher damit, dass da jemand Bullshit programmiert hat. Sorry, aber der Beitrag gehört mMn in die Unzyklopedia.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von »BlueCobold« (23.05.2011, 18:34)


NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

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

  • Private Nachricht senden

9

23.05.2011, 18:30

Das Ausschalten von VSync hat bei Counterstrike Sinn gemacht, weil der Rückstoß pro Frame um einen bestimmten Wert zurückgegangen ist. Man hat bei 60fps also viel schlechter getroffen als bei 100fps. Ist aber auch das einzige Spiel das ich kenne bei dem das Sinn macht.
"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?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

10

23.05.2011, 18:33

OK, das ist dann ein spieltechnischer Grund durch schlampige Programmierung. Aber mehr auch nicht ;)
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige