Come devo sviluppare il mio gioco Android in modo efficiente? [chiuso]


11

Ho allegato un'immagine di un diagramma di flusso che ho realizzato in vernice. Diagramma di flusso del concetto di gioco

L'immagine mostra come voglio sviluppare il mio gioco. Voglio un gioco che funzioni alla grande con una codifica intelligente che sia facile da aggiornare e funzioni pubblicitarie nel tempo. La mia piattaforma di destinazione è lo smartphone Android e tutto il codice sarà scritto in Java con risorse gonfiate in XML, se questo è importante. Non sto cercando un hard code, anche se lo pseudo-codice sarà di aiuto, preferirei di più suggerimenti e consigli dai professionisti.

Le mie domande sono:

È un buon modo per programmare un gioco o ci sono modi migliori per farlo? Ci sono delle modifiche che devono essere fatte? Eventuali suggerimenti sarebbero utili perché non ho esperienza nella programmazione di giochi, quindi preferirei i consigli di qualcuno che ha scritto diversi giochi e sa per esperienza come si dovrebbe fare per impostare il proprio codice per funzionare in modo efficiente.

Risposte:


12

Molti giochi Android non sono nemmeno abbastanza grandi da giustificare il salvataggio / caricamento o le opzioni / preferenze, non importa i personaggi personalizzati e simili semplicemente perché vengono giocati a mano per 10 minuti sul treno di casa.

Non commettere l'errore che ho fatto di intraprendere qualcosa con un ampio scopo per un primo gioco Android. Crea un gruppo di giochi più piccoli, quindi scegli qualcosa di più grande

Caratteristiche specifiche di Android:

Struttura:

Consiglierei di avere quasi tutto il gioco in una classe di attività. Android funziona sull'idea che ogni attività è come una mini-app, semi-indipendente dalle altre attività nell'app. L'app è essenzialmente una serie di attività, con l'utente che vede quale è sempre in cima.

Quando ne fai uscire uno in alto, generalmente viene distrutto e verrà ricreato la prossima volta che l'utente avvia una nuova attività (intento startActivity). Ciò rende difficile mantenere gli stati tra le attività e porta a un'unica architettura di attività

Potresti voler avere un'attività di tipo schermata principale con un menu "Nuova partita / Carica partita / Opzioni" su di essa e fare quella attività di lancio. Tuttavia, alla fine dovrai avere un menu di gioco anche nella tua attività di gioco, che avrà la maggior parte delle stesse funzioni al suo interno

La mia app, ho creato un "MenuActivity" che ha le funzioni che lanciano un nuovo gioco, salvano, caricano, cambiano opzioni. Quindi la mia HomeActivity lo estende, così come la mia GameActivity.

Dal momento che tutto è in una classe Activity, consiglierei di creare una gerarchia di classi di attività e utilizzare lotti di ambito privati, protetti e predefiniti. In questo modo, almeno puoi dividere le cose in file diversi per evitare di avere un file attività ingestibile. Ad esempio per la mia app:

GraphicsEngine extends MenuActivity.

PhysicsEngine extends GraphicsEngine.

GameLogicActivity extends PhysicsEngine.

UIActivity extends GameLogicActivity.

Dal momento che la mia app è in 3D, molte cose che faccio non funzionano tra le attività, quindi tutto è nella stessa attività, quindi forse sono distorto verso l'uso di un'architettura di attività

-

Threading

Per l'attività di gioco, hai due thread (o 3 se stai facendo cose 3D opengl). Un thread è l'interfaccia utente / thread principale. Questo è il thread in cui l'attività inizia e viene eseguita e ti viene data da Android.

Questo thread dell'interfaccia utente è l'unico in cui è possibile aggiornare gli elementi dell'interfaccia utente (viste, layout ecc.). È anche quello in cui verranno eseguiti tutti i listener per l'input dell'utente. Non vedi nessuno dei meccanismi del thread dell'interfaccia utente, solo che viene eseguito da qualche parte in un ciclo in background.

Il secondo thread, te lo fai (consiglierei di usare AsyncTask , nonostante tutte le sue carenze). Questo fa tutte le cose che non fai nell'interfaccia utente in un normale ciclo di gioco, come l'aggiornamento dei movimenti, il calcolo delle collisioni, i calcoli del combattimento e così via.

Rendi questo thread / classe AsyncTask come una classe interna della tua attività. In questo modo, è possibile disporre di alcuni oggetti ( Vector<Spaceship>) a portata di attività a cui è possibile accedere sia dal thread dell'interfaccia utente sia dal thread del loop di gioco.

Dal momento che la logica di gioco è in corso nel thread del loop di gioco, questo è l'unico thread che dovrà effettivamente cambiare i valori delle variabili (aggiornare la velocità del serbatoio, ridurre gli HP dei giocatori). Il thread dell'interfaccia utente legge solo i valori, quindi dovrebbero esserci problemi di concorrenza minimi.

