Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





[SDL] Ayuda con FPS (Fame por segundo)

Iniciado por mastermts, 02 de Agosto de 2008, 11:34:42 PM

« anterior - próximo »

mastermts

Hola, primero que todo quiero decir que soy nuevo en esto de la programacion de juegos.

Bueno, miren, lo que estoy haciendo es un juego de mario bross, algo simple para aprender, lo que tengo hasta ahora es al mario caminando a la izquierda o a la derecha, pero sin animacion.

ahora, he intentado darle animacion, pero me funciona a diferente velocidad en los 2 pc que tengo, por lo que he leido se trata del FPS ya que cada computadora al tener distinto CPU en algunos los calculos son mas rapidos que otros.

bueno hasta aqui todo bien ya he entendido el porke, pero ahora me gustaria saber como se controla el tiempo para que muestre los mismo FPS en cada segundo, por lo que he leido, tiene que ser minimo 25 FPS por segundo porque el cerebro desde esa velocidad ya ve animaciones en ves de fotos estaticas.

ahora intente hacer esto para hacer una ventana en el cual en el title me muestre un reloj y me funciono, pero ahora no se si esto mismo me sirve para hacer los fps, ya que al probar con mario = como que habeses los monos se ven como medios borrosos en una maquina y en la otra no.


bueno este es el codigo:

#include <cstdlib>
#include <iostream>
#include <SDL/SDL.h>
using namespace std;
void Iniciarp(SDL_Surface **Pantalla);
int main(int argc, char *argv[])
{
   SDL_Surface *Pantalla;
   SDL_Event event;
   Sint32 Salir=0;
   Uint32 Tiempo, Tiempo2, res;
   int hora=0, minuto=0, segundo=0, cuadros=0;
   char msn[100];
   Iniciarp(&Pantalla);
   Tiempo = SDL_GetTicks();
   while(! Salir){
           SDL_PollEvent(&event);
           if (event.type == SDL_QUIT) Salir = 1;
           res = Tiempo2 - Tiempo;
           sprintf(msn,"Hora:%d Minuto:%d Segundo:%d cuadros:%d",hora,minuto,segundo, cuadros);
           SDL_WM_SetCaption(msn, NULL);
           Tiempo2 = SDL_GetTicks();
           if (res >=1000){
              Tiempo=Tiempo2;
                   if (segundo>60){
                      segundo=0;
                      minuto++;
                   } else {
                     segundo++;
                   }
                   if (minuto>=60){
                      minuto=0;
                      hora++;
                   }
                   } else {
                     SDL_Delay(res / 10);
                   }

   }            
return EXIT_SUCCESS;
}
void Iniciarp(SDL_Surface **Pantalla){
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) == -1){
               printf("Error: %s\n", SDL_GetError());
    }
    *Pantalla = SDL_SetVideoMode(800, 600, 16, SDL_HWSURFACE);
    SDL_WM_SetCaption("Desarrollo de TCG", NULL);
}


espero que me puedan ayuda.

atte:  8) Mastermts

PD: estoy trabajando con el compilador dev-c++


aqui podre el codigo del mario que tengo:

main.cpp

/*
Titulo Proyecto: MARIO-SYL
AUTOR: Daniel Miranda
Fecha: Martes 22 de Julio del 2008
*/
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_rotozoom.h>
#include "personaje.cpp"
void Iniciarp(SDL_Surface **Pantalla);
//void Imprimirf(SDL_Surface *pantalla, struct PJ *PJ);
void Limpiarp(SDL_Surface *Monitor);
//void Movero(Sint32 *x, Sint32 *y, Sint32 ancho, Sint32 alto);

int main(Sint32 argc, char *argv[])
{
   //Entrada
   SDL_Surface *Monitor,;
   SDL_Event event;
   Sint32 salir = 0;
   Iniciarp(&Monitor);
   Uint32 Tiempo_final, Tiempo_actual, res=0;
   Jugador PJ;
   char msn[100];
   if (Monitor == NULL)
   {
       printf("Error: %s\n", SDL_GetError());
       return 1;
   }
   PJ.Cargar(10,21,5,4,"imagenes/personaje/2_mario.png");
   PJ.Agregar_ani(10,14,5,3);
   PJ.Agregar_ani(5,9,5,3);
   Tiempo_final = SDL_GetTicks();
//procesamiento
   while (! salir){
       //calculos
       SDL_PollEvent(&event);
       if (event.type == SDL_QUIT) salir = 1;
       Tiempo_actual = SDL_GetTicks();
       res = Tiempo_actual - Tiempo_final;
       if ( res >=70){
           Limpiarp(Monitor);
           sprintf(msn,"Tiempo: %d",res);
           SDL_WM_SetCaption(msn, NULL);
           PJ.animaciones();
           PJ.Control();
           PJ.mostrar(Monitor);
           //mostrar
           SDL_Flip(Monitor);
           SDL_Delay(30);
           Tiempo_final = Tiempo_actual;
       } else {
           SDL_Delay(70 - (res));
        }
   }
   //salida
   SDL_Quit();
   return 0;
}

void Limpiarp(SDL_Surface *Monitor)
{
       Sint32 a = SDL_MapRGB(Monitor->format, 200,200,200);
       SDL_FillRect(Monitor, NULL, a);
}

