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

41

05.09.2010, 13:58

[offtopic]Hm es ist nur die Frage ob einem hier die ganzen OOP vergötterer auch erklären können was nun wirklich er Vorteil von Singleton zu globalen Variablen ist. Und warum sie init und exit-Funktionen nutzen, wo es doch c-tor und d-tor gibt. const-correctness komplett sinnfrei finden und funktionen werte zurückgeben lassen die gar keine Fehler zurückgeben.[/offtopic]
War das Hauptproblem des Threads nicht schon behoben, als jemand erwähnte das er da Fenster-Kopien übergibt?
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

42

05.09.2010, 19:33

danke SaRu, funktioniert super !
ich verstehe allerdings nciht so recht, warum eine sf::Clock in allen funktionen bekannt ist, aber ein sf::RenderWindow nicht?! ?(

BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

43

05.09.2010, 19:38

Weil sf::Clock (das vermute ich mal) Singleton (oder zumindest statisch) ist, es würde ja auch keinen Sinn machen 5 Uhren in einem Thread zu verwenden.

44

05.09.2010, 20:02

aber wenn man doch für 2 verschiedene aktionen im spiel eine uhr bräuchte?
zb alle 5 sekunden einen neuen ball, alle 3 sekunden ein neues.. kp dreieck.. :D ?

BurningWave

Alter Hase

Beiträge: 1 106

Wohnort: Filderstadt/Konstanz

Beruf: Student

  • Private Nachricht senden

45

05.09.2010, 20:07

Es gibt auch noch Windows-Timer, aber das sinnvollste wäre, jede Sekunde eine Variable hochzuzählen und nach 3, bzw. 5 Sekunden die passende Aktion auszuführen.

46

05.09.2010, 20:31

Die Klasse sf::Clock ist kein Singleton. Du kannst beliebig viele Instanzen dieser Klasse anlegen um verschiedene Zeiten zu messen.

Wenn es dir nur um die FrameTime (Zeit für einen kompletten Durchgang der Programmschleife) geht - denn die brauchst du zumeist am ehesten - dann bietet dein sf::RenderWindow schon die Funktion GetFrameTime(), die genau diese Zeit liefert. Dafür brauchst du also nicht umbedingt ein sf::Clock Objekt.

Hier gehts im übrigen zu einem kleinen, offiziellen SFML Tutorial zur Zeitmessung.


Ach ja... noch zu deinem Beispiel bewa: Für "alle 5 Sekunden ein neuer Ball" usw. brauchst du nicht umbedingt mehrere Timer. Du kannst ja einfach eine Variable anlegen und diese bei jedem Schleifendurchgang hoch- bzw. runterzählen und so nach 5 Sekunden ein Event auslösen. ;)

Gruß
SaRu_

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

47

05.09.2010, 20:48

Es gibt auch noch Windows-Timer, aber das sinnvollste wäre, jede Sekunde eine Variable hochzuzählen und nach 3, bzw. 5 Sekunden die passende Aktion auszuführen.

Um das mal etwas Anfänger freundlicher darzustellen:
Du setzt eine Variable auf die derzeitige Zeit und schaust in jedem Durchlauf, ob deine Zeit (also 3 oder 5 Sekunden) vergangen sind. Dabei ist wichtig zu beachten, dass die Zeit in Millisekunden berechnet wird (1 sec = 1000 ms).
Ein Beispiel mit 5 Sekunden Pause (deswegen das " + 5000"):

C-/C++-Quelltext

1
2
3
4
5
6
7
8
sf::Clock Clock;
unsigned int last_time;
// schleife
last_time = Clock.GetElapsedTime();
if ((last_time + 5000) <= Clock.GetElapsedTime()) {
    cout << "Zeit ist abgelaufen";
    Clock.Reset();
}


Ich nehme jedenfalls mal stark an, dass sich die SFML da wie die SDL verhält und die Ticks in Millisekunden zurück gibt, ansonsten musst du natürlich lediglich 3 bzw. 5 statt 3000 bzw. 5000 schreiben.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Architekt« (05.09.2010, 20:53)


48

05.09.2010, 22:20

Ein Blick in die SFML Dokumentation verrät: Die Funktion liefert die vergangene Zeit seit dem letzten Aufruf von Reset() bzw. dem initialisieren des Objekts in Sekunden(!), das heißt der Rückgabewert ist ein float.


Gruß
SaRu_

