2011-12-09 12 views
5

Sto lavorando a un gioco di strategia a turni in Java (nel framework Android). Seguendo la struttura all'inizio di giochi Android, ho un thread di rendering e un thread dell'interfaccia utente. Il thread di rendering aggiorna ripetutamente lo stato del mondo e quindi ridisegna il mondo. Quando l'utente interagisce con lo schermo, la GUI invia Azioni al mondo (schema di comando). Ora sto aggiungendo giocatori AI, e qui è il mio piano:Come devo gestire la comunicazione tra i thread AI e il ciclo di gioco principale?

Ogni giocatore AI avrà una IA che viene eseguito su un thread separato.

Quando gli aggiornamenti mondiali su una piega AI, controlla per vedere se c'è una causa in corso. Se è così, lo esegue. Quindi chiede al giocatore di IA la sua prossima azione.

giocatore L'AI invierà la richiesta di un'azione per il filo AI, e poi tornare.

Alla fine, l'IA si presenti con un'azione e inviare di nuovo al mondo, che vedrà sul prossimo aggiornamento.

due domande:

1) Questo disegno sembrano suono?

2) Come gestisco la comunicazione da e verso il filo AI? Se ho la chiamata al thread AI world.queueAction (action), sembra che funzionerebbe, ma se il thread di rendering chiama ai.chooseAction (world) che eseguirà l'azione scegliendo sul thread render, che non è quello che voglio .

+0

Non stai facendo la logica mondiale nel thread di rendering, vero? – BRFennPocock

risposta

4

vorrei avere un ExecutorService per l'AIS e aggiungere attività ad esso per cose che vuoi di svolgere. Per l'interfaccia utente puoi avere una coda di cose che sono cambiate e potrebbe dover essere ridisegnata. Sarei tentato di usare un singolo thread per tutte le IA fino a quando non saprai che questo sarebbe d'aiuto. La maggior parte dei dispositivi Android ha solo 1-2 CPU.

+0

Ok, quindi la classe AI implementerà Runnable e il suo metodo run() calcolerà la prossima mossa in base allo stato del livello corrente e quindi accoderà una nuova Azione al mondo. AIPlayer avrà un ExecutorService statico. Quando selectAction() viene chiamato su un oggetto AIPlayer, aggiornerà la sua istanza AI con lo stato del livello corrente, quindi dirà al servizio executor di eseguire la sua istanza AI. – Perikles

+1

Sembra che funzioni, grazie! – Perikles

1

Se ho capito bene:

  • Hai un thread di rendering. Presumibilmente, questo funziona al frame rate del display.
  • Si ha una discussione "logica mondiale". Questo va da un timer prevedibile.
    • Hai fisica generale, input del giocatore o altre azioni in un thread;
    • e un thread separato per ogni personaggio AI

Sembrerebbe che è possibile eseguire in modo sicuro ognuno dei fili logici AI come Future e raccogliere i loro risultati insieme dopo aver fatto qualsiasi altra cosa il "mondo "il thread sta facendo, su ogni frame.

+0

In realtà è così: thread dell'interfaccia utente Android (registra il tocco dell'utente e altri eventi), Render thread (disegna lo schermo e aggiorna la logica del mondo, funziona al frame rate). Quindi non c'è un normale "clock tick" sugli aggiornamenti mondiali. Forse dovrebbe esserci? – Perikles

+0

Supponendo, quindi, che si tratti di un buffer di rendering fuori schermo o qualcosa del genere? Non devono avvenire tutti gli aggiornamenti dell'interfaccia utente in un thread su Android? (Lo hanno fatto in 1.5, ma non sono aggiornato, lo so ...) – BRFennPocock

+0

Ha un ciclo che aggiorna la logica mondiale, rende il mondo in un buffer, quindi blocca la tela, esegue il rendering del buffer e sblocca il tela, quindi torna all'inizio. – Perikles

2

Sei sicuro che il sistema sarà in grado di gestire un numero elevato di thread? Tenere presente che il numero 'ottimale' dei fili conduttori è solitamente n + 1, dove n è il numero di nuclei sistema contiene. Se questo è in esecuzione su un telefono, ce ne saranno meno, anche se non ne hai più di 10 ok ...

Per la connessione tra il tuo gioco e la tua intelligenza artificiale, può essere utile considerare la differenza tra il giocatore (umano) e l'intelligenza artificiale: c'è solo una distinzione importante: uno è un computer, l'altro no.Sarebbe meglio sottoporre le azioni che le IA portano alla stessa identica coda (o attraverso lo stesso meccanismo generale) dei giocatori umani (quindi, chiama lo world.queueAction(action);). Rende anche più semplice lo scambio tra AI e giocatori umani, poiché il codice di aggiornamento mondiale non ha bisogno di sapere la differenza ...

Suppongo che tu abbia già qualche tipo di evento da notificare al giocatore/aggiornamento lo schermo quando è il turno del giocatore umano. Esegui esattamente la stessa cosa con il/i thread/i IA: ascolta l'evento appropriato "It's your turn", causando il completamento di questi calcoli (questa iterazioni) e ponendo un'azione sulla coda. Si noti che questo deve essere fatto dal thread 'world update'; il thread di rendering dovrebbe riguardare esclusivamente il rendering dell'output sullo schermo (e riguarda solo in modo tangenziale l'input del player).

Problemi correlati