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;
}