viernes, 11 de diciembre de 2009

Cogiendo las monedas

Por fin, Mario puede coger sus monedas y ya empieza esto a parecerse más al New Super Mario Bross de la Nintendo DS.

Está quedando chulo, parece algo:



Se ha tenido que cambiar alguna cosilla de las librerías, pero nada demasiado raro.

Para coger las monedas lo primero es saber donde están y cuanto abultan. Es por esto que se ha tenido que introducir las variables width y height dentro de la clase Sprite. De paso hemos aprovechado para limpiar un poco los constructores y dejarlo todo más fino.

Dentro de la clase Sprite se han modificado e introducido las siguientes funciones:

  1. Sprite(unsigned int screen, unsigned int background, unsigned int size, int x, int y, int width, int height);  
  2.   
  3. Sprite(unsigned int screen, unsigned int background, unsigned int shape, unsigned int size, void *palette, void *sprite, int x, int y, int width, int height, int hflip);  
  4.   
  5. void SetWidth(int width);  
  6. void SetHeight(int height);  
  7. void SetWidthHeight(int width, int height);  
  8.   
  9. int GetWidth();  
  10. int GetHeight();  
  11.   
  12. bool InSprite(int x, int y);  

Esta última función, InSprite mira que el punto x,y esté dentro del Sprite. En nuestro caso será dentro de la moneda y se ha codificado de la siguiente manera:

  1. bool Sprite::InSprite(int x, int y) {  
  2. return (x >= m_x && x <= m_x + m_width && y >= m_y && y <= m_y + m_height);  
  3. }  

  1. No está fino del todo, pero ya lo iremos mejorando.  
También hemos codificado el destructor de la clase:

  1. Sprite::~Sprite() {  
  2. PA_StopSpriteAnim(m_screen, m_index_sprite);  
  3. PA_DeleteSprite(m_screen, m_index_sprite);  
  4.   
  5. }  

De esta forma al coger la moneda destruimos el sprite. Ahora la clase ScreenManager. En las funciones para crear Sprites y sprites de fondo se ha introducido el width y el height:
  1. Sprite *CreateSprite(unsigned int background, unsigned int shape, unsigned int sizes, void *palette, void *sprite, int x, int y, int width, int height, int hflip = 0);  
  2.   
  3. Sprite *CreateBackgroundSprite(unsigned int background, unsigned int shape, unsigned int sizes, void *palette, void *sprite, int x, int y, int width, int height, int hflip = 0);  
Y hemos introducido más funciones para trabajar con los Sprites de fondo:
  1. int ScreenManager::GetBackgroundSpriteIndex(int x, int y) {  
  2. unsigned int i;  
  3. for (i = 0; i < m_backgroundSprites->size(); i++) {  
  4. Sprite *sprite = m_backgroundSprites->at(i);  
  5. if (sprite->InSprite(x, y)) return i;  
  6. }  
  7. return -1;  
  8. }  
  9.   
  10. Sprite *ScreenManager::GetBackgroundSprite(unsigned int i) {  
  11. return m_backgroundSprites->at(i);  
  12. }  
  13.   
  14. void ScreenManager::EraseBackgroundSprite(unsigned int i) {  
  15. Sprite *sprite = m_backgroundSprites->at(i);  
  16. delete sprite;  
  17. m_backgroundSprites->erase(m_backgroundSprites->begin() + i);  
  18. }  
La primera obtiene el índice de un Sprite de fondo a partir de unas coordenadas. Devolverá el primer sprite de fondo que contenga esas coordenadas. La segunda devuelve el Sprite de fondo a partir de un índice. La tercera borra un Sprite de fondo a partir de un índice. Esta última destruye el Sprite. En cuanto a código PAlib hemos usado por primera vez, creo, la función que sirve para borrar un Sprite: PA_DeleteSprite(m_screen, m_index_sprite); Se le pasa la pantalla donde está el sprite asignado y el indice que se le asoció al crearlo (no confundir con el índice de los Sprites de fondo). Para adaptar todas estas nuevas funciones a nuestro propósito, que es coger monedas al pasar sobre ellas, he introducido las siguientes líneas al final de la función BeforeVBL de la clase NSMB.cpp:
  1. int i = topScreen->GetBackgroundSpriteIndex(mario->GetX() + 8, mario->GetY() + 8);  
  2. if (i > -1) { //hemos pillado moneda  
  3. topScreen->EraseBackgroundSprite(i);  
  4. puntuacion_monedas++;  
  5. PA_OutputText(SCREEN_BOTTOM, 1, 1, "monedas = %d      ", puntuacion_monedas); // para debugear  
  6. }  

El código lo podéis encontrar en esta dirección.

Esto es todo por ahora.

Saludos

1 comentario:

Unknown dijo...

compile tu codigo y me marca errores despues de darle el make y segui tu manual de ocmo instalarlo en ubuntu kisiera saber si lo hice bien