2009-07-15 8 views
19

Ho letto sul rilevamento delle collisioni nei giochi su StackOverflow e altri siti. Molti di loro parlano di BSP, elipsing di delimitazione, integrazione ecc. Tuttavia, sul NES, sono riusciti a eseguire il rilevamento di collisioni di pavimenti e pareti nei giochi e trovo difficile credere che abbiano fatto molti calcoli per rilevare le collisioni tra mura.Come hanno fatto i vecchi giochi il rilevamento delle collisioni con muri, pavimenti e soffitti?

Credo che la mia domanda sia, dato un livello composto da solo tessere, come hanno rilevato collisioni con muri e pavimenti in giochi come Mario e Megaman che avevano poca potenza di elaborazione?

  • Hanno seguito il percorso di movimento e determinato la tessera di connessione più vicina? (un po 'di ricerca) (priori)
  • Hanno determinato una collisione con il pavimento e poi hanno trovato il modo migliore per regolare il personaggio? (a posteriori) Questo è rischioso con timestep variabile, potresti saltare da una tessera se eri abbastanza veloce. Anche se presumo che i timestep dei giochi NES siano stati sincronizzati con la frequenza di aggiornamento della tv.
  • La gravità influisce sempre sul tuo personaggio quando sei a terra? O semplicemente "spegni" quando sei determinato a camminare su una tessera? E quando uscirai da una scogliera? Avresti bisogno di un qualche modo per determinare le piastrelle sotto di te altrimenti.
  • Se vi siete scontrati con una tessera, troverete il bordo di quella tessera e spostate il vostro personaggio sul lato di essa (a seconda della direzione di marcia)?
  • che dire di piastrelle in pendenza come in super metroid e mario?
  • Che dire di "piattaforme" in cui è possibile saltare attraverso il fondo e atterrare in cima. Come gestiresti le collisioni con queste tessere se lo facessi a posteriori?

Ho scritto un codice di collisione che è fondamentalmente 'priori' mentre cerca la prima tessera che verrà colpita in una certa direzione. Mi sto solo chiedendo se c'è un modo migliore. (Usando solo rilevamento delle collisioni dopo-il-fatto invece forse)

esempio, il codice per verificare le collisioni piastrelle per spostare verso il basso (posso controllare vert quindi movimento orizzontale):

def tile_search_down(self, char, level): 
     y_off = char.vert_speed 
     assert y_off > 0 

     # t_ are tile coordintes 
     # must be int.. since we're adding to it. 
     t_upper_edge_y = int(math.ceil((char.y+char.h)/self.tile_height)) #lowest edge 
     while (t_upper_edge_y*self.tile_height) < (char.y+char.h+y_off): # lowest edge + offset 

      t_upper_edge_x = int(math.floor(char.x/self.tile_width)) 
      while (t_upper_edge_x*self.tile_width) < (char.x+char.w): 

       t_x = t_upper_edge_x 
       t_y = t_upper_edge_y 
       if self.is_tile_top_solid(t_x, t_y, plane): 
        char.y = t_y*self.tile_height - char.h 
        char.vert_speed = 0.0 
        char.on_ground = True 
        return 

       t_upper_edge_x += 1 
      t_upper_edge_y += 1 

     char.y += y_off 

risposta

17

Per i tipi di NES- i giochi dell'epoca di cui parli, tutto era in 2D. Questo da solo semplifica molte cose.

Alcune macchine di quell'epoca (in particolare quelle con sprite hardware, come Commodore 64) avevano rilevamento di collisione hardware. La maggior parte dei giochi che non facevano affidamento sul rilevamento delle collisioni hardware utilizzava un riquadro di delimitazione o una maschera di successo (bitmap a 1 bit dello sprite).

In entrambi i casi, il rilevamento delle collisioni veniva solitamente eseguito "a posteriori", ad eccezione di casi speciali come i bordi del mondo. Alcuni giochi in realtà hanno bug in cui muoversi troppo velocemente quando colpisci qualcosa potrebbe farti passare attraverso di esso. (In effetti, le revisioni dei primi giochi degli anni 80 spesso commentavano quanto preciso fosse il rilevamento delle collisioni.)

Per i platform, in genere si controlla se il personaggio è "messo a terra" prima di applicare la gravità.

La piattaforma a una via non è troppo difficile da gestire dopo il fatto dato che si conosce il vettore di velocità dello sprite, quindi è possibile utilizzarlo per determinare se la collisione debba o meno essere registrata.

12

Per giochi come Super Mario World (SNES), il gioco memorizzava i livelli in un formato di memoria che rendeva facile prendere la posizione X/Y di Mario, convertirlo in un indirizzo di tessera e quindi controllare le tessere immediatamente intorno quell'indirizzo Poiché i livelli erano sempre di una larghezza fissa (sebbene l'area che si poteva vedere variata), rendeva l'indirizzamento più facile da gestire poiché era sempre un offset fisso dalla posizione di mario, ad es. Indirizzo + 1 per il riquadro accanto a mario, Indirizzo + 0x300 per il riquadro sottostante, ecc.

+0

Vorrei sottolineare che dopo aver trovato la piastrella, Mario World usata una tabella di ricerca di funzioni per gestire le collisioni di piastrelle, il che significava che ogni piastrella eseguito solo il codice che ha voluto eseguire. – Sukasa

12

C'è un articolo che è un approfondimento sulla programmazione di un "gioco di piattaforma" Nintendo Entertainment System (NES).

io non sono stato googling giusto perché non ho inciampato su questo articolo prima.

Problemi correlati