void Iniciarp(SDL_Surface **Pantalla){
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) == -1){
               printf("Error: %s\n", SDL_GetError());
    }
    *Pantalla = SDL_SetVideoMode(800, 600, 16, SDL_HWSURFACE);
    SDL_WM_SetCaption("Desarrollo de TCG", NULL);
}


personaje.cpp:

/*
Titulo Proyecto: MARIO-SYL
AUTOR: Daniel Miranda
Fecha: Martes 22 de Julio del 2008
SCRIPT: CLASE PJ
*/
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_rotozoom.h>

class Ani{
public:
   Uint32 Cinicio, Cfinal, Cactual; //cuadro inicio, final y actual
   Uint32 Columnas, Filas; //N° de columnas y fila
   Uint32 Activado; // si esta activada la animacion o no
   Sint32 ancho, alto;
};

class Jugador{
private:
   Uint32 X,Y,vel,Dir;//cordenadas X,y. Velocidad, Direccion de vista del pj.
   SDL_Surface *grilla;
   Sint32 con;
   Ani anima[3];
public:
   Jugador(){
       this->con=0;
   }
   void Cargar(Uint32 posX,Uint32 posY,Uint32 vel,Uint32 Dir, char *path){
       this->X = posX;
       this->Y = posY;
       this->vel = vel;
       this->Dir = Dir;
       this->Dir = Dir;
       this->grilla = IMG_Load(path);
   }
   void Agregar_ani(Uint32 Cinicio, Uint32 Cfinal,Uint32 Columnas,Uint32 Filas){
       this->con += 1;
       this->anima[this->con].Cinicio = Cinicio;
       this->anima[this->con].Cfinal = Cfinal;
       this->anima[this->con].Cactual = this->anima[this->con].Cinicio;
       this->anima[this->con].Columnas = Columnas;
       this->anima[this->con].Filas = Filas;
       this->anima[this->con].Activado = 0;
       this->anima[this->con].ancho = this->grilla->w / this->anima[this->con].Columnas;
       this->anima[this->con].alto = this->grilla->h / this->anima[this->con].Filas;
   }
   void mostrar(SDL_Surface *screen){
       Sint32 activo=0;
       if (this->anima[1].Activado == 1){
           activo=1;
       }
       if (this->anima[2].Activado == 1){
           activo=2;
       }
       
       
       SDL_Rect fuente;
       SDL_Rect destino;

       destino.x = this->X;
       destino.y = this->Y;

       fuente.w = this->anima[activo].ancho;
       fuente.h = this->anima[activo].alto;
       
       fuente.x = (this->anima[activo].Cactual % this->anima[activo].Columnas) * fuente.w;
       fuente.y = (this->anima[activo].Cactual / this->anima[activo].Columnas) * fuente.h;

       SDL_BlitSurface(this->grilla, &fuente, screen, &destino);
   }
   void Control(){
       Uint8 *key = SDL_GetKeyState(NULL);
       
       if (key[SDLK_LEFT]&& this->X > 0){
           if (key[SDLK_z]){
               (this->X) -= (this->vel * 2);
           } else {
               (this->X) -= this->vel;
           }
           this->anima[1].Activado = 1;
           this->Dir = 1;
       }
               
       if (key[SDLK_RIGHT] && (this->X + this->anima[1].ancho < 800)){  
           if (key[SDLK_z]){
               (this->X) += (this->vel * 2);
           } else {
               (this->X) += this->vel;
           }
           this->anima[2].Activado = 1;
           this->Dir = 2;
       }
       if (key[SDLK_UP] && this->Y > 0)
           (this->Y) -= this->vel;
               
       if (key[SDLK_DOWN] && (this->Y + this->anima[1].alto) < 600)
           (this->Y) += this->vel;
   }
   void animaciones(){
       //caminar Derecha
       if (this->anima[2].Activado == 1){
           if (this->anima[2].Cactual < this->anima[2].Cfinal){
               this->anima[2].Cactual++;
           } else {
                  this->anima[2].Activado = 0;
                  this->anima[2].Cactual = this->anima[2].Cinicio;
           }
       }
       // caminar Izquierda
       if (this->anima[1].Activado == 1){
           if (this->anima[1].Cactual < this->anima[1].Cfinal){
               this->anima[1].Cactual++;
           } else {
                  this->anima[1].Activado = 0;
                  this->anima[1].Cactual = this->anima[1].Cinicio;
           }
       }
   }
};


Tambien incluyo el proyecto compimido en ZIP con todo para llegar y compilar en windows con dev-c++
http://www.megaupload.com/es/?d=AE4PDHHP

davirro

usa esta cabecera <SDL_framerate.h> contiene las funciones para controlar los FPS

StraT

Hola:

Si se te ve con parpadeos (supongo que te refieres a eso cuando dices borroso) es porque no estás usando doble buffer.

Cambia esto:

*Pantalla = SDL_SetVideoMode(800, 600, 16, SDL_HWSURFACE);

por esto:

*Pantalla = SDL_SetVideoMode(800, 600, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);

Saludos
quot;Solo hay dos cosas infinitas, el universo y la estupidez humana, aunque de lo primero no estoy muy seguro\\\" Einstein

mastermts

ok, gracias por las respuestas, voy a probar ahora con el doble buffer.

con repecto a <SDL_framerate.h> no tenia idea que existiera una libreria para esto, buscare infomracion al respecto.


muchas gracias.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.