Architekt

Community-Fossil

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

49

05.09.2010, 22:44

Ein Blick in die SFML Dokumentation verrät: Die Funktion liefert die vergangene Zeit seit dem letzten Aufruf von Reset() bzw. dem initialisieren des Objekts in Sekunden(!), das heißt der Rückgabewert ist ein float.


Gruß
SaRu_

Brav gesucht.
Dann, wie ich schon anmerkte, statt "5000", 5 schreiben, sprich:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
sf::Clock Clock;
float last_time;
// schleife
last_time = Clock.GetElapsedTime();
if ((last_time + 5) <= Clock.GetElapsedTime()) {
    cout << "Zeit ist abgelaufen";
    Clock.Reset();
}

Wobei ich eben die von der SDL angebotenen Ticks in Millisekunden mehr schätze ;)

// edit: auch mal von unsigned int zu float gewechselt.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Architekt« (05.09.2010, 23:02)


50

05.09.2010, 23:20

ich kann noch lang nicht alles mit der SFML, aber ich bin auch nicht ganz blöd (wegen der 3 fachen erklärung) ;)

danke trotzdem :D

wie man aus dem thema schon erlesen kann, versuche ich, world hardest game nachzuschreiben.
ich hab ein array mit srites für die wände, die das level darstellen. zusätzlich habe ich ein array, dass mit gleich viele booleans gefüllt ist, und die beim laden des levels entsprechend auf true oder false gestellt werden. bei der hier schon so viel diskutierten Game::Run() -Funktion gibts booleans für die bewegung in jede richtung, die zu beginn auf true gesetzt werden. dann prüft die funktion in einer schleife, ob ein sprite des arrays aktiv ist (mitlaufendes array mit bools) und der bewegung im weg ist. wenn das für irgendein sprite der fall ist, setzt es den bool für die bewegung in diese richtung auf false. funktioniert auch alles. allerdings sind sprites, die im 2. level nicht mehr dargestellt werden, immernoch im weg, obwohl ich ihren boolean auf false gesetzt habe.
hab auch mit dem ein oder andere cout den fehler vesucht zu finden, aber i-wie kam ich ihm nicht auf die schliche:

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
void CGame::LoadLevel(int level)
{
    switch (level)
    {
    case(1):
        {
            levelsprite[0].SetColor(sf::Color(0,255,255));
            levelsprite[0].SetScale(100.f, 10.f);
            levelsprite[0].SetPosition(200.f, 200.f);

            showlevel[0] = true;

            levelsprite[1].SetColor(sf::Color(0, 255, 255));
            levelsprite[1].SetScale(10.f, 200.f);
            levelsprite[1].SetPosition(200.f, 210.f);

            showlevel[1] = true;

        }
        break;
            case(2):
        {
            levelsprite[0].SetColor(sf::Color(0,255,255));
            levelsprite[0].SetScale(10.f, 100.f);
            levelsprite[0].SetPosition(300.f, 300.f);

            showlevel[1] = false; //2. bool des arrays showlevel auf false
        }
        break; 
    }
}


void CGame::Move()
{
        spielermoveup = true;
        spielermovedown = true;
        spielermoveleft = true;
        spielermoveright = true;

        for (levelspritenr = 0; levelspritenr < 8; levelspritenr  ++)
        {
            if (showlevel[levelspritenr] == true) // nur prüfen, wenn das sprite auch dargestellt wird. bei dem sprite, welches nur die position geändert hat, funktioniert es. das, das garnicht mehr da ist, ist trotzdem im weg
            {
//Collisionsabfrage des levelsprites; jeweils levelsprite[levelspritenr] als sprite; wenn Collision: spielermoveup/down/left/right = false
}
if (spielermoveup == true)
spieler.Move(...)

}

void CGame::Run()
{

    while (Fenster->IsOpened())
    {
        ChangeLevel();
        Eventabfrage();
        Move();
        Render();   
    }
}

void CGame::ChangeLevel()
{
    if(Collision (spieler, ziel))
    levelcounter1 ++;

    if (levelcounter1 > levelcounter2)
    {
        levelcounter2 = levelcounter1;
        LoadLevel(levelcounter2);
    }
}


jeweils wieder große unwichtige teile rausgenommen, weils sonst einfach viel zu viel wäre. falls ihr nicht ganz versteht, kommentier ichs morgen noch bisschen.

Werbeanzeige

Ähnliche Themen