2009-11-05 15 views
15

Recentemente ho provato a scrivere un gioco in C#. Non sto usando XNA per questo, perché pensavo che avrei imparato di più se ho codificato il gioco da zero (anche se sto usando un motore multimediale).Programmazione giochi - comunicazione tra oggetti di gioco in 2d

Sto provando a progettare un gioco di ruolo in 2D, un po 'ambizioso, lo so, tuttavia ho una comprensione abbastanza buona almeno delle parti di base del gioco (cioè il codice' piastra di cottura '), e io' Ho raggiunto una parte in cui non so dove andare da qui.

Nel gioco 2D, si progredisce attraverso il gioco camminando intorno a diverse 'aree'. Una volta premuto un "riquadro portale", si viene trasportati nell'area successiva, ecc.

Non riesco a capire come devono essere impostati questi oggetti area. Questa è stata la mia prima idea: ogni area ha alcune strutture di raccolta diverse (ad esempio, un quadrangolo di visibilità, un quadruplo di collisione, un elenco di entità AI ecc.). Quindi, se dovessi aggiungere un'entità nemica nel gioco, verrebbe inserita nel quadrangolo di visibilità, nel quadruplo di collisione (perché puoi scontrarti con le entità) e nell'elenco delle entità AI. Quando l'area riceve una richiesta di aggiornamento, dice a ciascuna di queste strutture di aggiornarsi, il che a sua volta comunica alle entità di aggiornarsi. Tutto bene, finora.

La mia domanda è questa: cosa succede se questo nemico ha bisogno di comunicare con altri oggetti? Ad esempio, potrebbe essere necessario sapere se il giocatore si trovava in un certo intervallo di esso. O se sia stato colpito dal giocatore. O dove tutti gli oggetti collidabili sono nell'area (quindi potrebbe pathfind).

La prima (e cattiva) soluzione a questo problema sarebbe semplicemente passare ogni entità un riferimento a ciascuna raccolta. Ma questo ovviamente incoraggia gli oggetti strettamente accoppiati, il che non è buono.

La seconda soluzione che ho elaborato era che ogni entità fosse in grado di interrogare l'area, tramite le strutture dei messaggi. Quindi un nemico sarebbe in grado di dire "Dammi un elenco di ogni entità entro X distanza dalla mia posizione" e l'area restituirebbe una risposta. Tuttavia, questo diventerebbe sempre più difficile poiché dovrei codificare sempre più possibilità nell'area ("Dammi un elenco di entità che non si trovano entro X distanza da me stesso", "Dammi un elenco di tutte le entità con salute inferiore a X "ecc.).

Quello che sto cercando è una soluzione testata nel tempo per questo problema di comunicazione tra oggetti e fondamentalmente come impostare un'area. Suppongo che avrebbe bisogno anche di una sorta di sistema di messaggistica, anche se non ne sono sicuro.

Grazie per la lettura.

+4

muro di testo è spaventoso – Chad

risposta

4

È possibile esaminare lo Mediator pattern. Ti permetterebbe di avere un accoppiamento basso, ma sì, tu vorrebbe avere un sacco di codice nell'oggetto/i mediatore per facilitare la comunicazione tra gli altri oggetti. Ma penso che sia l'uno o l'altro. E poi questo è preferibile.Ti consentirebbe inoltre una maggiore libertà di fare trucchi, come accodare alcune richieste di aggiornamento e gestire le richieste in momenti più opportuni, o fare l'elaborazione in batch di molte richieste, invece di eseguirle una ad una che imporrebbe (ipoteticamente) una sorta di spese generali.

4

Penso che l'opzione migliore per questo genere di cose sia quella di utilizzare molto il pattern Observer ... creare eventi (decidendo quanto generico o concreto è un'altra decifrazione di progetto) e rendere i propri oggetti abbonarsi a quelli di cui hanno bisogno.

Ad esempio, il motore può generare eventi di collazione o prossimità quando 2 entità sono vicine, ma queste verranno ricevute solo dalle entità interessate. Puoi fare alcune ottimizzazioni per controllare solo quelle condizioni con gli osservatori riconosciuti.

Non so se questo è un posto comune nei giochi e non l'ho mai usato in alcun gioco (ancora), ma ho pensato molte volte a questo proposito ed è l'opzione che mi piace di più.

+1

Il problema di questo è però che il motore è responsabile per il monitoraggio di tutte le cose che accadono e degli eventi di fuoco quando necessario, al contrario delle entità che si mantengono. –

3

Un buon approccio potrebbe essere quello di configurare un'architettura client/server. Quindi il server avrebbe gestito tutti gli aggiornamenti del mondo di gioco e la logica interna e il client avrebbe solo chiesto al server se poteva fare determinate azioni. Il server avrebbe quindi risposto e il cliente avrebbe solo disegnato e aggiornato la schermata di gioco. Le entità non giocanti farebbero lo stesso. L'unica differenza sarebbe che il client è controllato dall'uomo e che le altre entità sono controllate dal computer. Ciò consentirebbe di separare la configurazione del mondo di gioco e gli eventi e gli aggiornamenti dalla logica dell'entità.

Il "sistema di messaggi" che hai citato è chiamato protocollo dell'applicazione e può essere un sistema binario esoterico complesso, o semplici stringhe leggibili dall'uomo che io raccomanderei. Mentre il giocatore si sposta, il server invierà una lista di entità che sono in vista del cliente. Le entità non giocanti dovrebbero operare nello stesso modo. Ovvero chiedendo al server il permesso di fare cose o informazioni su un'altra entità che il server l'ha precedentemente inviato mentre si spostava e arrivava nella vista dell'entità e il server rispondeva con la risposta o le informazioni appropriate.

Se si dovesse perseguire questo obiettivo con i socket si avrebbe la ovviamente beneficio di gioco in rete intrinseca come il server non importa se il cliente fosse collega sulla stessa macchina server è in esecuzione o se il cliente è in tutto il continente . Questo potrebbe non aver risposto alla tua domanda specificatamente con il codice, ma spero che sia stato almeno uno spunto di riflessione.

+1

Sicuramente spunti di riflessione. :) –

2

Questo è in genere molto più semplice se si dispone di un oggetto sopra l'entità che esegue la gestione. (ad esempio il "mondo" o il "gioco"). Può vedere facilmente quali entità sono in prossimità di altre e inviare di conseguenza eventi e notifiche.

Se le entità hanno bisogno di un po 'più di contesto per prendere decisioni significative quando vengono aggiornate, puoi sempre far passare il mondo in quel contesto in qualche modo. Ma lascia che il mondo gestisca il partizionamento e il posizionamento delle entità piuttosto che richiedere alle entità di preoccuparsi direttamente di ciò.

(Inoltre, perché un quadtree? Per un 2D rpg una griglia grossolana sarebbe probabilmente molto più semplice da implementare e ugualmente utile.)