oldcode – RallyNDS, Rally-X en tu NDS
Hace un tiempo atrás (en la epoca que desarrollar para Android o Iphone era impensable para un analista xD), hubo una gran euforia en el desarrollo de apps homebrew para Nintendo DS, gracias a la librería libnds (libre pero de desarrollo a bajo nivel) y sobre todo a Palib, está última, muy sencilla en base a funciones de alto nivel (nos abstrae mucho el uso de libnds).
A si fue, durante el 2009, con un poco de tiempo, trate de implementar un sencillo juego style Rally-X para Nintendo DS, utilizando la librería Palib (hoy en día sin mantenimiento desde Jul, 2010).
Palib, implementa una serie de funciones de muy fácil uso para trabajar con todo lo necesario en un juego, es decir, backgrounds, sprites, lógica, etc.
El desarrollo del juego es sencillo, en general, existe un auto que representa al usuario (centrado en la pantalla), mientras los otros son manejados por la cpu. Bajo este contexto, existe un gran diferencia entre el desplazamiento del auto usuario versus los autos cpu.
Ya que el auto del usuario siempre esta centrado en la pantalla , mientras el resto es lo que realmente se mueve (el fondo avanza, dando la sensación de que el auto del usuario avanza al igual como los autos de la cpu, por lo tanto hay que extrapolar la posición del resto (autos cpu) respecto al centro (auto usuario).
Sobre la detección de colisiones, he utilizado una de las capas que maneja Nintendo DS, para insertar una imagen que representa el mapa (en dos colores), de esta manera, podemos detectar si los vehículos han llegado a un tope del mapa.
El resto simplemente son png con sprites “tomados” de los juegos Pokemon xD.
Rally NDS … solo un demo en palib – libnds
Source Code
main.cpp
#include <PA9.h> #define ATTR0_DISABLED (2<<8) #define SCREEN_TOP 1 #define SCREEN_BOTTOM 0 #define BACKGROUND_ZERO 0 #define BACKGROUND_ONE 1 #define BACKGROUND_TWO 2 #define BACKGROUND_THREE 3 #define COLOR_MODE_256 1 /* #define BACKGROUND_X 120 #define BACKGROUND_Y -88 */ int BACKGROUND_X = 120; int BACKGROUND_Y = -88; #define MAP_MW 736 #define MAP_MH 672 #define CAR_PALLETE 0 #define CAR_SPRITE 0 #define CAR_REFLEJO_SPRITE 1 #define MAX_COMPUTER 7 #define MAX_PLAYERS 9 #define MAX_ITEM 64 #define MAX_ITEM_STARS 32 int CAR_X = 241; int CAR_Y = 0; /* #define CAR_X 241 #define CAR_Y 0 */ #define CAR_CENTER_X 120 #define CAR_CENTER_Y 88 /* #define CARCPU_X 241 #define CARCPU_Y 0 */ int CARCPU_X = 241; int CARCPU_Y = 0; #define CARCPU_CENTER_X 120 #define CARCPU_CENTER_Y 88 #define CAR_VELOCIDAD 5 #define ANIMACION_PAUSA 0 #define ANIMACION_ABAJO 1 #define ANIMACION_ARRIBA 2 #define ANIMACION_IZQUIERDA 3 #define ANIMACION_DERECHA 4 #define ESPACIO_LIBRE 0 #define DEBUGMODE 1 #include "rallye.h" #include "gfx/all_gfx.h" #include "gfx/all_gfx.c" #include "dev/devRallyN.cpp" //u8 obtenerBaldosa(s32 x, s32 y); //void cargarPortadas(); int main(int argc, char ** argv) { PA_Init(); PA_InitVBL(); PA_InitSound(); /* PA_InitWifi(); PA_ConnectWifiWFC(); */ /* PA_InitText(0, 3); PA_InitText(1, 0); */ PA_InitCustomText(0, //screen 3, //background number font); //font name PA_InitCustomText(1, //screen 1, //background number font); //font name Game *mygame = new Game(); // Load Presentation mygame->loadPresentation(); // Show Principal Menu mygame->loadMainMenu(); // Iniciamos el Juego mygame->runGame(); while( 1 == 1) { PA_WaitForVBL(); } PA_WaitForVBL(); return 0; }
devRallyN.h
// 0-31 // 0-23 int playerLocalX = 0; int playerLocalY = 0; int nplayerGlobal = 0; char buffer[256]; char debugGame[23][31]; int pdebugGame = 0; int fps = 0; int time = 0; void addStringDebug( char str[] ) { if ( pdebugGame == 22 ) pdebugGame = 0; strcpy(debugGame[pdebugGame],str); pdebugGame++; } // Function debugin xD void sleep() { while(1 == 1) { } } // Funciones Globales int getId() { static int icount = 0; icount++; if ( icount == 127 ) icount = 1; return ( icount-1 ); } int getNumberSprite() { static int scount = 0; scount++; if ( scount == 127 ) scount = 1; return ( scount-1 ); } int getNumberPallete() { static int pcount = 0; pcount++; if ( pcount == 15 ) pcount = 1; return ( pcount-1 ); } int getNumberPlayer() { static int npcount = 0; npcount++; return ( npcount -1 ); } int getNumberItem() { static int nicount = 0; nicount++; return ( nicount -1 ); } struct infplayer { int x; int y; int score; int life; }; infplayer infoPlayer[MAX_PLAYERS]; class itemMaps { private: int type,enabled,x,y; public: int id; int pallete; int nsprite; void setType( int gType ); void setEnabled( int gEnabled ); void setX( int gX ); void setY( int gY ); void renderer(); int getPallete(); int getType(); int getEnabled(); int getX(); int getY(); itemMaps(); }; class pointCar { private: int x,y; public: pointCar(); void setX( int gX ); void setY( int gY ); int getX(); int getY(); }; class MapWorld { private: int run,num; public: int arrPointCar[MAX_PLAYERS][2]; pointCar *myPointCar[MAX_PLAYERS]; //itemMaps *myItem[32]; //itemMaps *myItem[32]; itemMaps *myItem; MapWorld(); void setMap( int gNum ); void loadMap(); // In the map bool isAvailable( int *px , int *py , int *pncar , int *life , int *score ); // Collision Map bool thereAreCarCollision( int *x , int *y , int *ncar , int *life , int *score ); void positionRandom(int &gX , int &gY); void setPlayerPosition(int np , int mX , int mY); int getXPlayerPosition(int np ); int getYPlayerPosition(int np ); void renderer(); }; class Car { private: // x,y map // sx,sy screen int x, y , sx ,sy , a , v, ang, cf1, cf2, csp, lcf1, lcf2; void* pallete; void* sprite; public: int vel; int *score; int *life; int nplayer; int car_sprite; int car_pallete; MapWorld* mymap; Car(); void setSx( int sX ); void setSy( int sY ); int getSx(); int getSy(); void setX(int gX ); void setY(int gY ); void setAng( int gAng ); void setRandomAng(); int getX(); int getY(); int getAng(); void runCar(); void setPallete( void* p ); void setSprite( void* s); void createCar(); }; class Player { private: int idplayer; bool connect; public: int score; int life; int nplayer; char name[64]; MapWorld* mymap; // Constructor Car* myCar; Player(); void setMyCar( void* pal , void* spr , int mX , int mY , int sX , int sY ); void setName( char gName[] ); }; class PlayerLocal : public Player { public: // Constructor PlayerLocal(); void play(); void renderer(); }; class PlayerComputer : public Player { public: // Constructor PlayerComputer(); void play(); void renderer(); }; class Game { private: int loop; // Local PlayerLocal* player; // Computer PlayerComputer* playercpu; // String public: // Constructor MapWorld* mymap; Game(); void loadPresentation(); void runGame(); void showDebug(); void loadMainMenu(); void renderScore( char gName[] , int pos , int score , int life ); };
devRallyN.cpp
#include "devRallyN.h" void* getSpriteCar( int c ) { if ( c == 1 ) return (void*)car1_Sprite; else if ( c == 2 ) return (void*)car2_Sprite; else if ( c == 3 ) return (void*)car3_Sprite; else if ( c == 4 ) return (void*)car3_Sprite; else return (void*)car1_Sprite; } void* getPalleteCar( int c ) { if ( c == 1 ) return (void*)car1_Pal; else if ( c == 2 ) return (void*)car2_Pal; else if ( c == 3 ) return (void*)car3_Pal; else if ( c == 4 ) return (void*)car4_Pal; else return (void*)car1_Pal; } // PointCar pointCar::pointCar() { this->x = -1; this->y = -1; } void pointCar::setX( int gX ) { this->x = gX; } void pointCar::setY( int gY ) { this->y = gY; } int pointCar::getX() { return this->x; } int pointCar::getY() { return this->y; } // itemMaps itemMaps::itemMaps() { this->y = -1; this->x = -1; this->type = -1; this->enabled = -1; this->pallete = this->getPallete(); this->nsprite = -1; this->id = getNumberItem(); }; void itemMaps::setX(int gX){ this->x = gX; } void itemMaps::setY(int gY){ this->y = gY; } int itemMaps::getY(){ return this->y ; } int itemMaps::getX(){ return this->x ; } void itemMaps::setType( int gType ){ this->type = gType; }; void itemMaps::setEnabled( int gEnabled ){ this->enabled = gEnabled; }; int itemMaps::getType(){ return this->type; }; int itemMaps::getEnabled(){ return this->enabled; }; int itemMaps::getPallete() { static int pallete = 0; if ( pallete == 0 ) pallete = getNumberSprite(); return pallete; } void itemMaps::renderer() { int xl,yl; if ( this->nsprite == -1 ) this->nsprite = getNumberSprite(); this->y = this->y * (-1); /* char out[32] = " "; sprintf(out,"START(%03d,%03d)xy", x , y ); addStringDebug(out); */ // ¿ Esta en el espacio visual del player local ? if ( playerLocalX -128 <= this->x && playerLocalX +128 >= this->x /*&& (playerLocalY*(-1)) - 95 <= this->y && (playerLocalY*(-1)) + 95 >= this->y*/ ) { // Mostramos el Sprite PA_obj[SCREEN_TOP][this->nsprite].atr0 &= ~(2<<8); // Calculamos el punto de referencia xl = this->x - ( playerLocalX - 128 ); yl = this->y - ( playerLocalY*-1 - 95 ); // Fixme // Fixme PA_SetSpriteXY(SCREEN_TOP,this->nsprite , xl -9 , yl -4 ); } else { // Deberiamos ocultar al Sprite PA_obj[SCREEN_TOP][this->nsprite ].atr0 |= (2<<8); } } // MapWorld MapWorld::MapWorld() { run = 1; for(int i = 0 ; i < MAX_PLAYERS ; i++) { this->setPlayerPosition(i,-1,-1); this->myPointCar[i] = new pointCar(); } // Pedimos memorias y instanciamos myItem = new itemMaps[32]; char out[32] = " "; for(int i=0; i < 32 ; i++) { sprintf(out,"SI(%02d)id", (myItem+i)->id ); addStringDebug(out); } /* myItem = new itemMaps[32]; //this->myItem = new itemMaps[32]; // Cada Mapa tiene 32 Banderitas for(int i=0; i < 32 ; i++) { //this->(myItem+i) = new itemMaps(); (myItem+i)->setType(0); (myItem+i)->setX(100); (myItem+i)->setY(100); } */ } void MapWorld::renderer() { // Renderizo las Banditas /* for(int i=0; i < 32 ; i++) { (myItem+i)->renderer(); PA_OutputText(SCREEN_BOTTOM, 1, i, "%d,%d", (myItem+i)->id , (myItem+i)->id ); } sleep(); */ char out[32] = " "; //for(int i=0; i < 10 ; i++) //{ sprintf(out,"SI(%02d)id", (myItem+1)->id ); addStringDebug(out); //} } void MapWorld::setMap( int gNum ) { num = gNum; } void MapWorld::loadMap() { if ( num == 1 ) { PA_EasyBgLoad(SCREEN_TOP, BACKGROUND_THREE, map1Col); PA_EasyBgLoad(SCREEN_TOP, BACKGROUND_TWO, map1Med); //PA_EasyBgLoad(SCREEN_TOP, BACKGROUND_ONE, map1Top); PA_PlayMod(rallye); } } void MapWorld::setPlayerPosition(int np , int mX , int mY) { char out[32] = " "; /* if ( np == 0 ) { sprintf(out,"SET(%02d,%03d,%03d)np,x,y",np,mX,mY); addStringDebug(out); } */ /* if ( np >= 0 && np < MAX_PLAYERS ) { this->myPointCar[np]->setX(mX); this->myPointCar[np]->setY(mY); } */ if ( np >= 0 && np < MAX_PLAYERS ) { this->arrPointCar[np][0] = mX; this->arrPointCar[np][1] = mY; } /* if ( np == 0 ) { sprintf(out,"GET(%02d,%03d,%03d)np,x,y",np,this->arrPointCar[np][0],this->arrPointCar[np][1]); addStringDebug(out); } */ } int MapWorld::getXPlayerPosition( int np ) { if ( np >= 0 && np < MAX_PLAYERS ) { //return this->myPointCar[np]->getX(); return this->arrPointCar[np][0]; } else return -1; //return this->arrPointCar[np][0]; } int MapWorld::getYPlayerPosition(int np ) { if ( np >= 0 && np < MAX_PLAYERS ) { //return this->myPointCar[np]->getY(); return this->arrPointCar[np][1]; } else return -1; //return this->arrPointCar[np][1]; } void MapWorld::positionRandom(int &gX , int &gY) { int xl = PA_RandMinMax(1,MAP_MW); int yl = PA_RandMinMax(1,MAP_MH); while( !isAvailable(&xl,&yl,NULL,NULL,NULL) && !( xl == 0 || yl ==0 ) ) { xl = PA_RandMinMax(1,MAP_MW); yl = PA_RandMinMax(1,MAP_MH); } gX = xl; gY = yl; } bool MapWorld::thereAreCarCollision(int *x , int *y , int *ncar , int *life , int *score) { bool myreturn = true; if ( ncar == NULL && life == NULL && score == NULL ) return true; if ( *y < 0 ) *y = *y *-1; if ( *ncar == -1 ) return true; // Vamos a Recorrer infoPlayer de 0 a MAX_PLAYERS for(int i = 0 ; i < MAX_PLAYERS ; i++ ) { if ( i != *ncar ) { if ( *x >= infoPlayer[i].x && *x <= (infoPlayer[i].x+16) && *y >= (infoPlayer[i].y*-1) && *y <= ((infoPlayer[i].y*-1)+16) ) { (*life)--; myreturn = false; } if ( infoPlayer[i].x >= *x && (infoPlayer[i].x+16) <= *x && (infoPlayer[i].y*-1) >= *y && ((infoPlayer[i].y*-1)+16) <= *y ) { (*life)--; myreturn = false; } } } return myreturn; } bool MapWorld::isAvailable(int *px , int *py , int *pncar , int *life , int *score ) { // 0 Disponible // 1 Ocupado int x = *px; int y = *py; int ncar = *pncar; y = y * (-1); if ( y < 0 ) y = y*(-1); if ( y == 0) return false; if ( ( PA_EasyBgGetPixel(SCREEN_TOP,BACKGROUND_THREE,x, y) == 0 ) && ( PA_EasyBgGetPixel(SCREEN_TOP,BACKGROUND_THREE,x+8, y) == 0 ) && ( PA_EasyBgGetPixel(SCREEN_TOP,BACKGROUND_THREE,x, y+8) == 0 ) && ( PA_EasyBgGetPixel(SCREEN_TOP,BACKGROUND_THREE,x+8, y+8) == 0 ) && thereAreCarCollision(&x,&y,&ncar , life , score) ) { return true; } else { return false; } } // Car Car::Car() { x = 0; y = 0; a = 0; v = 0; sx = 0; sy = 0; ang = 270; // 0.5px/s vel = 60; //vel = 0; cf1 = 0; cf2 = 1; csp = 6; lcf1=255; lcf2=255; car_pallete = getNumberPallete(); car_sprite = getNumberSprite(); //mymap = new MapWorld(); } void Car::setRandomAng() { int n = PA_RandMinMax(0,3); if ( n == 0 ) { setAng(0); } else if( n == 1 ) { setAng(90); } else if( n == 2 ) { setAng(270); } else if( n == 3 ) { setAng(180); } } void Car::setAng( int gAng ) { ang = gAng; } int Car::getAng() { return ang; } void Car::runCar() { // En teoria runCar debe ejecutarse a 30fps int yt=0; int xt=0; /* char out[32] = " "; sprintf(out,"(%d,%d,%d,%d)",x,y,sx,sy); addStringDebug(out); */ if ( DEBUGMODE == 1 ) { PA_OutputText(SCREEN_BOTTOM, 20, 21, "ang:%d ", ang); PA_OutputText(SCREEN_BOTTOM, 20, 22, "vel:%d ", vel); } /* Cada Car ocupa una dimensión de 16x16 px */ /* if ( fps%30 == 0 ) { char out[32] = " "; sprintf(out,"CAR - (%03d,%03d)xy ang:%d vel:%d ",x,y,ang,vel); addStringDebug(out); } */ if ( ang == 90 ) { yt = y + ( vel / 30 ); if ( mymap->isAvailable(&x,&yt,&nplayer,this->life,this->score) ) { y = yt; //PA_StartSpriteAnim(SCREEN_TOP, car_sprite, 3, 4, 10); cf1=3;cf2=4; } else { // Giro //ang = 180; setRandomAng(); } } if ( ang == 180 ) { xt = x - ( vel / 30 ); if ( mymap->isAvailable(&xt,&y,&nplayer,this->life,this->score) ) { x = xt; //PA_StartSpriteAnim(SCREEN_TOP, car_sprite, 7, 8, 10 ); cf1=7;cf2=8; PA_SetSpriteHflip(SCREEN_TOP, car_sprite, 1); } else { //ang = 270; setRandomAng(); } } if ( ang == 270 ) { yt = y - ( vel / 30 ); if ( mymap->isAvailable(&x,&yt,&nplayer,this->life,this->score) ) { y = yt; cf1=0;cf2=1; //PA_StartSpriteAnim(SCREEN_TOP, car_sprite, 0, 1, 10 ); } else { //ang = 0; setRandomAng(); } } if ( ang == 0 ) { xt = x + ( vel / 30 ); if ( mymap->isAvailable(&xt,&y,&nplayer,this->life,this->score) ) { x = xt; //PA_StartSpriteAnim(SCREEN_TOP, car_sprite, 7, 8, 10 ); cf1=7;cf2=8; PA_SetSpriteHflip(SCREEN_TOP, car_sprite, 0); } else { //ang = 90; setRandomAng(); } } if ( cf1 != lcf1 && cf2 != lcf2 ) { PA_StartSpriteAnim(SCREEN_TOP, car_sprite, cf1, cf2, csp); lcf1=cf1; lcf2=cf2; } //this->mymap->setPlayerPosition(nplayer,this->x,this->y); if ( nplayer > 0 && nplayer < MAX_PLAYERS ) { infoPlayer[nplayer].x = x; infoPlayer[nplayer].y = y; } } void Car::setX( int gX ) { x = gX; } void Car::setY( int gY ) { y = gY; } void Car::setSx( int sX ) { sx = sX; } void Car::setSy( int sY ) { sy = sY; } int Car::getSy() { return sy; } int Car::getSx() { return sx; } int Car::getY() { return y; } int Car::getX() { return x; } void Car::setPallete( void* p ) { pallete = p; } void Car::setSprite( void* s ) { sprite = s; } void Car::createCar() { // Cargamos y Creamos Sprite PA_LoadSpritePal(SCREEN_TOP, car_pallete,pallete); PA_CreateSprite(SCREEN_TOP, car_sprite, sprite, OBJ_SIZE_16X32, COLOR_MODE_256, car_pallete, sx, sy); } // Game Game::Game(){} void Game::showDebug() { /* char url[512] = " "; */ for(int i=0; i <= pdebugGame ; i++) { PA_OutputText(SCREEN_BOTTOM, 0, i+3, "%02d-%s", i , debugGame[i] ); /* sprintf(url,"http://deerme.piloto.cl/rand.php?s=%s",debugGame[i]); PA_GetHTTP(buffer, url); */ } } void Game::loadPresentation() { // Developer deerme PA_EasyBgLoad(SCREEN_TOP, BACKGROUND_ZERO, gameP0); // GPL Lic PA_EasyBgLoad(SCREEN_BOTTOM, BACKGROUND_ZERO, gameP3); int lfps = 0; while( lfps < 120 ) { if ( lfps < 30 ) { if ( lfps%2 ) PA_SetScreenLight(SCREEN_TOP, 1); else PA_SetScreenLight(SCREEN_TOP, 0); } PA_WaitForVBL(); lfps++; } PA_SetScreenLight(SCREEN_TOP, 1); PA_EasyBgLoad(SCREEN_TOP, BACKGROUND_ZERO, gameP1); // Mientras haga Click bool click = false; while (!click) { click = Stylus.Held; PA_WaitForVBL(); } int i = 0; for (i = 0; i < 64; i++) { PA_SetBrightness(SCREEN_TOP, -i); PA_SetBrightness(SCREEN_BOTTOM, -i); PA_WaitForVBL(); } PA_DeleteBg(SCREEN_BOTTOM, BACKGROUND_ZERO); PA_DeleteBg(SCREEN_TOP, BACKGROUND_ZERO); PA_SetBrightness(SCREEN_TOP, 0); PA_SetBrightness(SCREEN_BOTTOM, 0); /* if ( DEBUGMODE != 1 ) PA_EasyBgLoad(SCREEN_BOTTOM, BACKGROUND_ZERO, gameP1); */ return; } void Game::loadMainMenu() { // Load Fondo menu PA_EasyBgLoad(SCREEN_BOTTOM, 3, gameP6); // Init Text PA_InitCustomText(SCREEN_BOTTOM, 0, font); // Iniciamos Menu char menu[2][16]; sprintf(menu[0],"ARCADE \n"); sprintf(menu[1],"MULTIPLAYER \n"); sprintf(menu[2],"OPTIONS \n"); //strcpy(menu[0],"ARCADE\n"); /* for(int i=0; i <= 2 ; i++) { //PA_OutputText(SCREEN_BOTTOM, 0, i+3, "%s", i , menu[i] ); PA_OutputText(SCREEN_BOTTOM, 5, 7+i, "%s", menu[i] ); } */ // Deber PA_DeleteBg(SCREEN_BOTTOM, 3); PA_EasyBgLoad(SCREEN_BOTTOM, 3, gameP7); } void Game::renderScore( char gName[] , int pos , int score , int life) { char tempChar[32]; sprintf(tempChar,"%-7.7s %03d %03d" , gName , score , life ); PA_OutputText(SCREEN_BOTTOM, 2, 5+pos, "%s", tempChar ); } void Game::runGame() { // Instanciamos el Mapa // /* PA_EasyBgLoad(SCREEN_TOP, BACKGROUND_TWO, map1Med); PA_EasyBgLoad(SCREEN_TOP, BACKGROUND_THREE, agua); PA_EasyBgLoad(SCREEN_TOP, BACKGROUND_ONE, map1Top); */ addStringDebug("Instance World"); mymap = new MapWorld(); mymap->setMap(1); mymap->loadMap(); // Instanciamos PlayerLocal addStringDebug("Instance Player and CPU"); PlayerLocal *player = new PlayerLocal(); player = new PlayerLocal(); char temporalName[64]; strcpy(temporalName,(char*)PA_UserInfo.Name); player->setName(temporalName); player->mymap = mymap; // Instanciamos PlayerComputer PlayerComputer *playercpu[MAX_COMPUTER]; // Load PlayerComputer for(int i=0; i<MAX_COMPUTER;i++) { mymap->positionRandom(CARCPU_X,CARCPU_Y); CARCPU_Y = CARCPU_Y*(-1); // Palleta y Sprite Aleatorio int styleCar = PA_RandMinMax(1,4); playercpu[i] = new PlayerComputer(); playercpu[i]->mymap = mymap; playercpu[i]->setMyCar( getPalleteCar(styleCar) , getSpriteCar(styleCar) , CARCPU_X , CARCPU_Y , CARCPU_CENTER_X , CARCPU_CENTER_Y ); char temporalNameCPU[64]; sprintf(temporalNameCPU,"CPU %d",i); playercpu[i]->setName(temporalNameCPU); } // Pruebas (voy a mover a CAR) CAR_X = 225; CAR_Y = 0; mymap->positionRandom(CAR_X,CAR_Y); CAR_Y = CAR_Y*(-1); mymap->positionRandom(CARCPU_X,CARCPU_Y); CARCPU_Y = CARCPU_Y*(-1); BACKGROUND_X = CAR_X - CAR_CENTER_X; BACKGROUND_Y = CAR_Y - CAR_CENTER_Y; // Centrado player->setMyCar( (void*)car1_Pal , (void*)car1_Sprite , CAR_X , CAR_Y , CAR_CENTER_X , CAR_CENTER_Y ); // Prioriodad de Fondos PA_SetSpritePrio(SCREEN_TOP, CAR_SPRITE, BACKGROUND_TWO); PA_EnableSpecialFx(SCREEN_TOP, SFX_ALPHA, 0, SFX_BG0 | SFX_BG1 | SFX_BG2 | SFX_BG3 | SFX_BD); PA_SetSFXAlpha(SCREEN_TOP, 12, 15); PA_InitParallaxX(SCREEN_TOP, 0, 256, 256, 0); PA_InitParallaxY(SCREEN_TOP, 0, 256, 256, 0); //PA_ParallaxScrollXY(SCREEN_TOP, BACKGROUND_X, BACKGROUND_Y); // Movemos la Pantalla int i = 0; while( 1 == 1) { /* if ( fps%15 ) */ // Rally NDS by deerme.org player->play(); if ( fps%25 ) renderScore( player->name , player->nplayer , player->score , player->life ); for(int i=0; i<MAX_COMPUTER;i++) { playercpu[i]->play(); if ( fps%25 ) renderScore( playercpu[i]->name , playercpu[i]->nplayer , playercpu[i]->score , playercpu[i]->life ); } // !! runCar !! player->myCar->runCar(); for(int i=0; i<MAX_COMPUTER;i++) { playercpu[i]->myCar->runCar(); } /* if ( time == 10 ) { char out[32] = " "; for( int i = 0 ; i< MAX_COMPUTER; i++ ) { sprintf(out,"(%02d,%03d,%03d)" , i, this->mymap->getXPlayerPosition(i) , this->mymap->getYPlayerPosition(i) ); addStringDebug(out); } showDebug(); } */ if ( fps%25 ) { showDebug(); } // Renderizamos player->renderer(); for(int i=0; i<MAX_COMPUTER;i++) { playercpu[i]->renderer(); } playercpu[0]->renderer(); playercpu[1]->renderer(); mymap->renderer(); if ( fps == 30 ) { fps = 0; time++; } if ( time == 10000 ) { time = 0; } if ( DEBUGMODE == 1 ) PA_OutputText(SCREEN_BOTTOM, 20, 20, "fps:%d", fps); fps++; PA_WaitForVBL(); } //PA_WaitForVBL(); } // Player Player::Player() { //mymap = new MapWorld(); strcpy(name,"NOTENGONOMBRE "); nplayer = getNumberPlayer(); this->score = 0; this->life = 100; } void Player::setMyCar( void* pal , void* spr , int mX , int mY , int sX , int sY) { // Instanciamos a myCar //Car *myCar = new Car(); Corregido por lgm myCar = new Car(); myCar->setPallete( pal ); myCar->setSprite( spr ); // Score y Life myCar->life = &this->life; myCar->score = &this->score; // Mapa myCar->setX( mX ); myCar->setY( mY ); // Screen myCar->setSx( sX ); myCar->setSy( sY ); myCar->createCar(); // Paso al Auto una referencia del mapa myCar->mymap = mymap; myCar->nplayer = this->nplayer; // Seteo el valor mymap->setPlayerPosition(nplayer,mX,mY); } void Player::setName( char gName[] ) { strcpy(this->name,gName); } PlayerLocal::PlayerLocal(){} void PlayerLocal::play() { // Como soy el Player local debo analizar las Teclas Presionadas if ( Pad.Held.Up ) { myCar->setAng(90); } if ( Pad.Held.Down ) { myCar->setAng(270); } if ( Pad.Held.Left ) { myCar->setAng(180); } if ( Pad.Held.Right ) { myCar->setAng(0); } if ( Pad.Held.A ) { if ( this->myCar->vel < 120 ) this->myCar->vel++; } if ( Pad.Held.B ) { if ( this->myCar->vel > 60 ) this->myCar->vel--; } // Analizamos la Aceleracion } void PlayerLocal::renderer() { // Soy el PlayerLocal, yo muevo la pantallaplayerLocalX = (int)myCar->getX(); playerLocalY = (int)myCar->getY(); PA_ParallaxScrollXY(SCREEN_TOP, BACKGROUND_X - CAR_X + (int)myCar->getX() , BACKGROUND_Y - CAR_Y + ((int)myCar->getY()*-1) ); /* PA_ParallaxScrollXY(SCREEN_TOP, CAR_CENTER_X - CAR_X + (int)myCar->getX() , (CAR_CENTER_Y*-1) - CAR_Y + ((int)myCar->getY()*-1) ); */ } PlayerComputer::PlayerComputer(){} void PlayerComputer::play() { // Por el momento no tengo logica xD //myCar->setAng(0); if ( time%100 == 0 ) { int n = PA_RandMinMax(0,3); if ( n == 0 ) { myCar->setAng(0); } else if( n == 1 ) { myCar->setAng(90); } else if( n == 2 ) { myCar->setAng(270); } else if( n == 3 ) { myCar->setAng(180); } } } void PlayerComputer::renderer() { // Por el momento no tengo logica xD int xl = myCar->getX(); int yl = myCar->getY(); yl = yl * (-1); /* if ( fps%30 == 0 ) { char out[32] = " "; sprintf(out,"CPU - (%d,%d)xy",xl,yl); addStringDebug(out); } */ // ¿ Esta en el espacio visual del player local ? ///if ( playerLocalX + 128 <= xl && playerLocalX - 128 >= xl /*&& (playerLocalY*(-1)) + 95 < yl && (playerLocalY*(-1)) - 95 > yl*/ )*/ if ( playerLocalX -128 <= xl && playerLocalX +128 >= xl && (playerLocalY*(-1)) - 95 <= yl && (playerLocalY*(-1)) + 95 >= yl ) { PA_obj[SCREEN_TOP][myCar->car_sprite].atr0 &= ~(2<<8); // Calculamos el punto de referencia xl = xl - ( playerLocalX - 128 ); yl = yl - ( playerLocalY*-1 - 95 ); myCar->setSx(xl); myCar->setSy(yl); // Fixme // Fixme PA_SetSpriteXY(SCREEN_TOP, myCar->car_sprite , myCar->getSx() -9 , myCar->getSy() -4 ); } else { // Deberiamos ocultar al Sprite PA_obj[SCREEN_TOP][myCar->car_sprite].atr0 |= (2<<8); /* char out[32] = " "; sprintf(out,"No entro
![]()
"); addStringDebug(out); */ } };