[Java] Threadoplossing voor strategiespel

Pagina: 1
Acties:

  • Potatoman
  • Registratie: September 2000
  • Laatst online: 20:16
Ik ben bezig met een spelletje, dat qua werking vergelijkbaar is met realtime-strategiespellen (ala c&c, simcity, transport tycoon etc.), waarbij ik op het moment aan het zoeken ben naar de beste manier om de game-events af te handelen.
Ik heb verder nog weinig aan het spelverloop gewerkt, omdat ik eerst zeker wil weten dat Java hier goede mogelijkheden voor heeft (en dat ik het werkend kan krijgen natuurlijk :) )

Ik heb al veel op java.sun.com gezocht, en heb aardig wat dingen met threads en gerelateerde zaken uitgeprobeerd. Uiteindelijk ben ik uitgekomen op een java.util.Timer met een TimerTask erbij. Deze blijft erg goed om een bepaalde tijd lopen, en als de taak vertraagd wordt, wordt er daarna in kortere tussenpozen de tijd (het aantal gemiste executies) ingehaald. Dit is ongeveer wat ik wil voor mijn spel.

Ik loop op het moment nog tegen één probleem aan: de mouselisteners die ik gebruik krijgen een hogere prioriteit dan de timer. Dat wil zeggen: als ik het speelveld scroll, gaat de timer pauzeren, en daarna als een gek de verloren tijd inhalen :'(

Daaruit volgend heb ik een aantal vragen:
1. Is het makkelijk om zelf een eenvoudige mouse(motion)listener te schrijven in de vorm van een thread of timer, en hoe efficiënt is dit vergeleken met de java listeners?
2. Denken jullie dat de java.util.Timer de beste oplossing is voor dit type werk?
Ik heb ook al gekeken naar de swingtimer en eigen threads, maar de utiltimer bevalt tot nu toe het beste.
3. Is het anders ook mogelijk de prioriteit van de bestaande mouselistener threads in te stellen, en hoe?

Bovendien werd het wel weer eens tijd voor een leuk javatopic :)

[ Voor 3% gewijzigd door Potatoman op 21-04-2003 00:12 ]

The cyclographing developer


Verwijderd

Ik dacht dat als je een nieuwe Thread aanmaakt, dat je die wel kunt gebruiken samen met Listeners.
Dus je maakt een niewe Thread en je laat een loopje het nodige doen (in dit loopje kun je de tijd opvragen System.getCurrentTimeMillis() en zo een tijdsinterval berekenen).
Vergeet niet om de lus even doen te slapen (bijvoorbeeld om de 1 millisec), anders kan de GUI wat sloom worden.

Verwijderd

beetje klok/klepel verhaal,

maar zou het niets te doen kunnen hebben met syncblocks?

  • ari3
  • Registratie: Augustus 2002
  • Niet online
Het lijkt er op dat thread prioriteit jouw probleem is aangezien mouse events eerder afgehandeld worden. Je gaf de mogelijke oplossingen zelf al aan.

In algemene zin kun je thread prioriteit niet gebruiken om realtime relatief te sturen (zoals jij wilt). De schedueling van threads is OS-afhankelijk is en je daarmee dus geen garantie hebt hoe het werkelijk draait.

Je moet jezelf even inlezen op het gebruik van de thread synchronisatie methoden wait() en notify(). Hiermee kun je de thread executie beter in de hand houden.

"Kill one man, and you are a murderer. Kill millions of men, and you are a conqueror. Kill them all, and you are a god." -- Jean Rostand


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22-08 01:56
Mijn kennis van event handling in Java is helaas vrij beperkt, maar als mijn vermoedens kloppen dat het ongeveer op dezelfde manier werkt als (bijvoorbeeld) onder Windows, dan heeft je probleem niet met prioriteiten te maken, maar met het onevenredig vullen van de event queue (wachtrij van gebeurtenissen) met 'mouse moved' events en 'timer' events.

