Animation in C, with Graphics.h

1

I'm doing a task animation, based on images with putpixel, I use setvisualpage, and setactivepage for the blinking it has when it comes to displaying and removing an image. The fact is that now I want the animation to move faster, will there be a way to do it? with delay the delay but I do not know if there is a function or way that allows me to see the animation fluid.

#include<winbgim.h>
#include<conio.h>
#include<gotoxy.h>
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include <stdbool.h>
#include <ctype.h>
#include <string.h>

void fotograma(int alto, int ancho);
void Llenar(int alto, int ancho);
void Archivo(int cont);
void Bienvenida();

FILE *archivo;

struct Pixeles
{
    int Rojo;
    int Verde;
    int Azul;   
}RGB[2000];

struct Imagen
{
    struct Pixeles RGB[2000];
}foto[2000];

int main()
{

int cont, page=0;
system("color f4");
initwindow(720,480);
setbkcolor(15);
clearviewport();
Bienvenida();
for(int ciclo=0;ciclo<10;ciclo++)
{
    for(cont=1;cont<7;cont++)
    {
        setactivepage(0);
        setvisualpage(1);
        cleardevice();
        Archivo(cont);
    }
}
closegraph();
}
void Bienvenida()
{
    setcolor(BLACK);
    settextstyle(2,0,8);
    outtextxy(40,40,"H");Beep(200,100);delay(500);outtextxy(70,40,"O");Beep(200,100);delay(500);
    outtextxy(100,40,"L");Beep(200,100);delay(500);outtextxy(130,40,"A");Beep(200,100);delay(500);
}
void Archivo(int cont)
{
    int  alto=0, ancho=0, aux=0;
    char nombre[20];
    switch(cont)
    {
    case 1:
            strcpy(nombre,"foto1.txt");     fflush(stdin);      break;  
    case 2:
            strcpy(nombre,"foto2.txt");     fflush(stdin);      break;
    case 3:
            strcpy(nombre,"foto3.txt");     fflush(stdin);      break;
    case 4:
            strcpy(nombre,"foto4.txt");     fflush(stdin);      break;
    case 5:
            strcpy(nombre,"foto5.txt");     fflush(stdin);      break;
    case 6:
            strcpy(nombre,"foto6.txt");     fflush(stdin);      break;
    }
    archivo=fopen(nombre,"r");
        if(archivo==NULL)
        {
            system("CLS");
            gotoxy(20,20);printf("ERROR AL CREAR EL ARCHIVO");
            system("pause");
            return;
        }
    setcolor(BLACK);
    settextstyle(11,0,1);
    //outtextxy(2,690,"¡¡ARCHIVO DE TEXTO ABIERTO CON EXITO!!");
    fscanf(archivo,"%d %d",&alto,&ancho);
    fscanf(archivo,"%d",&aux);
    Llenar(alto, ancho);
}
void Llenar(int alto, int ancho)
{   
    for(int i=0;i<ancho;i++)
    {
        for(int j=0; j<alto;j++)
        {
            int auxR=0, auxG=0,auxB=0;
            fscanf(archivo,"%d %d %d",&auxR,&auxG,&auxB);
            foto[j].RGB[i].Azul=auxB; foto[j].RGB[i].Rojo=auxR; foto[j].RGB[i].Verde=auxG;
        }
    }
    fotograma(alto,ancho);
}
void fotograma(int alto, int ancho)
{   
    for(int i=0;i<ancho;i++)
    {
        for(int j=0; j<alto;j++)
        {
        putpixel(j+20,i+20,COLOR(foto[j].RGB[i].Rojo,foto[j].RGB[i].Verde,foto[j].RGB[i].Azul));
        }
    }
fclose(archivo);
}
    
asked by LordOfDreams 30.11.2017 в 05:48
source

1 answer

3

To control how a graph is displayed on screen you must first understand the concept of Frames per second , copy of wikipedia :

  

Frames per second , also called refresh rate , images per second , frames per second , FPS (from English "frames per second") or framerate , is the speed (rate) at which a device displays images called frames or frames .

That is, the refresh of the graphics on the screen will be linked to the speed that your program refreshes the visual data.

Proposal.

Forget delay , and make your images always be painted, the image to be painted will depend on the animation you are painting, to control it create a animacion object that stores the frame count, its refresh rate and the moment when the animation started:

typedef struct animacion
{
    unsigned fotogramas;
    unsigned refresco;
    clock_t inicio;
};

With this animation object you can calculate which frame you should paint depending on when the animation started. For example, an animation of 8 frames to a frame every two seconds would have a animacion object like this:

struct animacion a;
a.fotogramas = 8;
a.refresco = 2000; // tiempo expresado en milisegundos
a.inicio = clock();

To calculate in which frame of the animation you are, you will do it based on when the animation started:

int fotograma_actual(struct animacion *p_animacion)
{
    long tiempo_transcurrido = clock() - p_animacion->inicio();
    return (int)tiempo_transcurrido / p_animacion->refresco;
}

The fotograma_actual function makes an entire division between the time elapsed since the start of the animation and the refresh rate of the animation, following our example:

  • If 0.5 seconds have elapsed since the start of the animation, the frame is 500 / 2000 which is 0 (the first frame).
  • If 1,367 seconds have elapsed since the start of the animation, the frame is 1367 / 2000 that is 0 (the first frame).
  • If 3,442 seconds have elapsed since the start of the animation, the frame is 3442 / 2000 that is 1 (the second frame).
  • If 13 seconds have elapsed since the start of the animation, the frame is 13000 / 2000 which is 6 (the seventh frame).
  • If 57.31 seconds have elapsed since the start of the animation, the frame is 57310 / 2000 that is 28 (the twenty-ninth frame).

As you can see, we can get results beyond the frames allowed by the animation, it will depend on you to decide what to do in those cases, if the frame is larger than the frames of the animation you should consider the finished animation, but if you want show the animation in loop you can keep the remainder of dividing the frame obtained by the number of frames:

struct animacion a;
a.fotogramas = 8;
a.refresco = 2000; // tiempo expresado en milisegundos
a.inicio = clock();

while(1)
{
    int fotograma = fotograma_actual(&a) % a.fotogramas;
    // pintar fotograma
}
    
answered by 30.11.2017 / 17:56
source