Interpolare le posizioni in una partita multiplayer


14

Per risparmiare larghezza di banda nel mio gioco multiplayer , non aggiorno ogni oggetto ogni tick del server, ma ogni oggetto ha un updateRate che dice al gioco che questo oggetto dovrebbe essere aggiornato ogni tick del server X.

Quando ricevo un messaggio di aggiornamento per un oggetto, calcolo il tempo in cui mi aspetto che arrivi il prossimo aggiornamento:

origin = serverCurrentPosition
diff = serverNextPosition - origin
arriveTime = now + timeBetweenTicks * updateRate

Quando disegno l'oggetto, calcolo il tempo rimasto fino al prossimo aggiornamento e interpolo la posizione di conseguenza:

step = 100 / timeBetweenTicks * updateRate
delta = 1 - step * ((arriveTime - now) / 100)
position = origin + diff * delta

Funziona ... ma c'è ancora un po 'di jitter nel disegno, anche se nella mia teoria tutto dovrebbe funzionare bene, dal momento che il ridimensionamento dovrebbe occuparsi di certo ritardo, giusto?

Quindi la domanda qui è, è questo l'approccio migliore? Devo mettere un ritardo effettivo nel calcolo? Se è così, come lo farei? Ho fatto alcuni esperimenti, ma il jitter è peggiorato.


Ciao Ivo Penso che questo sia un buon argomento, ma non è chiaro cosa stia facendo il tuo codice - per esempio da dove viene serverCurrentPosition, serverNextPosition, timeB BetweenTicks?
CiscoIPPhone

Cioè invia i dati di aggiornamento che provengono dal server.
Ivo Wetzel,

Risposte:


11

Hai jitter, perché il ritardo cambia costantemente. Ciò significa che mentre il server invia gli aggiornamenti esattamente ogni timeBetweenTickstick, il client li riceve dopo un tempo variabile. Quella volta è probabilmente vicinatimeBetweenTicks una buona connessione, ma non esattamente uguale (E inoltre, potresti avere un ritardo del server e diverse velocità di clock su server e client).

Pertanto, quando si fa affidamento sulla ricezione dell'aggiornamento esattamente nel tempo specificato, si arriva costantemente a destinazione un po 'prima / dopo l'aggiornamento effettivo. Quindi, jitter.

Un approccio semplice per ridurre il jitter sta usando la "banda di gomma", che è ciò che Martin suggerisce in un'altra risposta. Fondamentalmente, quando ricevi l'aggiornamento, non cambi immediatamente la posizione dell'oggetto. Invece, se la posizione del client e la posizione del server differiscono solo leggermente, si inizia a interpolare la posizione del client, in modo che dopo un determinato periodo di tempo (diciamo, a metà strada al prossimo aggiornamento) convergono le posizioni client e server.

Un'altra idea per ridurre il jitter nella configurazione: poiché si trasmettono le coordinate "corrente" e "successiva", è possibile calcolare la velocità dell'oggetto. Quindi, quando l'aggiornamento è in ritardo, non si ferma l'oggetto nella sua destinazione (cioè la posizione "successiva"), ma si continua a spostarlo con la stessa velocità. Se i tuoi oggetti non cambiano bruscamente la loro velocità, questo migliorerà davvero la fluidità del movimento sul client.


È già così, che gli oggetti non si fermano, continuano ad andare avanti fino alla ricezione del prossimo aggiornamento. Inoltre, l'utilizzo dell'accelerazione hardware sulla tela HTML sembra ridurre un po 'l'effetto jitter. Forse sono impazzito dopo aver lavorato su quella cosa per così tanto tempo.
Ivo Wetzel,

È del tutto possibile. Se l'attivazione dell'accelerazione aumenta la frequenza dei fotogrammi, aumenta la probabilità di gestire le informazioni di aggiornamento nel momento esatto.
Nevermind,

9

Ho già risolto questo problema con un certo successo con un approccio che chiamo "ombre di rete". Non so se questo è qualcosa che fanno gli altri, ma ha sempre funzionato per me.

Ogni entità che viene sincronizzata attraverso la rete ha un'entità ombra invisibile della rete. Quando arriva un aggiornamento dalla rete, si teletrasporta l'ombra direttamente nella posizione in cui la rete dice che dovrebbe trovarsi, quindi si interpola lentamente l'entità visibile locale verso l'ombra nel tempo.

Ho incluso molti dettagli su questo approccio nella mia risposta precedente qui


Hm, ho fatto una cosa del genere in una versione precedente, l'imprecisione in virgola mobile a volte l'ha resa davvero brutta, ho intervalli di tempo piuttosto grandi tra gli aggiornamenti, fino a 300 ms per alcuni oggetti, ma forse ho fatto male, lo darò uno scatto quando trovo del tempo libero :)
Ivo Wetzel,

la precisione in virgola mobile non dovrebbe davvero entrare in questo! Hai letto la mia risposta collegata su StackOverflow? Copre tutti i dettagli dell'implementazione di questo tipo di cose.
Martin,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.