????????????【聲明和備注】本例子屬于轉載來源于《C高級實用程序設計》(王士元,清華大學出版社)第11章,菜單設計與動畫技術,第11.5節,一個動畫例子。
????????????本例講解的是在一個繁星背景下,一個由經緯線組成的藍色地球,并環繞有紅色光環,一藍色宇宙飛船從左至右緩緩飛過,周而復始,給人一種遨游太空的神秘感。本例屬于C語言圖形程序,使用 Turbo C 2.0 編譯。本來我想貼到 BCCN 論壇,無奈該論壇掛了,無法登錄。所以暫且就貼到自己的 BLOG 上了。
????????????這個例子采用的基本技術主要是 TC 提供的圖形函數,動畫部分是采用了 getimage 和 putimage 函數,并使用 XOR 方式合成到屏幕上實現“擦除”和“更新”的動畫效果。我調整了原范例中的函數命名和可能是屬于印刷錯誤的錯誤。
????????????源代碼如下:
?


/**************************************
?*?<<C高級實用程序>>(王士元)Page?324
?*
?*?????????????人造衛星環繞地球運行圖
?*
?*????2009.05.27?00:35
?**************************************/
?
#include?<graphics.h>
#include?<stdlib.h>
#include?<stdio.h>
#include?<conio.h>
/*#include?<cpyscr.h>*/
#define?IMAGE_SIZE?10
void?draw_image(int?x,?int?y);
void?putstar(void);
void?main()
{
????int?graphdriver?=?DETECT;
????int?graphmode,?color;
????void?*pt_addr;
????int?x,?y,?maxx,?maxy,?midy,?midx,?i;
????unsigned?int?size;
????registerbgidriver(EGAVGA_driver);
????registerbgifont(TRIPLEX_FONT);
????initgraph(&graphdriver,?&graphmode,?"C:\\TC\\");
????maxx?=?getmaxx();
????maxy?=?getmaxy();
????midx?=?maxx/2;
????x?=?0;
????midy?=?y?=?maxy/2;
????setcolor(YELLOW);
????settextstyle(TRIPLEX_FONT,?HORIZ_DIR,?4);
????settextjustify(CENTER_TEXT,?CENTER_TEXT);
????outtextxy(midx,?400,?"AROUND?THE?WORLD");
????setbkcolor(BLACK);
????setcolor(RED);
????setlinestyle(SOLID_LINE,?0,?THICK_WIDTH);
????ellipse(midx,?midy,?130,?50,?160,?30);
????setlinestyle(SOLID_LINE,?0,?NORM_WIDTH);
????draw_image(x,?y);????/*畫飛船*/
????size?=?imagesize(x,?y?-?IMAGE_SIZE,
????????x?+?(4?*?IMAGE_SIZE),?y?+?IMAGE_SIZE);
????pt_addr?=?malloc(size);
????getimage(x,?y?-?IMAGE_SIZE,
????????x?+?(4?*?IMAGE_SIZE),?y?+?IMAGE_SIZE,?pt_addr);
????putstar();????/*畫星星*/
????setcolor(WHITE);
????setlinestyle(SOLID_LINE,?0,?NORM_WIDTH);
????rectangle(1,?1,?maxx?-?1,?maxy?-?1);?/*畫方框*/
????while(?!kbhit()?)
????{
????????putstar();
????????setcolor(RED);
????????setlinestyle(SOLID_LINE,?0,?THICK_WIDTH);
????????ellipse(midx,?midy,?130,?50,?160,?30);
????????setcolor(BLACK);?/*畫一個圍繞地球的光環*/
????????ellipse(midx,?midy,?130,?50,?160,?30);
????????for(i?=?0;?i?<=?13;?i++)
????????{
????????????setcolor(i?%?2?==?0???LIGHTBLUE?:?BLACK);
????????????ellipse(midx,?midy,?0,?360,?100,?100?-?8?*?i);?/*畫地球*/
????????????setcolor(LIGHTBLUE);
????????????ellipse(midx,?midy,?0,?360,?100?-?8?*?i,?100);
????????}
????????putimage(x,?y?-?IMAGE_SIZE,?pt_addr,?XOR_PUT);?/*恢復原畫面*/
????????x?=?x?>=?maxx???0?:?x+6;
????????putimage(x,?y?-?IMAGE_SIZE,?pt_addr,?XOR_PUT);?/*在另一位置顯示飛船*/
????}
????/*CopyScreen("c:\\demo.bmp",?0,?0,?maxx,?maxy);*/
????free(pt_addr);????/*釋放緩沖區*/
????closegraph();
????return;
}
void?draw_image(int?x,?int?y)?/*畫飛船*/
{
????int?arw[8];?/*梯形飛船本體*/
????arw[0]?=?x?+?10;?arw[1]?=?y?-?10;
????arw[2]?=?x?+?34;?arw[3]?=?y?-?6;
????arw[4]?=?x?+?34;?arw[5]?=?y?+?6;
????arw[6]?=?x?+?10;?arw[7]?=?y?+?10;
????setcolor(14);
????moveto(x?+?10,?y?-?4);????/*上面飛船尾巴*/
????linerel(-30,?-16);
????moveto(x?+?10,?y);????????????/*中間飛船尾巴*/
????linerel(-30,?0);
????moveto(x?+?10,?y?+?4);????/*下面飛船尾巴*/
????linerel(-30,?16);
????setcolor(3);????????????????????????/*畫飛船本體*/
????setfillstyle(1,?LIGHTBLUE);
????fillpoly(4,?arw);
}
void?putstar(void)????/*畫星星*/
{
????int?seed?=?1858;
????int?i,?dotx,?doty,?h,?w,?color,?maxcolor;
????maxcolor?=?getmaxcolor();?/*最多顏色數*/
????w?=?getmaxx();
????h?=?getmaxy();
????srand(seed);
????for(i?=?0;?i?<?250;?i++)
????{
????????dotx?=?1?+?random(w-1);
????????doty?=?1?+?random(h-1);
????????color?=?random(maxcolor);
????????setcolor(color);
????????putpixel(dotx,?doty,?color);????/*用點表示小星*/
????????circle(dotx?+?1,?doty?+?1,?1);?/*用圓表示大星*/
????}
????srand(seed);
}
?
????????????運行效果截圖如下(使用我自己的截屏函數):
????????????