Gedeeltelijke gamestate updates

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 01-10 16:14

Gerco

Professional Newbie

Topicstarter
Ik ben een simpel "bordspel" aan het maken waarbij de speler "machines" en "shapes" op een spelbord plaatst en dan op "play" drukt om het resultaat van de opstelling te zien. Voor een voorbeeld van wat ik bedoel: zie "The Sequence" op iOS.

Iedere game loop moeten de machines op het bord hun werk doen, dat heb ik geïmplementeerd door een simpele loop over alle "GameObjects" en het aanroepen van een update() functie:
C++:
1
2
3
for(auto& go: gameObjects) {
    go->update();
}


Nu is het probleem dat deze update() functions direct de game state muteren. De "conveyor" machine doet bijvoorbeeld het volgende:
C++:
1
2
3
4
5
6
7
8
9
void Conveyor::update() {
        switch(direction) {
            case Left:
                moveEntitiesTo((*ownerPuzzle)(ownerTile->x-1, ownerTile->y));
                break;
                
            case Right:
                moveEntitiesTo((*ownerPuzzle)(ownerTile->x+1, ownerTile->y));
                break;


Als er nu twee van deze naast elkaar staan dan verplaatsen ze alle "entities" twee vakjes in één game loop in plaats van één (de tweede update() function ziet het bord na de mutatie van de eerste function en doet direct zijn ding op de gewijzigde board state).

De vraag is nu: Hoe pak ik dit aan?
  • De hele board state kopiëren. Hierdoor krijg ik nieuwe pointers naar alle tiles en moeten alle views geupdate worden met die nieuwe pointers (er is een view object voor elke Tile). Lijkt me minder handig.
  • Two-phase update: update() functies een function laten returnen die de daadwerkelijke update doet. Nadat al die functies verzameld zijn, allemaal uitvoeren. Lastig om precies ditzelfde probleem te vermijden in de update functies.
  • In plaats van de "machines", de "entities" updaten. Daarvoor moeten entities dan naar het vakje kijken waar ze op staan en de machines op zichzelf laten opereren. Dat gaat lastig worden wanneer een machine op meerdere objecten moet werken of wanneer ik objecten wil samenvoegen of splitsen.
Nog andere opties?

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Acties:
  • 0 Henk 'm!

  • johnkeates
  • Registratie: Februari 2008
  • Laatst online: 04-07 16:30
Ik dacht dat de meeste games twee soorten updates deden, delta-achtige updates voor single moves die lossy mogen zijn en world updates voor alle game state data om dat het in de praktijk niet zo veel is in een binaire stream. Zelfs met msgpack moet het nog kunnen.

Er zijn wel andere manieren om je game state in sync te houden, maar ik zou gewoon bij de ouderwetse methode blijven. Dat heeft wat nadelen zoals jumpcuts als er lag is, maar je kan natuurlijk prima je views bevriezen zolang er een transactie bezig is.

Acties:
  • 0 Henk 'm!

  • Damic
  • Registratie: September 2003
  • Laatst online: 07:16

Damic

Tijd voor Jasmijn thee

Zoals @johnkeates al zei, implementeer 2 updates, bvb Run() en ObjUpdate(). Bij run ga je echt de objecten laten werken en bij ObjUpdate ga je alleen dat object updaten na een bewerking (verplaatsen/ groter kleiner maken/...).

Al wat ik aanraak werk niet meer zoals het hoort. Damic houd niet van zijn verjaardag


Acties:
  • 0 Henk 'm!

  • DroogKloot
  • Registratie: Februari 2001
  • Niet online

DroogKloot

depenisvanjezus

Werk met twee states, i.e. pas double buffering toe.

[ Voor 4% gewijzigd door DroogKloot op 29-06-2017 11:29 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Inderdaad, twee rondes - bij de eerste ga je bepalen wat de nieuwe state van een object zou moeten zijn, dus je hebt voor de zaken die in die fase kunnen veranderen een tweede set variabelen nodig (bijv. dstX, dstY). In die eerste ronde kun je bijvoorbeeld ook collisions detecteren, en aan de hand daarvan de state van een object dat eerder nog gewoon leek te kunnen bewegen alsnog veranderen in "BOEM".

In de tweede ronde pas je de mutaties die het gevolg zijn van de eerste daadwerkelijk toe.