Во-первых спасибо всем за активное участие в теме.
Во-вторых в хелпе я нашел функции для работы со страницами:
setactivepage(int)
setvisualpage(int)
и попытался их использовать, вот что получилось
#include <dos.h>
#include <time.h>
#include <math.h>
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
class TPoint
{
public:
TPoint(int ax,int ay,int c,int dd):
x(ax),y(ay),color(c),dl(dd)
{
init();
GetKoords();
dx = 20;
dy = 20;
};
TPoint()
{
randomize();
x=random(xmax);
y=random(ymax);
color=random(getmaxcolor());
dl=5;
init();
GetKoords();
dx = 20;
dy = 20;
};
int GetColor() const
{
return color;
};
void SetColor(int c)
{
color=c;
};
void GetPos(int &xp,int &yp) const
{
xp=x;
yp=y;
};
void SetPos(int xp,int yp)
{
x=xp;
y=yp;
};
void Fly3();
void Fly1();
virtual void Show() const
{
putpixel(x,y,color);
};
virtual void Hide()
{
putpixel(x,y,bgcolor);
};
int xmax,ymax,bgcolor;
struct koords
{
int x2,y2,rp,r,w,h,sh,i;
}k;
protected:
void init();
int x,y,color,dl;
int dx,dy;
void GetKoords();
virtual void MoveTo(int nx,int ny);
struct arccoordstype arcinfo;
private:
};
/*------------------------------------------------------*/
void TPoint::init()
{
int gdriver=VGA,gmode=VGAMED,errorcode;
if (getgraphmode()!=2)
{
// detectgraph(&gdriver,&gmode);
initgraph(&gdriver,&gmode,""); //EGAVGA.BGI must be in same directory
errorcode=graphresult();
if (errorcode!=grOk)
{
printf("Graph error:%s\n",grapherrormsg(errorcode));
getch();
exit(1);
}
}
bgcolor=0;
xmax=getmaxx();
ymax=getmaxy();
setcolor(bgcolor);
};
/*------------------------------------------------------*/
void TPoint::MoveTo(int nx,int ny)
{
if (nx<0) {nx=0; dx=-dx;}
else if (nx>xmax) {nx=xmax; dx=-dx;}
if (ny<0) {ny=0; dy = -dy;}
else if (ny>ymax) {ny=ymax; dy = -dy;}
putpixel(x,y,0); /* off for proc1 */
x=nx;y=ny;
putpixel(x,y,color);
delay(dl);
};
/*------------------------------------------------------*/
void TPoint::Fly1()
{
int nx,ny;
dx = dx + random(3)-1;
dy = dy + random(3)-1;
nx = x+dx;
ny = y+dy;
MoveTo(nx,ny);
}
/*-----------------------------------------*/
void TPoint::Fly3()
{
int d;
if (k.w)
k.rp+=k.sh;
else
k.r+=k.sh;
d=k.w*k.sh-(k.w-1);
setcolor(0);
arc(k.x2, k.y2, k.rp, k.rp+d, k.r);
getarccoords(&arcinfo);
MoveTo(arcinfo.xend,arcinfo.yend);
if (++k.i > k.h) GetKoords();
};
/*------------------------------------------------------*/
void TPoint::GetKoords()
{
k.r=random(130)+10;
k.rp=random(340)+20;
setcolor(0);
arc(x,y,0,k.rp,k.r);
setcolor(0);
getarccoords(&arcinfo);
k.x2=arcinfo.xend;
k.y2=arcinfo.yend;
k.rp-=180;
if (x==k.x2)
if(y>k.y2) k.rp=-90;
else k.rp=90;
if (y==k.y2)
if(x>k.x2) k.rp=0;
else k.rp=180;
k.w=random(2);
k.sh=pow(-1,random(2));
if (k.w)
k.h=random(150)+20;
else
if (k.sh<0)
k.h=random(k.r);
else
k.h=random(180)+20;
k.i=0;
}
/*-----------------------------------------------*
* *
* Circle *
* *
*------------------------------------------------*/
class TCircle : public TPoint
{
public:
TCircle(int ax,int ay,int c,int d,int r) :
TPoint(ax,ay,c,d), rd(r){};
TCircle();
~TCircle()
{
// free(pic);
Hide();
};
void MoveTo(int nx,int ny);
void Show() const;
void Hide();
protected:
void GetPic();
int rd;
private:
void *pic;
unsigned int size;
};
/*------------------------------------------------------*/
TCircle::TCircle()
{
rd=random(50)+10;
dl=0;
x=random(xmax-2*rd)+rd;
y=random(ymax-2*rd)+rd;
// GetPic();
};
/*------------------------------------------------------*/
void TCircle::GetPic()
{
Show();
size = imagesize(x-rd,y-rd,x+rd,y+rd);
pic = malloc(size);
getimage(x-rd,y-rd,x+rd,y+rd,pic);
Hide();
};
/*------------------------------------------------------*/
void TCircle::Show() const
{
setfillstyle(1,color);
fillellipse(x,y,rd,rd);
};
/*------------------------------------------------------*/
void TCircle::Hide()
{
setfillstyle(1,0);
fillellipse(x,y,rd,rd);
};
/*------------------------------------------------------*/
void TCircle::MoveTo(int nx,int ny)
{
if (nx<rd) {nx=rd; dx=-dx;}
else if (nx>xmax-rd) {nx=xmax-rd; dx=-dx;}
if (ny<rd) {ny=rd; dy = -dy;}
else if (ny>ymax-rd) {ny=ymax-rd; dy = -dy;}
/* if (nx<rd) nx=rd;
else if (nx>xmax-rd) nx=xmax-rd;
if (ny<rd) ny=rd;
else if (ny>ymax-rd) ny=ymax-rd;*/
setcolor(0);
Hide();
SetPos(nx,ny);
Show();
delay(dl);
}
/*------------------------------------------------------*/
class TSqare : public TPoint
{
public:
TSqare(int ax,int ay,int c,int ld,int dd) :
TPoint(ax,ay,c,ld) ,d(dd){};
TSqare();
void MoveTo(int nx,int ny);
void Show() const;
void Hide();
private:
int d;
};
/*------------------------------------------------------*/
TSqare::TSqare()
{
d=random(50)+10;
dl=0;
x=random(xmax-2*d)+d;
y=random(ymax-2*d)+d;
// GetPic();
};
/*------------------------------------------------------*/
void TSqare::Show() const
{
setcolor(color);
rectangle(x-d,y-d,x+d,y+d);
setfillstyle(1,color);
floodfill(x,y,color);
};
/*------------------------------------------------------*/
void TSqare::Hide()
{
setcolor(0);
setfillstyle(1,bgcolor);
floodfill(x,y,bgcolor);
};
/*------------------------------------------------------*/
void TSqare::MoveTo(int nx,int ny)
{
if (nx<d) {nx=d; dx=-dx;}
else if (nx>xmax-d) {nx=xmax-d; dx=-dx;}
if (ny<d) {ny=d; dy = -dy;}
else if (ny>ymax-d) {ny=ymax-d; dy = -dy;}
/* if (nx<d) nx=d;
else if (nx>xmax-d) nx=xmax-d;
if (ny<d) ny=d;
else if (ny>ymax-d) ny=ymax-d;*/
setcolor(0);
Hide();
SetPos(nx,ny);
Show();
delay(dl);
}
/*------------------------------------------------------*/
class TRing : public TCircle
{
public:
TRing(int ax,int ay,int c,int d,int r,int rmin) :
TCircle(ax,ay,c,d,r), rm(rmin) { };
TRing();
void MoveTo(int nx,int ny);
void Show() const;
void Hide();
private:
int rm;
};
/*------------------------------------------------------*/
TRing::TRing()
{
rd=random(50)+10;
rm=random(50)+10;
dl=0;
x=random(xmax-2*rd)+rd;
y=random(ymax-2*rd)+rd;
// GetPic();
};
/*------------------------------------------------------*/
void TRing::Show() const
{
setfillstyle(1,color);
fillellipse(x,y,rd,rd);
setfillstyle(1,0);
fillellipse(x,y,rm,rm);
};
/*------------------------------------------------------*/
void TRing::Hide()
{
setfillstyle(1,0);
fillellipse(x,y,rd,rd);
};
/*------------------------------------------------------*/
void TRing::MoveTo(int nx,int ny)
{
if (nx<rd) {nx=rd; dx=-dx;}
else if (nx>xmax-rd) {nx=xmax-rd; dx=-dx;}
if (ny<rd) {ny=rd; dy = -dy;}
else if (ny>ymax-rd) {ny=ymax-rd; dy = -dy;}
/* if (nx<rd) nx=rd;
else if (nx>xmax-rd) nx=xmax-rd;
if (ny<rd) ny=rd;
else if (ny>ymax-rd) ny=ymax-rd;*/
setcolor(0);
Hide();
SetPos(nx,ny);
Show();
delay(dl);
}
/*------------------------------------------------------*/
#include "grobj2.cpp"
void main()
{ // x y c dl rd rm
TPoint t(20 , 24 , 1, 0);
TCircle c(320, 240, 2, 0, 20);
TCircle d(30 , 220, 4, 0, 20);
TSqare q(120, 140, 7, 0, 20);
TRing r(220, 20 , 5, 0, 20, 10);
// directvideo=1;
setcolor(0);
int p=0;
randomize();
for(int i=0;i<2000;i++)
{
setactivepage(!p);
setvisualpage(p);
p = !p;
c.Fly3();
// delay(5);
// d.Fly3();
// t.Fly3();
// q.Fly3();
// r.Fly3();
}
getch();
closegraph();
}
Но драйвера и режимы которые поддерживают многостраничность (точнее всего 2 страницы) имеют разрешение
экрана 640*350, видимо поэтому фигуры изменились (круг стал похож на эллипс) и почему-то перестали правильно стираться.
В основном же анимация стала более плавной (перерисовки менее заметны), правда иногда по фигуре проскакивают широкие черные полосы (горизонтальные).
Я не уверен правильнл ли я испольэую переключнеие страниц, может надо как-то подругому?
(EXEшник во вложенми)