Come gestire le differenze tra le coordinate dello schermo 2D e le coordinate cartesiane


23
  • La maggior parte dei sistemi di coordinate 2D schermo / bitmap ha l'asse Y positivo rivolto verso il basso (con l'origine nell'angolo in alto a sinistra).
  • Questo è in contrasto con il modo in cui la maggior parte delle persone pensa geometricamente con l'asse Y positivo rivolto verso l'alto (con l'origine al centro).

In che modo la maggior parte dei giochi gestisce i due diversi sistemi di coordinate 2D? Esistono due tipi principali di coordinate (schermo vs cartesiano), ma potrebbero esserci molti spazi di coordinate diversi: spazio sprite, spazio mondo, spazio vista, spazio schermo, ecc ...

Sfondo:

Inizialmente ho fatto in modo che le coordinate del mondo nel mio gioco corrispondessero alla convenzione delle coordinate dello schermo 2D. Ciò ha reso molto naturale l'utilizzo delle routine di disegno grafico, ma si sono verificati problemi sottili quando si utilizzano funzioni trigonometriche come atan2 (). I risultati dell'alimentazione delle coordinate dello schermo 2D atan2 () sono molto confusi perché atan2 () assume che l'asse y positivo sia rivolto verso l'alto.

Quindi ho cambiato le mie coordinate del mondo per seguire il classico sistema di coordinate cartesiane (con l'origine nella parte inferiore sinistra dello schermo). Il ragionamento con atan2 () è molto più diretto, ma ora è più difficile fare altri tipi di ragionamento:

  • Se clicco sullo schermo qui, quale sprite è sotto?
  • Dove ho cliccato su quello sprite?
  • Se uno sprite viene disegnato nella posizione sbagliata, cosa è stato calcolato in modo errato? Le coordinate dello schermo o le coordinate del mondo?

Mi rendo conto che la conversione dallo schermo alle coordinate cartesiane implica semplicemente il ridimensionamento del valore y di -1 con una traduzione opzionale di entrambi i valori (x, y). Sono più interessato alle migliori pratiche per la progettazione di giochi:

  • La maggior parte dei giochi si attiene semplicemente alla convenzione delle coordinate dello schermo e cambia il loro pensiero su come dovrebbero funzionare cose come atan2 ()?
  • Quando / come vengono eseguite le conversioni del sistema di coordinate? (Uso di matrici, astrazione OOP, ecc.)
  • Le posizioni degli sprite sono memorizzate come il centro dello sprite o uno degli angoli? L'altezza / larghezza dello sprite che va nella direzione "sbagliata" sembra essere un problema comune quando le disegno.

Sebbene la mia domanda riguardi principalmente i giochi 2D, sembra che OpenGL usi un sistema di coordinate in cui l'asse Y punta verso l'alto. OpenGL deve eventualmente proiettare quelle coordinate 3D su un sistema di coordinate dello schermo 2D. Forse alcune indicazioni potrebbero essere trovate nel metodo OpenGL ...

Risposte:


8

Avendo provato ogni modo immaginabile di farlo, ho scoperto che è puramente un gioco 2D, basta usare il sistema di disegno dello schermo, renderà la tua vita molto più semplice. Sin, Cos e atan2 devono essere usati in modo leggermente diverso, ma questo inconveniente è facilmente compensato dalla semplicità di sapere in che direzione si trovano su, giù, in senso orario e antiorario. Consiglierei anche di lavorare in pixel anziché in metri per i giochi 2D: è molto più facile pensare alle distanze sullo schermo e le probabilità che tu voglia cambiare l'intera scala del tuo gioco sono vicine allo zero.

"In che modo la maggior parte dei giochi gestisce i due diversi sistemi di coordinate 2D?"

  • la maggior parte dei giochi 2D ho visto la fonte per utilizzare il sistema dello schermo, ma ogni entità dovrebbe conoscere il suo spazio mondiale, lascia che il tuo gestore di disegni lo converta in una posizione sullo schermo. A questo punto farai qualunque trasformazione di matrice ti serva.

"Le posizioni degli sprite sono memorizzate come il centro dello sprite o uno degli angoli?"

  • Se lavori dal centro rende la rotazione più semplice, anche se vorrai conoscere anche gli angoli.

"Forse alcune indicazioni potrebbero essere trovate nel metodo OpenGL ..."

  • I motori 3D sono un caso completamente diverso. Dato che hanno delle vere telecamere, la posizione dello schermo può essere molto diversa dalla posizione mondiale. Per un gioco dall'alto verso il basso dovresti lavorare sugli assi X e Z, anziché su X e Y per una cosa.

1

Potrei semplificare eccessivamente le cose qui, ma la mia inclinazione sarebbe quella di avere un sottosistema 2D / UI strettamente legato a quelle che hai soprannominato coordinate "schermo". Avresti due matrici: ScreenToCartesianTransform e CartesianToScreenTransform. Quando si ricevono eventi di input del mouse, le coordinate del mouse vengono trasformate utilizzando CartesianToScreenTransform prima di essere passate al gestore input del sistema 2D / UI. Da lì, il sistema UI eseguiva i test di successo utilizzando il sistema di coordinate dello schermo e gestiva (o non gestiva) l'evento di conseguenza. Se un evento di input del mouse non viene gestito dall'interfaccia 2D / UI, potrebbe essere passato al sistema 3D (se presente) utilizzando le coordinate originali, non trasformate.

Poiché il sistema 2D / UI si occuperebbe solo di coordinate "schermo", la sua geometria dovrebbe essere trasformata tramite ScreenToCartesianTransform prima di essere elaborata dal motore di rendering.


In realtà, a seconda del toolkit in uso, gli eventi di input del mouse potrebbero essere già nelle coordinate dello schermo. In tal caso, non li trasformeresti per il sistema 2D / UI, ma per il sistema 3D (se ne esiste uno).
Mike Strobel,

0

Preferisco usare un albero di visualizzazione come in Flash. Avrò un nodo radice (vista di gioco) che contiene un figlio per il mondo (nodo mondiale) e uno in cima per l'HUD. All'interno del nodo del mondo ci saranno i nodi per gli oggetti nel mondo di gioco.

Quindi trasformo semplicemente il nodo mondiale. Insieme alla traduzione (panoramica della videocamera) e al ridimensionamento proporzionale (zoom della videocamera) applico anche altre due trasformazioni:

  • Una scala di -1 y per invertire il sistema di coordinate.
  • Un ridimensionamento per convertire unità del mondo (metri) in unità dello schermo (pixel)

Quindi uso le coordinate y-up / world nel codice di disegno dell'oggetto di gioco e le coordinate y-down / screen nel codice di disegno HUD, che sembrano entrambe molto naturali.

Per rispondere a domande come "su quale oggetto sto facendo clic" utilizzo i metodi del nodo di visualizzazione per convertire le coordinate tra i sistemi di coordinate (come globalToLocale il suo inverso in Flash).

A proposito, atannon funziona in modo diverso quando y è abbassato, devi solo pensare a tutti gli angoli come andare in senso orario invece che in senso antiorario.


0

OpenGL, come DirectX, ha gli assi X e Z lungo il piano orizzontale e Y rivolto verso l'alto.
Non ho mai avuto problemi con le coordinate dello schermo e penso che il modo più semplice sarebbe semplicemente quello di trattarlo così com'è: se a qualcosa come atan2 non piace, allora cambia i parametri che vengono alimentati.

Se stai usando coordinate relative o locali, come un grafico di scena, allora una semplice funzione come ToGlobalCoords () è buona. In effetti, se vuoi saperne di più sul posizionamento spaziale, i grafici delle scene e localToGlobal, l'estratto gratuito di Game Engine Architecture è proprio questo.

Gli sprite sono disegnati dall'angolo in alto a sinistra o (0,0) l'origine. I motivi per cui sono a causa dell'origine in alto a sinistra della finestra.

Sembra un po 'sciocco cambiare il sistema di coordinate della finestra, e renderebbe le cose come l'input, che gioca un ruolo maggiore nella maggior parte dei giochi rispetto ai trigem, significativamente più difficile. Ti allontana anche dalla norma e da qualsiasi utente del tuo codice.

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.