https://rapidshare.com/files/3376479166 ... 42012-.rar
*NOTA:El codigo esta en gran parte en español para que se les facilite entenderlo.Utilizo Programacion Orientada a Objetos(POO).
- Código: Seleccionar todo
 #include <SDL.h>
 #include <SDL_image.h>
 #include <SDL_ttf.h>
 #include <string>
 #include <fstream>
 //Atributos de la pantalla
 const int PANTALLA_ANCHO = 800;
 const int PANTALLA_ALTO = 600;
 const int PANTALLA_BPP = 32;
 //La velocidad de cuadros por segundo (FPS)
 const int CUADROS_POR_SEGUNDO = 20;
 //Las dimensiones del Personaje
 const int PJ_ANCHO = 20;
 const int PJ_ALTO = 20;
 //Las dimensiones del nivel
 const int NIVEL_ANCHO = 1280;
 const int NIVEL_ALTO = 960;
 //Constantes del "Tile"
 const int TILE_ANCHO = 80;
 const int TILE_ALTO = 80;
 const int TOTAL_TILES = 192;
 const int TILE_GRAFICOS = 2;
 //Los diferentes graficos del tile
 const int TILE_LADRILLO = 0;
 const int TILE_VACIO = 1;
 bool SALIR = false;
 char TITULO[]="Juego de pruebas #1";
 //Las superficies
 SDL_Surface *PJ_GRA = NULL;
 SDL_Surface *PANTALLA = NULL;
 SDL_Surface *GRAFICOS = NULL;
 SDL_Surface *MENSAJE = NULL;
 //Recta donde se guardan los tiles que se "recortaran" desde el archivo de graficos
 SDL_Rect clips[ TILE_GRAFICOS ];
 //La estructura EVENTO
 SDL_Event EVENTO;
 //El rectangulo de la camara
 SDL_Rect CAMARA_R = { 0, 0, PANTALLA_ANCHO, PANTALLA_ALTO };
 //Definicion de los diferentes parametros que se necesitan para mostrar el texto por la pantalla
 TTF_Font *FUENTE = NULL;
 SDL_Color COLOR_TEXTO = { 255, 255, 255 };
 char TEXTO[]="Variables del PJ (x,y)";
 //La clase TILE
 class TILE
 {
 private:
 //Los atributos del tile
 SDL_Rect RECTA2;
 //El tipo de tile
 int TIPO;
 
 public:
 //Inicializacion de las variables
 TILE( int x, int y, int TIPOTILE );
 //Muestra los tiles
 void MOSTRAR();
 //Obtiene el tipo de tile
 int OBT_TIPO();
 //Obtiene el rectangulo de la colision
 SDL_Rect OBT_RECT();
 };
 //La clase PJ
 class PJ
 {
 private:
 //El rectangulo de colision del personaje (PJ)
 SDL_Rect RECTANGULO;
 //La velocidad del PJ
 int VEL_X, VEL_Y;
 public:
 //Inicializa las variables
 PJ();
 //Detecta las pulsaciones del teclado y ajusta la velocidad del PJ
 void TECLADO();
 //Mueve al PJ
 void MOVER( TILE *tiles[] );
 //Muestra al PJ en la pantalla
 void MOSTRAR();
 //Establece la camara sobre el personaje
 void CAMARA();
 };
 //Temporizador (TEMPO)
 class TEMPORIZADOR
 {
 private:
 //La hora del reloj cuando el TEMPO comenzo
 int startTicks;
 //La hora del reloj cuando el TEMPO pauso
 int pausedTicks;
 //El estado del TEMPO
 bool paused;
 bool started;
 public:
 //Inicializa las variables
 TEMPORIZADOR();
 //Las diferentes acciones del reloj
 void start();
 void stop();
 void pause();
 void unpause();
 //Obtiene la hora del temporizador
 int get_ticks();
 //Chekea el estado del temporizador
 bool is_started();
 bool is_paused();
 };
 SDL_Surface *CARGAR( std::string filename )
 {
 //La imagen que sera cargada
 SDL_Surface* CARGAR_IMAGEN = NULL;
 //La superficie optimizada que sera usada
 SDL_Surface* IMAGEN_OPTIMIZADA = NULL;
 //Cargar la imagen
 CARGAR_IMAGEN = IMG_Load( filename.c_str() );
 //Si la imagen se cargo
 if( CARGAR_IMAGEN != NULL )
 {
 //Crea una superficie optimizada
 IMAGEN_OPTIMIZADA = SDL_DisplayFormat( CARGAR_IMAGEN );
 //Descarga la superficie vieja
 SDL_FreeSurface( CARGAR_IMAGEN );
 //Si la superficie fue optimizada
 if( IMAGEN_OPTIMIZADA != NULL )
 {
 //Color de profundidad de la superficie
 SDL_SetColorKey( IMAGEN_OPTIMIZADA, SDL_SRCCOLORKEY, SDL_MapRGB( IMAGEN_OPTIMIZADA->format, 255, 0, 128 ) );
 }
 }
 //Retorna la superficie optimizada
 return IMAGEN_OPTIMIZADA;
 }
 void DIBUJAR( int x, int y, SDL_Surface* ORIGEN, SDL_Surface* DESTINO, SDL_Rect* CLIP = NULL )
 {
 //Rectangulo
 SDL_Rect RECTANGULO;
 //Asignacion de variables al rectangulo
 RECTANGULO.x = x;
 RECTANGULO.y = y;
 //Dibujar
 SDL_BlitSurface( ORIGEN, CLIP, DESTINO, &RECTANGULO );
 }
 bool COLISION( SDL_Rect A, SDL_Rect B )
 {
 //Lados de los rectangulos
 int leftA, leftB;
 int rightA, rightB;
 int topA, topB;
 int bottomA, bottomB;
 //Calcular los lados del rectangulo A
 leftA = A.x;
 rightA = A.x + A.w;
 topA = A.y;
 bottomA = A.y + A.h;
 //calcular los lados del rectangulo B
 leftB = B.x;
 rightB = B.x + B.w;
 topB = B.y;
 bottomB = B.y + B.h;
 //Si alguno de los lados de A esta fuera de B
 if( bottomA <= topB ){ return false; }
 if( topA >= bottomB ){ return false; }
 if( rightA <= leftB ){ return false; }
 if( leftA >= rightB ){ return false; }
 //Si ninguno de los lados de A esta fuera de B
 return true;
 }
 bool INICIAR()
 {
 //Inicializa todos los sub sistemas de SDL
 if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ){ return false; }
 //Configura la pantalla
 PANTALLA = SDL_SetVideoMode( PANTALLA_ANCHO, PANTALLA_ALTO, PANTALLA_BPP, SDL_SWSURFACE );
 //Si hubo algun error al configurar la pantalla
 if( PANTALLA == NULL ){ return false; }
 if( TTF_Init() == -1 ){ return false; }
 //El titulo de la ventana
 SDL_WM_SetCaption( TITULO, NULL );
 //Si todo se inicializo bien
 return true;
 }
 bool CARGAR_ARCHIVOS()
 {
 //Abre la fuente del tipo de letra
 FUENTE = TTF_OpenFont( "cour.ttf", 28 );
 //Carga la imagen
 PJ_GRA = CARGAR( "PJ.bmp" );
 //Si hubo algun problema en cargar la imagen del PJ
 if( PJ_GRA == NULL ){ return false; }
 //Carga los graficos de los tiles
 GRAFICOS = CARGAR( "tiles.bmp" );
 //Si hubo algun problema en cargar los graficos de los tiles
 if( GRAFICOS == NULL ){ return false; }
 //Si todo se cargo bien
 return true;
 }
 void DESCARGAR_ARCHIVOS( TILE *tiles[] )
 {
 //Descarga las superficies
 SDL_FreeSurface( PJ_GRA );
 SDL_FreeSurface( GRAFICOS );
 SDL_FreeSurface( MENSAJE );
 //Descarga o elimina las superficies
 for( int t = 0; t < TOTAL_TILES; t++ )
 {
 delete tiles[ t ];
 }
 TTF_CloseFont( FUENTE );
 TTF_Quit();
 //Salir de SDL
 SDL_Quit();
 }
 //Esta funcion recorta los tiles del archivo imagen donde se encuntran estos
 void RECORTES()
 {
 //Recorte de los graficos
 clips[ TILE_LADRILLO ].x = 0;
 clips[ TILE_LADRILLO ].y = 0;
 clips[ TILE_LADRILLO ].w = TILE_ANCHO;
 clips[ TILE_LADRILLO ].h = TILE_ALTO;
 clips[ TILE_VACIO ].x = 80;
 clips[ TILE_VACIO ].y = 0;
 clips[ TILE_VACIO ].w = TILE_ANCHO;
 clips[ TILE_VACIO ].h = TILE_ALTO;
 
 }
 /*Esta funcion se encarga de colocar los tiles en el orden en que estan, en el archivo "map"
 que se cargo*/
 bool COLOCAR_TILES( TILE *tiles[] )
 {
 //Las variables de los tiles
 int x = 0, y = 0;
 //Abre el archivo "map"
 std::ifstream map( "mapa.map" );
 //Si el archivo map no pudo ser cargado
 if( map == NULL ){ return false; }
 //Inicializa los tiles
 for( int t = 0; t < TOTAL_TILES; t++ )
 {
 //Determina que tipo de tile sera colocado
 int TIPOTILE = -1;
 //Lee el tile desde el archivo "map"
 map >> TIPOTILE;
 //Si hubo algun problema en leer el archivo "map"
 if( map.fail() == true )
 {
 //Para el cargado del archivo map
 map.close();
 return false;
 }
 //Si el numero es un numero de tile valido
 if( ( TIPOTILE >= 0 ) && ( TIPOTILE < TILE_GRAFICOS ) )
 {
 tiles[ t ] = new TILE( x, y, TIPOTILE );
 }
 //Si no se reconoce el tipo de tile
 else
 {
 //Para el cargado del archivo map
 map.close();
 return false;
 }
 //Mover al siguiente lugar de tile
 x += TILE_ANCHO;
 //Si hemos ido demasiado lejos
 if( x >= NIVEL_ANCHO )
 {
 //Mover atras
 x = 0;
 //Mover a la siguiente fila
 y += TILE_ALTO;
 }
 }
 //Cerrar el archivo map
 map.close();
 //Si el archivo map se cargo bien
 return true;
 }
 bool COLISION_TILE( SDL_Rect RECTA_F, TILE *tiles[] )
 {
 //Ir atravez de los tiles
 for( int t = 0; t < TOTAL_TILES; t++ )
 {
 //Si el tile es un ladrillo
 if( ( tiles[ t ]->OBT_TIPO() == TILE_LADRILLO ))
 {
 //Si el rectangulo de colision toca un tile de ladrillo
 if( COLISION( RECTA_F, tiles[ t ]->OBT_RECT() ) == true )
 {
 return true;
 }
 
 }
 
 }
 //Si los tiles de la pared no fueron tocados
 return false;
 }
 TILE::TILE( int x, int y, int TIPOTILE )
 {
 //Obtiene las variables del rectangulo
 RECTA2.x = x;
 RECTA2.y = y;
 //Asignacion de acho y alto al rectangulo
 RECTA2.w = TILE_ANCHO;
 RECTA2.h = TILE_ALTO;
 //Obtiene el tipo de tile
 TIPO = TIPOTILE;
 }
 void TILE::MOSTRAR()
 {
 //Si el tile esta en la pantalla
 if( COLISION( CAMARA_R,RECTA2 ) == true )
 {
 //Dibuja el tile
 DIBUJAR( RECTA2.x - CAMARA_R.x, RECTA2.y - CAMARA_R.y, GRAFICOS, PANTALLA, &clips[ TIPO ] );
 }
 }
 int TILE::OBT_TIPO()
 {
 return TIPO;
 }
 SDL_Rect TILE::OBT_RECT()
 {
 return RECTA2;
 }
 PJ::PJ()
 {
 //Inicializa las variables del rectangulo
 RECTANGULO.x = 0;
 RECTANGULO.y = 0;
 RECTANGULO.w = PJ_ANCHO;
 RECTANGULO.h = PJ_ALTO;
 //Inicializa la velocidad
 VEL_X = 0;
 VEL_Y = 0;
 }
 void PJ::TECLADO()
 {
 //Si una tecla fue presionada
 if( EVENTO.type == SDL_KEYDOWN )
 {
 //Ajusta la velocidad
 switch( EVENTO.key.keysym.sym )
 {
 case SDLK_UP: VEL_Y -= PJ_ALTO / 2; break;
 case SDLK_DOWN: VEL_Y += PJ_ALTO / 2; break;
 case SDLK_LEFT: VEL_X -= PJ_ANCHO / 2; break;
 case SDLK_RIGHT: VEL_X += PJ_ANCHO / 2; break;
 
 }
 }
 //Si una tecla fue levantada
 else if( EVENTO.type == SDL_KEYUP )
 {
 //Ajusta la velocidad
 switch( EVENTO.key.keysym.sym )
 {
 case SDLK_UP: VEL_Y += PJ_ALTO / 2; break;
 case SDLK_DOWN: VEL_Y -= PJ_ALTO / 2; break;
 case SDLK_LEFT: VEL_X += PJ_ANCHO / 2; break;
 case SDLK_RIGHT: VEL_X -= PJ_ANCHO / 2; break;
 
 }
 }
 //Si se presiona la tecla escape, salir.
 if(EVENTO.key.keysym.sym == SDLK_ESCAPE){ SALIR = true; }
 }
 void PJ::MOVER( TILE *tiles[] )
 {
 
 //Mover al PJ a la izquierda o derecha
 RECTANGULO.x += VEL_X;
 
 //Si el PJ se sale por la izquierda o derecha,o a tocado un ladrillo
 if( ( RECTANGULO.x < 0 ) || ( RECTANGULO.x + PJ_ANCHO > NIVEL_ANCHO ) || COLISION_TILE( RECTANGULO, tiles ) )
 {
 //Mover atras
 RECTANGULO.x -= VEL_X;
 }
 //Mover al PJ arriba o abajo
 RECTANGULO.y += VEL_Y;
 
 
 //Si el PJ se sale por arriba o abajo,o a tocado un ladrillo
 if( ( RECTANGULO.y < 0 ) || ( RECTANGULO.y + PJ_ALTO > NIVEL_ALTO ) || COLISION_TILE( RECTANGULO, tiles ) )
 {
 //Mover atras
 RECTANGULO.y -= VEL_Y;
 }
 }
 void PJ::MOSTRAR()
 {
 //Dibuja al PJ
 DIBUJAR( RECTANGULO.x - CAMARA_R.x, RECTANGULO.y - CAMARA_R.y, PJ_GRA, PANTALLA );
 
 }
 void PJ::CAMARA()
 {
 //Centrar la camara sobre el PJ
 CAMARA_R.x = ( RECTANGULO.x + PJ_ANCHO / 2 ) - PANTALLA_ANCHO / 2;
 CAMARA_R.y = ( RECTANGULO.y + PJ_ALTO / 2 ) - PANTALLA_ALTO / 2;
 //Mantiene la camara dentro del ecenario
 if( CAMARA_R.x < 0 ){CAMARA_R.x = 0;}
 if( CAMARA_R.y < 0 ){CAMARA_R.y = 0;}
 if( CAMARA_R.x > NIVEL_ANCHO - CAMARA_R.w ){CAMARA_R.x = NIVEL_ANCHO - CAMARA_R.w;}
 if( CAMARA_R.y > NIVEL_ALTO - CAMARA_R.h ){CAMARA_R.y = NIVEL_ALTO - CAMARA_R.h;}
 }
 TEMPORIZADOR::TEMPORIZADOR()
 {
 //Inicializa las variables
 startTicks = 0;
 pausedTicks = 0;
 paused = false;
 started = false;
 }
 void TEMPORIZADOR::start()
 {
 //Inicia el temporizador
 started = true;
 //Pausa el temporizador
 paused = false;
 //Obtiene la hora actual del reloj
 startTicks = SDL_GetTicks();
 }
 void TEMPORIZADOR::stop()
 {
 //Para el temporizador
 started = false;
 //Reanuda el temporizador
 paused = false;
 }
 void TEMPORIZADOR::pause()
 {
 //Si el temporizador esta en marcha y no se detuvo
 if( ( started == true ) && ( paused == false ) )
 {
 //Pausa el temporizador
 paused = true;
 //Calcula el tiempo de pausa
 pausedTicks = SDL_GetTicks() - startTicks;
 }
 }
 void TEMPORIZADOR::unpause()
 {
 //Si el temporizador esta pausado
 if( paused == true )
 {
 //reanuda el temporizador
 paused = false;
 //Reinicia el tiempo de inicio
 startTicks = SDL_GetTicks() - pausedTicks;
 //Reinicia el tiempo de pausado
 pausedTicks = 0;
 }
 }
 int TEMPORIZADOR::get_ticks()
 {
 //Si el temporizador esta corriendo
 if( started == true )
 {
 //Si el temporizador esta pausado
 if( paused == true )
 {
 //Devuelve el numero de tiempo cuando el temporizador fue pausado
 return pausedTicks;
 }
 else
 {
 //Devuelve el tiempo actual menos la hora de inicio
 return SDL_GetTicks() - startTicks;
 }
 }
 //Si el temporizador no esta funcionando
 return 0;
 }
 bool TEMPORIZADOR::is_started()
 {
 return started;
 }
 bool TEMPORIZADOR::is_paused()
 {
 return paused;
 }
 int main( int argc, char* args[] )
 {
 //El PJ
 PJ PELOTA;
 //Los tiles que seran usados
 TILE *tiles[ TOTAL_TILES ];
 //El regulador de velocidad de cuadros
 TEMPORIZADOR FPS;
 //Inicializar
 if( INICIAR() == false ){ return 1; }
 //Cargar los archivos
 if( CARGAR_ARCHIVOS() == false ){ return 1; }
 MENSAJE = TTF_RenderText_Solid( FUENTE, TEXTO, COLOR_TEXTO );
 //Recortes de los graficos
 RECORTES();
 //Coloca los tiles
 if( COLOCAR_TILES( tiles ) == false ){ return 1; }
 //Mientras el usuario no se salga
 while( SALIR == false )
 {
 //Iniciar el temporizador de cuadros
 FPS.start();
 //Mientras halla eventos por manejar
 while( SDL_PollEvent( &EVENTO ) )
 {
 //Eventos del teclado para el PJ
 PELOTA.TECLADO();
 //Evento de salida
 if( EVENTO.type == SDL_QUIT )
 {
 //Salir del programa
 SALIR = true;
 }
 }
 //Mover al PJ
 PELOTA.MOVER( tiles );
 
 //Activa la camara
 PELOTA.CAMARA();
 //Muestra los tiles
 for( int t = 0; t < TOTAL_TILES; t++ ){ tiles[ t ]->MOSTRAR(); }
 //Muestra al PJ en la pantalla
 PELOTA.MOSTRAR();
 //Dibujar el mensaje
 DIBUJAR( 10,10 , MENSAJE, PANTALLA );
 //Actualiza la pantalla
 if( SDL_Flip( PANTALLA ) == -1 ){ return 1; }
 //Calculo de la velocidad de cuadros por segundo
 if( FPS.get_ticks() < 1000 / CUADROS_POR_SEGUNDO )
 {
 SDL_Delay( ( 1000 / CUADROS_POR_SEGUNDO ) - FPS.get_ticks() );
 }
 }
 //Descargar archivos
 DESCARGAR_ARCHIVOS( tiles );
 return 0;
 }

