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:
- Sprite(unsigned int screen, unsigned int background, unsigned int size, int x, int y, int width, int height);
-
- 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);
-
- void SetWidth(int width);
- void SetHeight(int height);
- void SetWidthHeight(int width, int height);
-
- int GetWidth();
- int GetHeight();
-
- bool InSprite(int x, int y);
Sprite(unsigned int screen, unsigned int background, unsigned int size, int x, int y, int width, int height);
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);
void SetWidth(int width);
void SetHeight(int height);
void SetWidthHeight(int width, int height);
int GetWidth();
int GetHeight();
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:
- bool Sprite::InSprite(int x, int y) {
- return (x >= m_x && x <= m_x + m_width && y >= m_y && y <= m_y + m_height);
- }
bool Sprite::InSprite(int x, int y) {
return (x >= m_x && x <= m_x + m_width && y >= m_y && y <= m_y + m_height);
}
- No está fino del todo, pero ya lo iremos mejorando.
No está fino del todo, pero ya lo iremos mejorando.
También hemos codificado el destructor de la clase:
- Sprite::~Sprite() {
- PA_StopSpriteAnim(m_screen, m_index_sprite);
- PA_DeleteSprite(m_screen, m_index_sprite);
-
- }
Sprite::~Sprite() {
PA_StopSpriteAnim(m_screen, m_index_sprite);
PA_DeleteSprite(m_screen, m_index_sprite);
}
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:
- 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);
-
- 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);
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);
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:
- int ScreenManager::GetBackgroundSpriteIndex(int x, int y) {
- unsigned int i;
- for (i = 0; i < m_backgroundSprites->size(); i++) {
- Sprite *sprite = m_backgroundSprites->at(i);
- if (sprite->InSprite(x, y)) return i;
- }
- return -1;
- }
-
- Sprite *ScreenManager::GetBackgroundSprite(unsigned int i) {
- return m_backgroundSprites->at(i);
- }
-
- void ScreenManager::EraseBackgroundSprite(unsigned int i) {
- Sprite *sprite = m_backgroundSprites->at(i);
- delete sprite;
- m_backgroundSprites->erase(m_backgroundSprites->begin() + i);
- }
int ScreenManager::GetBackgroundSpriteIndex(int x, int y) {
unsigned int i;
for (i = 0; i < m_backgroundSprites->size(); i++) {
Sprite *sprite = m_backgroundSprites->at(i);
if (sprite->InSprite(x, y)) return i;
}
return -1;
}
Sprite *ScreenManager::GetBackgroundSprite(unsigned int i) {
return m_backgroundSprites->at(i);
}
void ScreenManager::EraseBackgroundSprite(unsigned int i) {
Sprite *sprite = m_backgroundSprites->at(i);
delete sprite;
m_backgroundSprites->erase(m_backgroundSprites->begin() + i);
}
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:
- int i = topScreen->GetBackgroundSpriteIndex(mario->GetX() + 8, mario->GetY() + 8);
- if (i > -1) {
- topScreen->EraseBackgroundSprite(i);
- puntuacion_monedas++;
- PA_OutputText(SCREEN_BOTTOM, 1, 1, "monedas = %d ", puntuacion_monedas);
- }
int i = topScreen->GetBackgroundSpriteIndex(mario->GetX() + 8, mario->GetY() + 8);
if (i > -1) { //hemos pillado moneda
topScreen->EraseBackgroundSprite(i);
puntuacion_monedas++;
PA_OutputText(SCREEN_BOTTOM, 1, 1, "monedas = %d ", puntuacion_monedas); // para debugear
}
El código lo podéis encontrar en esta
dirección.
Esto es todo por ahora.
Saludos
1 comentario:
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
Publicar un comentario