View Full Version : [JAVA]Gioco multiplayer
Come potrei fare un gioco muliplayer?
Vorrei fare che uno potrebbe fare da server e rimanere in ascolto di vari client(numero prestabilito), e ovviamente che quando un client si connette riceve dati dal server e invia i propri.
Io ho pensato ad un thread che resta in ascolto della connessione dei client(temporizzato in modo da non bruciare troppa cpu, non so tipo 200ms) e che quando riceve la richiesta di connessione da un client avvia un altro thread adibito alla comunicazione con quel client.
Secondo voi andrebbe bene così??
Il fatto è che avrei molto thread poi, ed in più i thread per gestire i client(ognuno il suo) non devono essere temporizzati o sbagli? Altrimenti avrei un lag assurdo.
Mmm sto pensando, il thread che rimane in ascolto dei client può anche essere non temporizzato credo visto che tanto rimane bloccato finche un client non si connette.
Stavo poi anche pensando ad una cosa, se il ping di norma tra due linee adsl è di 90ms come cavolo faccio a spedire la posizione di un oggetto e rielaborarla dall'altra parte? Cioè se spedisco ogni 90ms circa, avrò un frame rate bassissimo!!!
Mettiamo un caso semplice dove c'è un server ed un solo client, ognuno può muovere una palla ede entrambi vedono sullo schermo la propria palla e quella dell'altro.
Si devono ovviamente spedire la posizione delle singole palle, ma andranno a scattissimi se spedisco ogni 90ms!!! Sono solo 11frame per secondo, assurdo ci deve essere un'altro modo!
Mi sono dimenticato di dire che prima parlavo del protocollo TCP :D
Sto guardando il protoccollo UDP e forse credo che potrebbe fare al caso mio...
Mmm sto pensando, il thread che rimane in ascolto dei client può anche essere non temporizzato credo visto che tanto rimane bloccato finche un client non si connette.Esatto ... rimane bloccato sulla accept().
Stavo poi anche pensando ad una cosa, se il ping di norma tra due linee adsl è di 90ms come cavolo faccio a spedire la posizione di un oggetto e rielaborarla dall'altra parte? Cioè se spedisco ogni 90ms circa, avrò un frame rate bassissimo!!!Innanzitutto in questi casi in cui si ha bisogno di una certa velocità, credo (ma non ne sono sicuro) che sarebbe meglio usare UDP invece che TCP.
Comunque non confondere la latenza (90ms) con la velocità! E comunque chi vuole veramente giocare "on-line" è bene che si prenda una ADSL settata in modalità "fast". ;)
Tieni presente che dal momento in cui invii un pacchetto di dati, esso arriva al destinatario con un certo ritardo (questo è ovvio e normale). Quello che ti deve importare non è tanto questa latenza ma la velocità con cui puoi spedire pacchetti! Non devi per forza spedire pacchetti ogni 90ms! Se tu spedisci pacchetti di dati ogni 20ms (50 volte al secondo) il destinatario li riceverà più o meno ogni 20 ms ma semplicemente "ritardati" di un tot di tempo, che è comunque molto basso! (90ms sono comunque meno di una frazione di secondo!).
P.S. stavo osservando il tuo avatar .... divertente :rotfl:
Ah ok capito grazie!
Te hai mai realizzato qualcosa del genere??
Stavo proprio guardando se non era il caso di usare l'UDP(mai fatto prima) se butto giù un po' di codice hai tempo di seguirmi un attimino? :D
Comunque mi chiedevo, se io ho un thread per ogni client dove spedisco i dati(parlo ancora del TCP) in pratica dovrei fare una cosa del genere
ObjectOutputStream.writeObject(pos_giocatore_server);
ObjectInputStream.readObject(pos_giocatore_client);
ObjectOutputStream.writeObject(altri dati);
In pratica ogni volta si blocca finchè non riceve i dati dal client giusto? Questo fa perdere un casino di tempo o sbaglio?
ps.grazie x l'avatar(fatto con le mie mainine il giorno dopo la vittoriaaaaaaa) :D
Te hai mai realizzato qualcosa del genere??No .... magari. :(
Stavo proprio guardando se non era il caso di usare l'UDP(mai fatto prima) se butto giù un po' di codice hai tempo di seguirmi un attimino? :DPiù o meno (più il meno che il più ;) ), perché non sono ferratissimo in materia di networking e socket.
Comunque mi chiedevo, se io ho un thread per ogni client dove spedisco i dati(parlo ancora del TCP) in pratica dovrei fare una cosa del genere
ObjectOutputStream.writeObject(pos_giocatore_server);
ObjectInputStream.readObject(pos_giocatore_client);
ObjectOutputStream.writeObject(altri dati);
In pratica ogni volta si blocca finchè non riceve i dati dal client giusto? Questo fa perdere un casino di tempo o sbaglio?Innanzitutto sarebbe, credo, meglio avere 2 thread per una singola comunicazione, uno per la scrittura e l'altro per la lettura.
Uhm ma i thread non cominciano a diventare un po' troppi?
Facciamo due conti, essendo un'applicazione grafica, quindi elbarazione e rendering:
SERVER
1 thread per elaborare la posizione
1 thread per disegnare quel che c'è da disegnare
1 thread per rimanere in attesa dei client
n thread dove n?numero client
2 thread per client 1 di lettura uno di scrittura
TOTALE=3+2*n thread
CLIENT
1 thread per elaborare la posizione
1 thread per disegnare quel che c'è da disegnare
1 thread per spedire i dati
1 thread per leggerli
TOTALE 4 thread
Non sono un po' tantini? :D
Non sono un po' tantini? :DDal lato client, avere 4 thread non è certamente un problema. Dal lato server, non credo nemmeno e comunque dipende da quanto vale quel "n".
Intanto butto giù un po' di codice per cercare di fare una connessione multithread sempre TCP per ora.
Più tardi spero di postare il risultato :fagiano:
franksisca
13-07-2006, 16:05
vai, ti seguo impazientemente, speriamo che ci riesca, e se hai problemi postali
A prop, mi sono "scopiazzato" il tuo avatar:D
Fai pure per l'avatar no problem :cool:
Sto scrivendo intanto fra poco dovrei postare le prime cose!
Problemino, che so come risolvere ma penso ci sia un metodo meno macchinoso del mio!
Allora ho un thread(A) il quale resta in ascolto delle connessioni dei client, quando un client si connette genera un thread(B) il quale svolge tutte le attività inerenti allo scambio di dati tra server e client.
Il problema è questo:come faccio dal thread(B) a far entrare ed uscire i dati che devo scambiare?
Un po' di codice:
...metodo run del thread(A)
public void run(){
try{
System.out.println("Server Avviato...");
while(true){
cs=ss.accept(); // crea il socket del client per comunicarci
nClient++;
ServerThread st=new ServerThread(cs,in,out); //E' il thread che si occupa dello scambio dati
st.start();
System.out.println(nClient);
}
}
catch(Exception e){
System.err.println(e);
}
}
Come potete vedere creo i thread quando un client si connette.
...metodo run thread(B)
public void run(){
Thread leggi=new Thread("Lettura"){
public void run(){
while(true){
try{
ObjectInputStream is=new ObjectInputStream(cs.getInputStream());
in=(String)is.readObject();
System.out.println(in);
sleep(1);
}
catch(Exception e){
System.err.println(e);
}
}
}
};
Thread scrivi=new Thread("Scrittura"){
public void run(){
while(true){
try{
ObjectOutputStream os=new ObjectOutputStream(cs.getOutputStream());
os.writeObject(out);
sleep(1);
}
catch(Exception e){
System.err.println(e);
}
}
}
};
leggi.start();
scrivi.start();
}
Allora in pratica il thread(B) istanzia altri due thread uno per la lettura ed uno per la scrittua di una stringa(in e out sono le stringhe)
Per usare tutto questo basta creare un oggetto di tipo Server ed automaticamente si creerà un thread che resta in ascolto delle connessioni, ma poi come passo i valori da scrivere e come tiro fuori ciò che ho letto???
Io ho pensato che potrei inserire tutti i thread che creo quando si connetto i client in un array invece di perdere i riferimenti, così posso usarli per scambiare i dati. Basterebbe infatti interrogare ogni thread uno ad uno con un ciclo for.
Mi sembra però un po' macchinoso.
Ho praticamente fatto una chat multiutente, cioè che ciò che scrivi lo vedono tutti, un po' come irc.
Il fatto è che non funziona :D cioè, quando scrive il server scrive a tutti i client, ma quando scrivono i client riceve solo il server...
Allora, ho finito la chat multiutente se posto il codice non mi prendete in giro vero? :D :fagiano:
Ho finito la mia piccola prova direi, si tratta di una connessione multiutente dove ogni utente può muovere una palla e scrivere in una chat, e ovviamente vedere la posizione delle altre palle.
In locale funziona benissimo ora vorrei provarlo "veramente" chi si offre? :D
Mi sono iscritto qui http://www.no-ip.com/ come faccio per poter reindirizzare il mio ip sulla rete?
Cioè vorrei che digitando il mio ip, non mi collego direttamente alla mia macchina ma passo da un loro server.
Ma magari apri un 3d apposta.
Anche se non vi frega dopo diverse prove con il TCP ho dedotto che forse non è quello che fa per me.
Sono riuscito a fare quello che volevo ma non mi piace molto il metodo, ora provo con l'UDP!
il_luridone
15-07-2006, 00:10
No, il TCP non fa per te, non fosse altro per l'algoritmo di Neagle che ritarda la spedizione dei segmenti tcp finchè non hanno una certa dimensione, per evitare frammentazione.
L'UDP in effetti era la scelta giusta fin da subito, ovvero un protocollo veloce che non dia garanzie di ricezione (non ti interessa che un pacchetto perso venga rispedito, essendo "real time" un pacchetto rispedito è già obsoleto e quindi inutile).
Magari una panoramica sui protocolli prima di mettersi a scrivere il codice aiuta ed evita fatiche inutili :D
Wikipedia di solito su queste cose è abbastanza buona come punto di partenza.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.