Als de applicatie sneller 'mouse moved' events genereerd dan dat ze afgehandeld kunnen worden (doordat je bijvoorbeeld als reactie het speelveld opnieuw wilt tekenen, wat lang duurt) wordt de event queue overspoelt met die events. De Timer voegt dan wel op een vast interval Timer events aan de queue toe, maar omdat die queue steeds langer wordt, worden die events pas later afgehandeld. In dat geval helpt het wijzigen van de Timer thread (als die al in een aparte thread draait) je helemaal niets, aangezien het toevoegen van events wel tijdig gebeurd (binnen een kleine marge).

Probeer eens of het leegmaken van je teken-methode (paint(), update(), of nog iets anders) het probleem oplost? Zo ja, dan is de oorzaak van het probleem duidelijk en hebben we een beginpunt om verder over te discussieren. (Tekenen in een aparte thread, bijvoorbeeld.)

  • Potatoman
  • Registratie: September 2000
  • Laatst online: 20:16
Soultaker schreef op 21 april 2003 @ 11:55:

Probeer eens of het leegmaken van je teken-methode (paint(), update(), of nog iets anders) het probleem oplost? Zo ja, dan is de oorzaak van het probleem duidelijk en hebben we een beginpunt om verder over te discussieren. (Tekenen in een aparte thread, bijvoorbeeld.)
Hier heb ik ook al even mee geexperimenteerd, door de repaint instructie in een aparte thread te zetten, of in de timer klasse te zetten. Als ik dan heftig met de muis heen en weer beweeg dan krijgt de mouselistener nog steeds een hogere prioriteit dan de timer en de repainter, wat als gevolg heeft dat het beeld nogal schokt.

Vraagje over de mouselisteners: zijn er eenvoudige manieren waarop ik de positie van de muis kan opvragen, en welke knop ingedrukt is? Als dat zo is, kan ik misschien beter proberen het te integreren in mijn huidige oplossing.

The cyclographing developer


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22-08 01:56
Potatoman schreef op 21 April 2003 @ 12:08:
Hier heb ik ook al even mee geexperimenteerd, door de repaint instructie in een aparte thread te zetten, of in de timer klasse te zetten. Als ik dan heftig met de muis heen en weer beweeg dan krijgt de mouselistener nog steeds een hogere prioriteit dan de timer en de repainter, wat als gevolg heeft dat het beeld nogal schokt.
Wat je volgens mij beter kunt doen, is een aparte thread starten, die continue tekent (en dus niet meerdere teken-threads bij elkaar). Dan heb je tenminste nog het 'prettige' Java event model en hoef je niet handmatig de huidige positie van de muis in de gaten te houden (als dat ueberhaupt al kan).

Had je ook al geprobeerd om helemaal niets te tekenen? Dan weet je tenminste zeker of het probleem 'm in de vertraging van het tekenen zit.

Volgens mij heeft het met prioriteiten niets te maken; ik neem aan dat je geen aparte MouseListener thread hebt. Normaliter krijg je niet zóveel events tegelijk binnen dat je ze niet tijdig af zou kunnen handelen, dus als je dan gewoon zorgt dat je de langdurige zaken elders (in een andere thread) afhandeld, zou het probleem opgelost moeten zijn. Dit betekent natuurlijk wel dat je niet voor elke "mouse moved" event het scherm opnieuw kan tekenen.

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
Bah zit hier ook met Java UI bezig op het moment - kan maar een ding zeggen: ROT slecht (die event handler zuigt enorm) tip: gebruik, zoals soultaker zegt een aparte thread voo tekenen en stuur je MouseListener (wat een naam) zelf 'teken' messages door: beetje zoals een Graphics API doet. Het probleem zit em in het feit dat je MouseListener in dezelfde thread zit als je Teken ding : dwz dat de domme event handler gewoon messages erachter propt en krijg je dus de bekende Jump In Time gevallen. Nog beter lijkt me:

1 Thread (waar je x-keer per seconden een update stuurt (mbv milliseconds)) -> Swing Thread (get Mouse Dingens) -> Draw Thread. (ie NOT event based).
Pagina: 1