2009-06-30 17 views
8

Ho scritto un gioco multiplayer 2D flash e un server socket. Il mio piano originale per l'algoritmo di movimento tra il client e il server è stato il seguente:"algoritmo" di movimento nei giochi Multiplayer (MMO) client-server?

  • Il client comunica al server sulla modalità di movimento del giocatore (andare avanti o non si muove) e la modalità di rotazione del giocatore (non girando, girando a sinistra o girando a destra) ogni volta che cambiano.
    • Il server esegue il ciclo di tutti i lettori ogni pochi millisecondi e calcola l'angolo ruotato e la distanza spostata, in base alla differenza di tempo. Lo stesso calcolo viene eseguito dal cliente.

Il mio attuale di calcolo per il cliente (stessa matematica è usata in server) ==>

Passando

var newTimeStamp:uint = UtilLib.getTimeStamp(); //set current timeStamp 
       var rot:uint = Math.round((newTimeStamp - turningTimeStamp)/1000 * 90); //speed = x degrees turning every 1 second 
       turningTimeStamp = newTimeStamp; //update timeStamp 
       if (turningMode == 1) //left 
       { 
        movementAngle = fixAngle(movementAngle - rot); 
       } 
       else if (turningMode == 2) //right 
       { 
        movementAngle = fixAngle(movementAngle + rot); 
       } 

private function fixAngle(angle:int):uint //fixes an angle in degrees (365 -> 5, -5 -> 355, etc.) 
     { 
      if (angle > 360) 
      { 
       angle -= (Math.round(angle/360) * 360); 
      } 
      else if (angle < 0) 
      { 
       angle += (Math.round(Math.abs(angle)/360) + 1) * 360; 
      } 
      return angle; 
     } 

Movimento

var newTimeStamp:uint = UtilLib.getTimeStamp(); //set current timeStamp 
       var distance:uint = Math.round((newTimeStamp - movementTimeStamp)/1000 * 300); //speed = x pixels forward every 1 second 
       movementTimeStamp = newTimeStamp; //update old timeStamp 
       var diagonalChange:Array = getDiagonalChange(movementAngle, distance); //with the current angle, howmuch is dX and dY? 
       x += diagonalChange[0]; 
       y += diagonalChange[1]; 

private function getDiagonalChange(angle:uint, distance:uint):Array 
     { 
      var rAngle:Number = angle * Math.PI/180; 
      return [Math.round(Math.sin(rAngle) * distance), Math.round((Math.cos(rAngle) * distance) * -1)]; 
     } 

Questo sembra funzionare alla grande. Per tenere conto del ritardo, il server corregge le informazioni del cliente ogni tanto inviando questi dati.

Con questo sistema viene utilizzata una larghezza di banda molto ridotta per gestire il movimento. Tuttavia, le differenze tra il mio server e le coordinate e gli angoli del client sono troppo grandi. Dovrei forse estendere il mio "algoritmo", anche per tenere conto della latenza di un utente? O ci sono modi migliori per gestire i movimenti nel client con giochi multiplayer per server <> con grandi prestazioni?

risposta

6

Il mio progetto iniziale sarebbe simile al tuo, ma se questo è non funziona, forse si potrebbe consentire al cliente di fare tutto il movimento e solo il server fare qualche controllo gamma.

Quindi, se l'ultima posizione riportata era X, la successiva deve trovarsi entro un raggio da X, dove il raggio è basato sulla differenza di data/ora inviata dal client con i dati x, y.

Principalmente questo è solo necessario per rilevare barare.

Arrestare, combattere, ecc richiede che venga inviata una posizione insieme all'attacco e le azioni attivate dalle posizioni verranno attivate solo dopo che il client ha inviato l'aggiornamento per quella posizione, ma sarebbe basato sul server.

Non è sicuro che ciò sarebbe di grande aiuto, ma potrebbe interrompere le risincronizzazioni che si sarebbero verificate dall'algoritmo iniziale.

Commento risposta:

No, i clienti sarebbe ancora informare il server della loro posizione, ma il server non avrebbe cercato di calcolare la posizione successiva. Ciò significherebbe che il server (e tutti gli altri client) avrebbe almeno un ciclo di invio/ricezione in posizione.

