Stai creando un livello multiplayer 2D senza interruzioni?


15

Recentemente è emersa una discussione su come creare un gioco multiplayer 2D a scorrimento laterale che può avere un design a livello di loop (Pensa a Starbound e al modo in cui i loro mondi sono in loop).

Ho pensato che il modo più semplice sarebbe quello di avere una mappa rettangolare con zone trigger che potesse teletrasportare i giocatori da una parte all'altra. Tuttavia, l'ovvio problema con questo approccio è il caso di avere più giocatori sul bordo della mappa contemporaneamente. Non vuoi teletrasportare i giocatori uno di fronte all'altro e avresti bisogno di un modo per trasportare i giocatori senza far scomparire gli altri giocatori.

Per aggiungere questa idea e risolvere il problema, mi è venuto in mente quanto segue: avere una zona trigger (quadrato rosso nell'immagine) in cui i giocatori saranno in grado di vedere una "zona clone" (quadrato verde). In questo quadrato verde, gli oggetti dal lato opposto della zona di trigger verrebbero copiati nella corrispondente zona di clone (può essere visto con le forme A e B). Quando un giocatore arriva al bordo iniziale della "zona clone", viene teletrasportato dall'altra parte della mappa.

Immagine

In questo esempio il Giocatore 2 penserebbe di vedere il Giocatore 1, tuttavia vedrebbe effettivamente il suo clone e viceversa.

Sembrava un po 'estremo e complesso per il problema in questione. La mia domanda ora è sapere se questa soluzione è un buon approccio per affrontare il problema o esiste un modo più semplice per risolvere questo problema?


I giocatori sono autorizzati a spostarsi indietro in un'area precedente?
XiaoChuan Yu,

sì, avanti e indietro in modo da dare una sorta di effetto "passeggiare per il mondo". Simile a come è un mondo in starbound
KenQueso,

2
Hai mai considerato di trasformare il mondo in un grande cerchio? o trattare il livello come un grande cerchio e tradurlo in una fase 2D piatta?
Nzall,

non riesci sempre ad allineare la posizione della telecamera con il giocatore controllato?
Ali1S232,

Risposte:


16

Questo sistema con tutti questi trigger sembra un po 'troppo complicato e soggetto a errori.

Puoi avvolgere la posizione del giocatore usando il modulo con qualcosa di simile playerPositionX = playerPositionX % mapWidth

In questo modo quando il tuo giocatore raggiunge playerPosition == mapWidthilplayerPosition sarà ripristinare di nuovo a 0.

Questa soluzione potrebbe essere estesa con l'intero sistema di rendering.


1
non sarebbe questo il problema della chiusura da parte dei giocatori che vedono i giocatori la cui posizione resettare teletrasportarsi?
KenQueso,

Come estenderesti questo al sistema di rendering?
Mikael Högström,

Potresti avere un giocatore sempre al centro della videocamera e far girare la mappa. Come una mappa nella civiltà in modalità terra. Un altro approccio potrebbe essere quello di rendere la parte visibile di un giocatore su entrambi i lati della mappa.
Exaila,

4
@ MikaelHögström Basta renderizzare come al solito, ma le cose vicine al bordo destro devono essere rese una seconda volta a sinistra (cioè a pos - map_width).
Mario,

1
Ovunque nel tuo codice stai cercando 'quale oggetto si trova a questa coordinata' o 'quali sono le coordinate di questo oggetto', lo renderesti xcoord% mapWidth. È difficile dirlo senza il tuo codice, ma probabilmente lo renderebbe correttamente.
Tin Man,

13

La soluzione canonica è utilizzare i portali . Nel tuo esempio, c'è solo un livello, tranne che c'è un portale che collega le estremità sinistra e destra.

Qualunque cosa si muova attraverso quel portale avrà le sue coordinate tradotte all'altra estremità del portale, in modo che se qualcosa si muove a sinistra attraverso il portale, riapparirà sul lato destro del livello e viceversa.

La tua fotocamera deve supportare anche i portali; se il portale si trova all'interno della telecamera, deve eseguire il rendering di parti del livello su entrambi i lati del portale. Se hai familiarità con gli editor di immagini per la grafica di piastrelle senza soluzione di continuità, è lo stesso affare qui.

La parte noiosa è che tutto ciò che riguarda la distanza o il percorso dovrà anche supportare i portali. Ciò include AI, algos line-of-sight, attenuazione del suono e così via.

La cosa bella dei portali è che è molto potente. Il motore di build lo ha utilizzato per simulare livelli multi-story, nonostante non sia un "vero" motore 3d. Alcuni motori moderni usano anche i portali per creare spazi non euclidei; Portal e Antichamber sono esempi notevoli in 3D.


2
Se ascolti il ​​commento del gioco del portale, parte del modo in cui funzionano i portali viene implementata clonando ciò che è visibile attraverso il buco. (ma per motivi di fisica piuttosto che render)
Mooing Duck

6

Ricorda che ciò che visualizzi sullo schermo e ciò che è in memoria sono due cose totalmente diverse. Immagina di avere una finestra che devi riempire di dati sul mondo. Riempi la finestra da sinistra a destra. Mentre analizzi i tuoi dati per riempire il mondo, se raggiungi la fine del mondo, torna semplicemente all'inizio dei tuoi dati. L'uso di un'operazione modulo è l'ideale. Ricorda che devi farlo per tutto . Proiettili, raggi, giocatori, fisica; tutti hanno bisogno di avere le loro posizioni avvolte quando attraversano i confini del mondo.

Ogni giocatore condivide i dati, ma ha la propria prospettiva dei dati. Le loro finestre sono popolate in modo diverso a seconda di dove si trovano nel mondo.

Ciò significa che non è necessario creare cloni o teletrasportare nessuno. Essenzialmente tu sta creando cloni, semplicemente rendendo i personaggi ai rispettivi schermi.


3

Disconnetti il ​​rendering dal mondo e puoi eseguire un rendering avvolgente e corretto senza ricorrere a artefatti di clonazione o teletrasporto.

Innanzitutto, nel tuo mondo hai un mondo di dimensioni fisse, da 0a Width. Ogni volta che un oggetto scende sotto lo 0 lo avvolgi fino alla fine e ogni volta che un oggetto è finitoWidth avvolgi all'inizio. Ciò significa che tutti gli oggetti logici nel tuo mondo sono sempre nel raggio d'azione 0...Width.

In secondo luogo, per il rendering farai modulo sulla posizione. Quindi il lato sinistro dello schermo è "Base" e il lato destro è "Base + Dimensione". Quindi guardi nel tuo mondo alla ricerca di qualcosa all'interno di quel raggio. In realtà cercherai l'intervallo del modulo, che lo mappa nuovamente 0...Width.

Il trucco durante la ricerca è di restituire la posizione dell'oggetto rispetto al Baselato sinistro. Questo si converte in coordinate locali dello schermo in modo che il renderer stesso non debba preoccuparsi del modulo, ma solo la ricerca.

Non è necessario clonare nulla poiché ogni renderer si occupa solo dell'oggetto in una posizione.

Se il tuo mondo è prodotto in segmenti o utilizzando strutture 3D, dovrai segmentarlo. Quindi non è un blocco consecutivo, ma può essere spostato per soddisfare questo rendering. Non hai bisogno di molti blocchi, almeno 2.


1

Penso che l'unico approccio ragionevole sarebbe quello di implementare il tuo mondo avvolto in una struttura di dati sottostante completamente trasparente per il gioco e l'utente. Quindi su alcuni Low Level hai una funzione mapCoordinate () che avvolge le tue coordinate effettive sulla tua risorsa-mappa sottostante ...

Quindi, se il tuo mondo reale è largo solo 10 unità, il giocatore e il gioco non lo sapranno. Per il giocatore il mondo è infinito - e se il gioco chiede cosa si trova in posizione 15 - la funzione sottostante tradurrà questa richiesta, modulo10 e darà a pacchetto l'oggetto in posizione 5.

Quindi per l'intera logica di gioco e tutto il resto è come se avessi un grande mondo infinito, dove ci sono solo copie di tutto.


1

Non è esattamente lo stesso, ma ho implementato qualcosa di simile in una jam di gioco. Il gioco prevedeva che i giocatori si muovessero su un piccolo livello circolare, avvolto quando il giocatore raggiungeva una posizione "x" di pi. Il rendering è stato facile perché abbiamo appena eseguito il rendering di tutto e quindi abbiamo ruotato una telecamera offset per tenere traccia di ciò che stava accadendo. Potresti implementare qualcosa di simile, come è stato suggerito sopra:

  • Durante il disegno, controllare la posizione della fotocamera e determinare cosa deve essere disegnato, tenendo conto della posizione della fotocamera e del suo raggio di visione.
  • Nei casi in cui la telecamera vede oltre il 'bordo' della mappa, seleziona una quantità appropriata di contenuto dall'altra parte del mondo per disegnare su quel bordo, di solito semplicemente aggiungendo o sottraendo la larghezza del livello alla loro posizione.
  • La logica di gioco deve essere consapevole di questa cucitura e adattarsi come indicato in altre risposte. Casi particolari di cui tenere conto sono le collisioni in cui un oggetto si trova su un lato, ma si scontra con un oggetto sull'altro lato.
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.