Il problema è che il thread dell'interfaccia utente esegue aggiornamenti su richiesta del thread del loop di gioco. Ci sono un paio di modi per farlo. Se leggi la documentazione di AsyncTask, ha il metodo publishingProgress () / onProgressUpdate (). Questo in realtà sta aggiungendo elementi alla coda di thread del thread dell'interfaccia utente per eseguire il ciclo successivo.

Handler fa esattamente la stessa cosa, in cui si implementa il metodo handleMessage () e quel metodo viene effettivamente eseguito dal thread successivo dell'interfaccia utente.

Infine, qualsiasi input dell'utente, trovandosi nel thread dell'interfaccia utente, è possibile aggiornare immediatamente gli elementi dell'interfaccia utente (quindi all'interno dell'implementazione di tutti i listener onClick / onTouch). Se è necessario aggiornare gli oggetti di gioco, è possibile utilizzare cose come la sincronizzazione o è possibile implementare la propria coda di aggiornamenti in AsyncTask che, come il thread dell'interfaccia utente, passa alla successiva esecuzione del ciclo di gioco

Guida ai thread Android .

-

UI

Per quanto riguarda l'attuale struttura dell'interfaccia utente all'interno della singola attività, ti consiglio di avere un layout di frame come layout di base. Gli elementi figlio in un layout di frame funzionano come una coda. Il primo elemento viene disegnato per primo, il secondo viene disegnato in cima al primo, il terzo in cima al secondo.

In questo modo, è possibile disporre di più file di layout XML e, gestendo i figli del layout della cornice, è possibile scambiare facilmente set di viste dentro e fuori.

Se hai sempre SurfaceView in basso (primo figlio nel layout della cornice), puoi utilizzare tutte le solite viste / widget Android (pulsanti, viste di testo, viste di scorrimento) ecc. Sopra la vista di superficie, che fa la parte grafica del gioco.

Quindi, ad esempio, se qualcosa si sta caricando, puoi mettere in pausa il loop del gioco / farlo saltare per saltare tutto, aggiungere una schermata di 'caricamento' opaca come ultimo figlio al layout della cornice e l'utente vedrà apparire 'caricamento' sullo schermo , del tutto inconsapevole che dietro ci siano altre opinioni. In questo modo non è necessario rimuovere le visualizzazioni che richiedono molto tempo per essere configurate o causare complicazioni ogni volta che vengono aggiunte / rimosse.

Consiglierei anche di utilizzare i lotti View.setVisibility. Ad esempio, è possibile aggiungere un intero layout di "inventario" al layout del frame di base e quindi impostareVisibility (View.Visible) su di esso quando l'utente fa clic per visualizzare il proprio inventario e setVisibility (View.Gone) quando lo chiudono di nuovo. In questo modo, non stai nemmeno gestendo i figli del layout del frame, ma semplicemente aggiungendo tutto e rendendo le cose visibili / invisibili come e quando l'utente fa cose diverse

Questo aiuta di nuovo con il threading; quando l'utente fa clic per aprire il proprio inventario, onCLickListener viene gestito nel thread dell'interfaccia utente, l'inventario viene reso visibile al suo interno e il metodo updateInventory viene chiamato, sempre dal thread dell'interfaccia utente, con solo getter su tutti gli oggetti di gioco chiamati

Ecco il diagramma che ho fatto per una domanda precedente sull'idea di layout di singola attività / frame:

inserisci qui la descrizione dell'immagine


quindi secondo te dovrei avere un layout a frame per contenere tutti i componenti del loop di gioco, giusto? Se lo facessi, come potrei ottenere visualizzazioni nella classe HUD per interagire con SurfaceView, ad esempio un d-pad virtuale / analogo virtuale? ho provato a fare cose del genere prima e ho riscontrato errori.
kdavis8,

Riscriverò la mia risposta per renderla un po 'più chiara
Spoon Thumb

Ho riscritto la mia risposta. Spero che sia più chiaro
Spoon Thumb

Grazie mille per la scomposizione che spiega davvero le cose, non ci sono davvero molti buoni tutorial là fuori per lo sviluppo di giochi Android
kdavis8,

11

Molto di ciò che vedo nel tuo diagramma è correlato all'interfaccia utente e questo sembra abbastanza ragionevole. C'è solo una piccola parte del diagramma riservata alla logica di gioco reale, ed è molto vaga.

Penso che stai provando troppo. Vorrei suggerire di iniziare a scrivere codice. Scegli un problema particolare e inizia a risolverlo. Imparerai così tanto che quando avrai una migliore idea di quale sia il tuo spazio problematico avrai una prospettiva completamente diversa (e più utile).


2
Non potrei essere più d'accordo con questo. Scegli un'architettura di design adatta al gioco e alle tue preferenze, quindi inizia a scrivere codice. Quando si colpisce un particolare problema prestazionale, ottimizzare fino a quando non funziona. Ogni singolo meccanismo nel tuo gioco avrà le sue caratteristiche prestazionali e potenziali ottimizzazioni - devi pensarci individualmente, non nel suo insieme.
Polinomio,

dove si potrebbe trovare una guida a tali schemi per l'architettura di gioco? sarebbe davvero utile per me.
bot_bot,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.