📄 display.c
字号:
/*=======================Display.c========================*/
/*=====================动画演示文件======================*/
#include"head.h"
void InitGraph()
{
int gd=DETECT,gm;
initgraph(&gd,&gm,"c:\tc\tc");
}
/*--------------画炮台--------------------------------*/
void Emplacement()
{
int x1,y1;
emp.x=rect.left+rect.width/2,emp.y=rect.bottom-31; /*设置炮台中心位置*/
emp.width=60,emp.lenth=40; /*设置炮台大小*/
emp.color=YELLOW; /*炮台边框颜色*/
setfillstyle(1,0);
bar(emp.x-emp.width,emp.y-emp.lenth,emp.x+emp.width,emp.y+emp.lenth);
/*先清除这片区域的背景*/
setcolor(emp.color);
rectangle(emp.x-emp.width,emp.y-emp.lenth,emp.x+emp.width,emp.y+emp.lenth);
rectangle(emp.x-emp.width+10,emp.y-emp.lenth+10,
emp.x+emp.width-10,emp.y+emp.lenth-10);
setfillstyle(1,LIGHTGRAY);
floodfill(emp.x-emp.width+1,emp.y-emp.lenth+1,emp.color); /*填充两个矩形框之间的部分*/
}
/*--------------将整型转化为字符型--------------------*/
void ShowInt(int data,int x,int y)
{
char *s;
sprintf(s,"%d",data);
outtextxy(x,y,s);
}
/*--------------画坦克--------------------------------*/
void DrawTank(struct Target T,int Tcolor,int GunColor)
{
int i,j;
int x=T.x,y=T.y,r=T.r,d,t;
d=r/4;t=d*0.6;
setcolor(Tcolor);
/*------------------*/
line(x-r,y,x+r-t,y);
line(x-r,y,x-r+d,y+2*d);
line(x-r+d,y+2*d,x+3*d,y+2*d);
line(x+3*d,y+2*d,x+r-t,y);
/*----------------------*/
line(x-r,y,x-r+t,y-t);
line(x-r+t,y-t,x-2*d,y-t);
line(x-2*d,y-t,x-2*d+t,y-d-t);
line(x-2*d+t,y-d-t,x-3*d,y-d-t);
line(x-3*d,y-d-t,x-3*d+t,y-2*d);
line(x-3*d+t,y-2*d,x+r-t,y-2*d);
line(x+r-t,y-2*d,x+r-t,y);
/*---------------------------*/
line(x-3*d,y-d-t,x-2*d,y-t);
/*------------------------*/
line(x-r+d-t,y+2*(d-t),x+3*d+r*0.04,y+2*(d-t));
for(i=0;i<2*(r/d-1);i++)
line(x-3*d+i*d,y+2*(d-t),x-3*d+i*d,y+2*d);
/*---------------------------------*/
setfillstyle(1,Tcolor);
bar(x-d*1.2,y-d*0.6,x+d*2,y-d*0.2);
line(x-d*1.2,y-d*0.6,x-d*0.6,y-d*1.8);
line(x-d*0.6,y-d*1.8,x+d*2.4,y-d*1.8);
line(x+d*2.4,y-d*1.8,x+d*2,y-d*0.6);
line(x+d*2.4,y-d*1.8,x+d*2.4,y-d*1.4);
line(x+d*2,y-d*0.2,x+d*2.4,y-d*1.4);
sector(x+d*0.6,y-d,0,180,d*1.2,d*1.4);
for(i=0;i<d*0.3;i++)
line(x+d*0.2,y-d*1.8+i,x-d*2.5,y-d*1.8+i);
setfillstyle(1,GunColor); /*用颜色GunColor画炮头*/
bar(x-d*3,y-d*1.9,x-d*2.3,y-d*1.3);
setcolor(Tcolor);
ShowInt(T.ID,x,y-3*d-t); /*显示该坦克的编号*/
}
/*--------------演示背景框的绘制------------------*/
void DisplayBG()
{
int i;
/*--------画演示矩形框----------*/
setbkcolor(0);
setcolor(LIGHTGRAY);
rect.width=600;
rect.height=450;
rect.d=70;
rect.left=30;
rect.top=20;
rect.right=rect.left+rect.width;
rect.bottom=rect.top+rect.height;
rectangle(rect.left,rect.top,rect.right,rect.bottom);
rectangle(rect.left-10,rect.top-10,rect.right+10,rect.bottom+10);
setfillstyle(1,LIGHTGRAY);
floodfill(rect.left-1,rect.top-2,LIGHTGRAY);
/*--------画炮台----------------*/
Emplacement();
}
/*--------------------初始化目标并显示-------------------*/
void InitTarget()
{
int i,t;
randomize();
for(i=0;i<n;i++) /*给n辆坦克各成员变量预先赋初值*/
{
Tank[i].color=color[random(3)];
/*从预先定义的三种颜色中随机产生一种赋给该坦克*/
Tank[i].r=20; /*坦克半径均设为20(当然也可设为不同的值)*/
Tank[i].x=rect.left+Tank[i].r+random(rect.width-2*Tank[i].r);
/*坦克初始x坐标为在矩形框范围内一随机的坐标*/
Tank[i].y=rect.top+Tank[i].r+random(rect.height-2*emp.lenth-2*Tank[i].r);
/*坦克y坐标范围为矩形框内炮台之上的任意值*/
Tank[i].ID=i+1; /*坦克标识符ID值为从1号依次递增*/
t=random(2);
/*随机产生初始方向值。由于方向值没有0,且关于0对称,
因而采用如下方式来随机产生*/
if(t==0) Tank[i].direction=1+random(4); /*产生正的方向值*/
else
Tank[i].direction=0-(1+random(4)); /*产生负的方向值*/
DrawTank(Tank[i],Tank[i].color,RED); /*显示该坦克*/
}
}
/*----------------画初始星空背景------------------------*/
void DrawStarBG()
{
int i,pixel_x,pixel_y;
for(i=0;i<100;i++) /*初始状态下共随机产生100个点*/
{
/*如果产生的该坐标位于大本营区域内,则重新产生一个坐标,
直到位于大本营区域外*/
do
{ /*在演示矩形框内随机产生坐标点*/
pixel_x=rect.left+10+random(rect.width-20);
pixel_y=rect.top+10+random(rect.height-20);
}while((pixel_x>emp.x-emp.width) && (pixel_x<emp.x+emp.width)
&& (pixel_y>emp.y-emp.lenth));
putpixel(pixel_x,pixel_y,StarColor); /*在产生的坐标处画一个点*/
}
}
/*----------------在坐标(x,y)处画闪烁的星的图案------------------------*/
void DrawShineStar(int x,int y,int i,int color)
{
setcolor(color);
line(x+i,y-i,x+4*i,y);
line(x+i,y-i,x,y-4*i);
line(x-i,y-i,x-4*i,y);
line(x-i,y-i,x,y-4*i);
line(x+i,y+i,x+4*i,y);
line(x+i,y+i,x,y+4*i);
line(x-i,y+i,x-4*i,y);
line(x-i,y+i,x,y+4*i);
}
/*----------------在坐标(x,y)处的闪烁效果------------------------------*/
void Shine()
{
int i,r=2,x,y;
do
{ /*在演示矩形框内随机产生坐标点*/
x=rect.left+10+random(rect.width-20);
y=rect.top+10+random(rect.height-20);
}while((x>emp.x-emp.width-15) && (x<emp.x+emp.width+15)
&& (y>emp.y-emp.lenth-15));
/*如果产生的该坐标位于大本营区域内,则重新产生一个坐标,
直到位于大本营区域外*/
for(i=0;i<r;i++)
{
/*由小到大画闪烁的星图,i代表该图的一个基本单位*/
DrawShineStar(x,y,i,StarColor);
delay(3000);
DrawShineStar(x,y,i,DisplayColor); /*延时后再将原星图用背景色清除*/
}
for(i=r;i>=0;i--)
{
/*再从大到小画闪烁的星图*/
DrawShineStar(x,y,i,StarColor);
delay(3000);
DrawShineStar(x,y,i,DisplayColor);
}
/*闪烁之后在该坐标处画一个点*/
putpixel(x,y,StarColor);
}
/*---------------决定当前坦克是否按当前方向值运动,或是碰到边框而须改变方向-------*/
int IsXYValid(struct Target T,int x,int y)
{
int i;
/*以下为预先判断改变后的坐标是否位于演示矩形框内*/
if((x>rect.left+T.r) && (x<rect.right-T.r) &&
(y>rect.top+T.r) && (y<rect.bottom-T.r*5/6)) /*如果位于演示矩形框内*/
{
if((x+T.r<emp.x-emp.width) || (x-T.r>emp.x+emp.width) ||
(y+T.r<emp.y-emp.lenth)) /*如果未碰到大本营边框*/
{
/*则表示可以向该方向运动,在这个新的位置画出该坦克*/
return 1; /*函数返回1*/
}
else /*否则,如果碰到大本营边框,则函数返回0*/
return 0;
}
else /*否则,如果碰到演示矩形边框,则函数返回0*/
return 0;
}
/*--------------锁定目标的效果-------------------------*/
int Lock(struct Target T)
{
int i,r=T.r,x,y;
int s;
char ch;
s=r/4;
for(i=0;i<3;i++)
circle(T.x,T.y,r+i);
line(T.x-r-2*s,T.y,T.x+r+2*s,T.y);
line(T.x,T.y-r-2*s,T.x,T.y+r+2*s);
line(T.x+r+2*s,T.y,T.x+r+2*s-5,T.y-5);
line(T.x+r+2*s,T.y,T.x+r+2*s-5,T.y+5);
line(T.x,T.y-r-2*s,T.x-5,T.y-r-2*s+5);
line(T.x,T.y-r-2*s,T.x+5,T.y-r-2*s+5);
while(1) /*显示目标闪烁效果,并等待用户按键*/
{
if(kbhit())
{
ch=getch();
if(ch==Enter)
return 1; /*如果按Enter键则开始攻击*/
if(ch==ESC)
return 0; /*如果按ESC键则取消此次攻击*/
}
DrawTank(Tank[best],DisplayColor,DisplayColor);
delay(30000);
DrawTank(Tank[best],Tank[best].color,LockColor);
delay(30000);
}
}
/*--------------绘制导弹---------------------------*/
void DrawMissile(int x,int y,int r,int color)
{
int i;
setcolor(color);
for(i=0;i<r;i++)
circle(x,y,i);
}
/*---------------攻击效果-------------------------*/
void Attack(int x1,int y1,int x2,int y2)
{
int i,size,trackColor,missileR,missileColor=WHITE;
int x,y;
void *buf;
x=x1;
y=y1;
missileR=5;
trackColor=BLUE;
setcolor(trackColor);
line(x1,y1,x2,y2);
if(y1==y2)
while(x!=x2)
{
size=imagesize(x-100,y-missileR,x+100,y+missileR);
buf=malloc(size);
getimage(x-100,y-missileR,x+100,y+missileR,buf);
DrawMissile(x,y,missileR,missileColor);
delay(3000);
putimage(x-100,y-missileR,buf,COPY_PUT);
if(x>x2)
x--;
else
x++;
free(buf);
}
else
while(y!=y2)
{
size=imagesize(x-100,y-missileR,x+100,y+missileR);
buf=malloc(size);
getimage(x-100,y-missileR,x+100,y+missileR,buf);
for(i=-50;i<=50;i++)
if(getpixel(x+i,y)==trackColor)
{
DrawMissile(x+i,y,missileR,missileColor);
delay(3000);
putimage(x-100,y-missileR,buf,COPY_PUT);
x=x+i;
break;
}
if(y>y2)
y--;
else
y++;
free(buf);
}
}
/*---------------爆炸效果----------------------------*/
void Blast(int x,int y,int r,int color)
{
int i,j;
for(i=0;i<r;i++)
{
for(j=0;j<i;j++)
{
DrawShineStar(x,y,j,color);
delay(10000);
DrawShineStar(x,y,j,DisplayColor);
}
delay(1000);
}
}
/*----------------动画演示函数--------------------------*/
void Display()
{
int i,t,x,y;
int count=0;
char ch;
DisplayBG();
DrawStarBG();
InitTarget();
Repeat:
while(1)
{
if(kbhit()) /*如果用户按Enter键则锁定目标*/
{
ch=getch();
if(ch==Enter)
break;
}
/*以下是显示星空闪现效果*/
count++; /*循环的次数*/
if((count=count%5)==0) /*如果循环次数正好是5的倍数,则*/
{
if(random(5)==1) /*如果产生的随机数恰好等于1*/
Shine(); /*那么闪烁一次*/
}
/*各目标按照预定的当前方向运动*/
for(i=0;i<n;i++)
{
l1:
x=Tank[i].x; /*首先保留原目标的坐标而用x,y代替*/
y=Tank[i].y;
switch(Tank[i].direction) /*根据当前方向值来试着改变坐标*/
{
/*以下是根据八个方向来改变坐标值*/
case -1: x--;break;
case 1: x++;break;
case -2: y--;break;
case 2: y++;break;
case -3: x--; y--;break;
case 3: x++; y++; break;
case -4: x--; y++;break;
case 4: x++; y--;break;
default: break;
}
/*尝试改变后,如果改变后的坐标未超过边界,则在新的坐标处显示该目标,
并擦去原坐标点的目标。同时将改变后的坐标作为该目标的新的当前坐标*/
if(IsXYValid(Tank[i],x,y)) /*如果坐标合法,则在新的坐标处画该坦克*/
{
DrawTank(Tank[i],DisplayColor,DisplayColor);
Tank[i].x=x;
Tank[i].y=y;
DrawTank(Tank[i],Tank[i].color,GunColor);
delay(100);
}
else
{/*否则,重新产生一个方向值,并返回根据新的方向值重新尝试改变坐标*/
t=random(2);
if(t==0)
Tank[i].direction=1+random(4);
else
Tank[i].direction=0-(1+random(4));
goto l1;
}
}
}
/*在此添加寻最优目标的算法调用*/
if(Lock(Tank[best])==0)/*表示用户按了ESC键,则取消此次攻击,返回到多目标动态显示的画面*/
goto Repeat;
Attack(emp.x,emp.y,Tank[best].x,Tank[best].y);
Blast(Tank[best].x,Tank[best].y,Tank[best].r,LockColor);
setcolor(DisplayColor);
line(emp.x,emp.y,Tank[best].x,Tank[best].y);
setfillstyle(1,DisplayColor);
bar(Tank[best].x-Tank[best].r*4,Tank[best].y-Tank[best].r*4,Tank[best].x+Tank[best].r*4,
Tank[best].y+Tank[best].r*4);
DisplayBG();
for(i=0;i<n;i++)
{
if(i==best)
continue;
DrawTank(Tank[i],Tank[i].color,GunColor);
}
}
/*---------------主函数-------------------------------*/
main()
{
int i;
InitGraph();
Display();
getch();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -