2012-04-04 4 views
0

Ich arbeite gerade daran, ein einfaches Spiel zu schreiben, um zu lernen, wie man SFML in C++ benutzt. Bisher lief alles reibungslos und ich habe ein grundlegendes Verständnis für die meisten Dinge, die mit SFML zu tun haben. Das Problem, auf das ich gestoßen bin, ist einen effizienten Weg zu zeitbasierten Ereignissen zu finden.Zeitbasierte Ereignisbehandlung

Das Spiel, an dem ich arbeite, ist ein sehr einfaches Raum-Eindringling-Esque-Spiel, bei dem Wellen von Feinden zu vordefinierten Zeiten während des Levels kommen. Ab sofort habe ich eine Ereignisklasse, die hält und steuert, was mit jedem aufgerufenen Ereignis passieren soll, damit ich einfache Ereignisse mehrmals wiederverwenden kann. Ab jetzt trigger ich diese Ereignisse durch Schleifen unter Verwendung einer SFML-Hülle und mit jeder Iteration der Spielschleife, die durch einen Vektor aller Ereignisse für die aktuelle Ebene läuft und die abgelaufene Zeit auf der Uhr mit der spezifizierten Zeit für das Ereignis vergleicht heißen. Das Problem ist, dass ich bei jeder Iteration des Spielablaufs einen ganzen Vektor von Ereignissen prüfen muss. Wenn die Ereignisliste lang genug wird, mache ich mir Sorgen, dass sie sich auf die Leistung des Spiels auswirken wird.

Ich hatte eine Idee, jedem Ereignis eine einfache numerische ID für seine Position in der Zeitleiste zu geben und einfach zu speichern, welches Ereignis als nächstes ausgeführt werden soll. Ich würde nur die Zeit eines Ereignisses pro Schleifeniteration prüfen müssen Während das ziemlich gut funktioniert, denke ich, war ich neugierig, ob eine effizientere Methode, die keine Überprüfung jeder Schleifeniteration erfordert, möglich ist? Ich habe ein wenig in die ereignisgesteuerte Programmierung geschaut, konnte aber nicht viel speziell zu zeitbasierten Ereignissen finden.

Also habe ich mich gefragt, ob jemand irgendwelche Erfahrung mit Timelines oder zeitbasierte Ereignisauslösung hatte und hätte irgendwelche Tipps oder Ressourcen, die ich mir ansehen könnte, um eine effizientere Idee herauszufinden? Jede Hilfe wäre großartig, danke!

+0

Zeit, zu der ein Ereignis ausgeführt werden soll ** ist ** seine ID, es ist keine weitere Nummer erforderlich (außer Sie benötigen es für andere Zwecke). –

+0

Halten Sie die Ereignisliste nach Zeit sortiert, so dass Sie nur die ersten Einträge anzeigen müssen. –

Antwort

2

Die Methode, die Sie vorschlagen, ist nur ein Vergleich jedes Mal durch die Spielschleife. Schneller geht es nicht.

Damit mehrere Ereignisse gleichzeitig ausgelöst werden können, verwenden Sie eine multimap, wobei Schlüssel Ereigniszeiten und Werte die Ereignisse selbst sind. Die Multimap wird dann nach der Zeit sortiert.

Jedes Mal durch das Spiel Schleife, so etwas wie dieser (Pseudo-Code):

now = getCurrentTime() 
while not events.isEmpty() and events.firstElement().key() < now: 
    e = events.firstElement().value 
    e.execute() 
    events.removeFirst() 
0

Sortieren Sie Vektor basierend auf der Zeit Ereignisse und dann einfach speichern, wie Sie durch den Vektor Bis jetzt haben so weit gekommen . Mit jeder Schleife werden Sie diese Position weiterführen, bis das nächste Ereignis noch nicht eintreten sollte, und die Ereignisse, die Sie gerade durchlaufen haben, auslösen.

std::vector<Event> time_line; 
size_t time_line_position; 

void fire_new_events(Time t) { 
    size_t new_time_line_position = time_line_position; 

    while(new_time_line_position < time_line.size() 
      && time_line[new_time_line_position].time <= t) 
     ++new_time_line_position; 

    fire_events(time_line.begin() + time_line_position, 
       time_line.begin() + new_time_line_position); 

    time_line_position = new_time_line_position; 
}