-
Jarek
witam,
spotkal sie juz moze ktos z takim problemem??? mam aplikacje client - server, ktora wysyla w czasie rzeczywistym dane z klawiatury. Nie moze byc opoznien, bo to jest gra arkanoid i dane musza byc na bierzaco aktualizowane.
Doszedlem tylko do takiego momentu, w ktorym dane sa wysylane za wolno i zle dziala, albo pojawia mi sie wyjatek tak jak w temacie.
wie moze ktos jak ten problem rozwiazac???
pozdrawiam -
mystery
-
Jarek
glowna petla gry
public void run(){
Thread myThread = Thread.currentThread();
Graphics g = getGraphics();
while (t == myThread){
startTime = System.currentTimeMillis();
if(paused){
try{
Thread.sleep(500);
}
catch(InterruptedException e){}
lastFrame = System.currentTimeMillis();
}
else{
g.setColor(0);
g.fillRect(0,0,getWidth(), getHeight());
g.setColor(0xffffff);
player.paint(g);
player2.paint(g);
myBall.paint(g);
flushGraphics();
keyState = getKeyStates();
this.keyboard(); / /czyta zdarzenia z klawiatury i uruchamia dalsze metody
if(player.collision(myBall) || player2.collision(myBall));
myBall.collision(true);
myBall.cycle((int)(System.curr entTimeMillis() - lastFrame));/ /ruch pilki
lastFrame = System.currentTimeMillis();
int timeSoFar = (int) (System.currentTimeMillis()-st artTime);
if ( timeSoFar < MS_PER_FRAME){
try{
Thread.sleep(MS_PER_FRAME - timeSoFar);
}
catch(InterruptedException e){}
}
}
}
}
-
Jarek
petla klienta
public void run() {
try{
locDevice = LocalDevice.getLocalDevice();
browser = locDevice.getDiscoveryAgent();
}catch(Exception e){
e.printStackTrace();
}
while(true){
try {
mDateConnect = browser.selectService(SERVER_U UID,
ServiceRecord.NOAUTHENTICATE_N OENCRYPT, false);
if(mDateConnect != null){
con = (StreamConnection) Connector.open(mDateConnect);
game.go(con);
dos = con.openDataOutputStream();
dos.writeInt(game.getKeyState( ));
dos.flush();
dos.close();
dis = con.openDataInputStream();
game.movePlayer2(dis.readInt() );
dis.close();
thread.sleep(50);
}
}catch(Exception e){}
}
} -
-
KosciaK
}catch(Exception e){}
I to prawdopodobnie jest odpowiedź. Program może wywalać masę wyjątków, o których nawet nie masz pojęcia. A jako, że wszystkie streamy zamykasz w bloku try to przy pojawieniu się wyjątku nie zostaną zamknięte! -
Jarek
hmmm.... ten kod co wkleilem to dziala ale chodzi o to ze nie wszystkie informacje sa przesylane o ruchu, np jak zrobilem 3 szybkie ruchy to zostaje wyslany tylko 1.
czyli po prostu jakby ta glowna petla byla za szybka, ale jak zwolnie to dziala beznadziejnie i tez nie ma takie rezultatu jakbym chcial.
inna opcja jest taka, ze w glownej petli moge wywolywac dodatkowa metode
public void sendMovement(int x, StreamConnection con){
try {
dos = con.openDataOutputStream();
dos.writeInt(x);
dos.flush();
dos.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
ale wtedy wywala mi wyjatek no output streams.
Pierwsze przejscie przez glowna petle jest wyslane, ale potem prawdopodobnie polaczenie nie daje rady sie tak szybko zamknac i nie wysyla.
nie wiem jak rozwiazac ten problem :( -
KosciaK
Dodaj ex.printStackTrace(); w obu pętlach i zobacz czy (i jakie) wyjątki ci zwraca. A najlepiej to przyrzyj się temu w debugerze -
KosciaK
no i jeszcze dość ważne pytanie to w którym miejscu pojawia ci się ten wyjątek "no more output streams". -
Jarek
public void sendMovement(int x, StreamConnection con){
try {
//w tym momencie
dos = con.openDataOutputStream();
//
dos.writeInt(x);
dos.flush();
dos.close();
} catch (IOException ex) {
ex.printStackTrace();
}
} -
mystery
A nie lepiej zamiast tej petli zrobic jakiegos KeyListenera, ktory bedzie wysylal wartosc wcisnietego klawisza? -
mystery
albo jeszcze sproboj zrobic tak:
otworz strumien
while(true){
wysylaj wcisniety klawisz
sleep(50)
}
zamknij strumien
-
Eric Wu
Arkanoid klient-serwer?
Ciekawy pomysł...
Ja bym to zrobił inaczej:
Key listener który by reagował na zdarzenie wciśnięcia klawisza. I teraz jedna z 2 rzeczy:
Wersja 1: zapis do tablicy klawiszy (bufor), wywołanie synchronizowane oczywiście, w pętli run co np. 100 ms również w synchronizowanym bloku zczytywany jest ten bufor, zamieniany na ciąg znaków, przesyłany do serwera i czyszczony, serwer analizuje ciąg, odtwarza sekwencję i reaguje.
Wersja 2: w momencie wciśnięcia klawisza w samym listenerze wywoływana metoda wysłania znaku do serwera
Moim zdaniem to problemem jest jedna z 2 rzeczy:
1. zrzuca Ci jakieś wyjątki tam gdzie nie wypisujesz co się stało w catch (czyli brak printStackTrace) i nie zamyka pootwieranych strumieni, robi Ci się ich dużo nie pozamykanych i w końcu program dociera do ograniczenia ich ilości
O tym już wspominali przedmówcy.
2. może zbyt często i za dużo strumieni otwierasz, zamknięcie strumienia przez close nie koniecznie musi oznaczać, że został on już do końca zamknięty i nie zajmuje miejsca w jakiejś ograniczonej puli, możliwe, że jak otwiera się i zamyka ich kilkadziesiąt na sekundę to można jakieś wewnętrzne ograniczenie JVM lub systemu operacyjnego po pewnym czasie przekroczyć
Moim zdaniem powinieneś otworzyć jeden strumień przy połączeniu (ewentualnie dwa strumienie jeden do komunikacji klient->serwer i drugi w drugą stronę) i wysyłać oraz odbierać w nich po jednym znaku, a nie otwierać oddzielny strumień dla każdego znaku.
Zresztą przedmówca już o tym pisał. -
Ja nie istnieje (FURBY)
Ja bym wysyłał komunikaty, ale w Javie jest CORBA i RMI może warto z nich skorzystać w końcu po coś są. :)
- Przeglądaj grona w kategorii Internet i Komputery
- Przeglądaj grona w okolicy Warszawa
- Załóż własne grono tematyczne
- Zostań moderatorem
Podobne Tematy
|
|
Wszystko co związane z programowaniem w Java (J2EE, JSP, JDBC, itd) test
Miejsca grona (1)
-
Kino Luna ul. Marszałkowska, Warszawa
www.kinoluna.pl kino.luna@maxfilm.com.pl 22 621 78 28
- Dodaj miejsce