Immagino che sto dicendo di lasciare che il client faccia tutto il lavoro, capire dove si trova il personaggio e dirlo al server, ma includere abbastanza informazioni che il server può opzionalmente controllare la validità per garantire che nessuno imbrogli.

Il rilevamento dei cheat potrebbe anche essere disattivato per le prestazioni o impostato su un controllo casuale.

Nota: tutte le informazioni su collisione/posizione su oggetti all'interno del raggio di movimento devono essere inviate al client affinché funzioni.

+0

Il server non avrebbe dovuto continuare a ricevere e inviare nuovamente tonnellate di messaggi se tutti i client dovevano informare tutti gli altri client della loro posizione corrente? – Tom

+0

+1 Stavo per suggerire la stessa cosa. Questo è ciò che fanno molti videogiochi multiplayer popolari. Il server si assicura solo che tutti siano sincronizzati periodicamente. (Credo che i giochi di Quake lo facciano.) –

+0

Bene, la mia prima domanda si applica ancora. I client non dovrebbero inviare migliaia di messaggi tutto il tempo per mantenere aggiornato il server ad ogni passo? Seguito dal server che invia questi dati uno di nuovo a tutti i giocatori vicini. – Tom

0

Il server è così lento da non poter gestire tutto il movimento? Soprattutto in un gioco 2-d? Tipicamente, quando eseguo piccoli giochi 2D, il server mi restituisce tutti i miei movimenti, quindi non è richiesto alcun calcolo sul client. Se il server inizia a rallentare, semplicemente mi blocco un po ', che è quello che normalmente ci si aspetterebbe in ogni caso (anche se questo quasi mai accade).

In ogni caso, vedrei sicuramente come è la prestazione senza che il client effettui autonomamente i calcoli. Se le prestazioni non sono abbastanza buone, controlla se il rallentamento dei movimenti del giocatore sul server causa il ritardo (e inizia a utilizzare un thread diverso per ciascun client).

Se esiste effettivamente una limitazione reale della larghezza di banda (i movimenti stessi passano pochissimi dati), allora certamente è necessario trovare il ritardo medio di quel particolare utente e calcolarlo nell'algoritmo. Tuttavia, per continuare a cercare continuamente la media (per precisione), dovrai continuare a pingare sul server per trovare il tempo di andata e ritorno, che non dovrebbe essere così costoso.

+0

Non è un gioco 2D. Dovrebbe gestire simultaneamente centinaia di giocatori. Ho bisogno del sistema più ottimizzato possibile. – Tom

+0

hmm, in tal caso modificando il server in modo che invii i dati in intervalli abbastanza piccoli dovrà fare. Ovviamente tutti i server necessiterebbero di un qualche tipo di player cap, ma per lo meno aggiungere un ritardo di 10-20ms sul lato del movimento del client. È quasi impercettibile e nella maggior parte dei casi dovrebbe corrispondere alla posizione attuale dei giocatori. – AlbertoPL

1

Ci sono 2 modi in cui posso pensare di fare questo: se il client invia comandi al server & il server sarà il custode della mappa finale.

Oppure, tenere le mappe in clienti, & i clienti dovranno stabilire connessioni con altri clienti che stanno "vicino" al fine di fare il movimento, con registri svolto dal server & controllato da alcuni coetanei (polizia degli hacker).

Interessante per me è la possibilità di monitorare le connessioni peer e i peer che hanno una latenza superiore a una certa soglia non verranno visualizzati nel gioco.

+0

Interessante, ma questo tipo di limiti combatte come P2P non è in grado di gestire molte connessioni contemporaneamente: ora si sta facendo affidamento anche sulla connessione del client per altri client. Sto ancora cercando il miglior server <> sistema client. – Tom

+2

Perché P2P non può gestire molte connessioni? Ogni volta che qualcuno fa qualcosa, o hai bisogno di una ritrasmissione dal server, o un messaggio dal peer.Pensavo che il traffico fosse vicino allo stesso (potrei sbagliarmi). – ryansstack

Problemi correlati