【声明和备注】本例子属于转载来源于《C高级实用程序设计》(王士元,清华大学出版社)第11章,菜单设计与动画技术,第11.5节,一个动画例子。
本例讲解的是在一个繁星背景下,一个由经纬线组成的蓝色地球,并环绕有红色光环,一蓝色宇宙飞船从左至右缓缓飞过,周而复始,给人一种遨游太空的神秘感。本例属于C语言图形程序,使用 Turbo C 2.0 编译。本来我想贴到 BCCN 论坛,无奈该论坛挂了,无法登录。所以暂且就贴到自己的 BLOG 上了。
这个例子采用的基本技术主要是 TC 提供的图形函数,动画部分是采用了 getimage 和 putimage 函数,并使用 XOR 方式合成到屏幕上实现“擦除”和“更新”的动画效果。我调整了原范例中的函数命名和可能是属于印刷错误的错误。
源代码如下:
Code_Planet.C
/**************************************
* <<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);
}
/**************************************
* <<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);
}
运行效果截图如下(使用我自己的截屏函数):