VC6.0简单绘图说明.doc_第1页
VC6.0简单绘图说明.doc_第2页
VC6.0简单绘图说明.doc_第3页
VC6.0简单绘图说明.doc_第4页
VC6.0简单绘图说明.doc_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第二章 VC6.0简单绘图说明许多学编程的都是从 C 语言开始入门的,而目前的现状是:有些学校以 Turbo C 为环境讲 C 语言,只是 Turbo C 的环境实在太老了,复制粘贴都很不方便。有些学校直接拿 VC 来讲 C 语言,因为 VC 的编辑和调试环境都很优秀,并且 VC 有适合教学的免费版本。可惜在 VC 下只能做一些文字性的练习题,想画条直线画个圆都很难,还要注册窗口类、建消息循环等等,初学者会受严重打击的。初学编程想要绘图就得用 TC,很是无奈。 还有计算机图形学,这门课程的重点是绘图算法,而不是 Windows 编程。所以,许多老师不得不用 TC 教学,因为 Windows 绘图太复杂了,会偏离教学的重点。新的图形学的书有不少是用的 OpenGL,可是门槛依然很高。要给初学者一个简单的学习平台,就要VC的开发平台和TC的简单的绘图功能,于是就有了这个 EasyX 库,我们需要在VC下下载安装EasyX库,下载地址:http://。下面是VC下简单绘图函数的基本说明。1. 系统支持操作系统版本:Windows 2000 及以上系统。编译环境版本:Visual C+ 6.0 / 2008(x86 & x64) / 2010(x86 & x64)。2. 安装请先将下载的压缩包解压缩,然后执行 Setup.hta,并跟随提示安装。安装程序会检测已经安装的 VC 版本,并根据选择将对应的 .h 和 .lib 文件安装至 VC 的 include 和 lib 文件夹内。安装程序不会修改注册表或者本机的任何文件。如果需要手动安装,请根据下面的文件列表说明将安装包里的相关文件分别复制到 VC 对应的 include 和 lib 文件夹内,或者将 include 和 lib 文件夹放到任意位置,然后修改 VC 中的 Lib 和 Include 的引用路径。3. 卸载由于安装程序并不改写注册表,因此在“添加删除程序”中不会看到 EasyX 的卸载项。如需卸载,请执行相应版本的 Setup.hta,并根据提示卸载4. 文件列表说明下载的压缩包里文件列表及对应说明如下:压缩包 include graphics.h/* 程序需要引用的头文件*/ lib amd64 graphicsw.lib /* VC2008 / VC2010 MBCS 库文件(x64) */ graphicswu.lib/* VC2008 / VC2010 Unicode 库文件(x64) */ graphics.lib/* VC6 MBCS 库文件*/ graphicsu.lib /* VC6 Unicode 库文件*/ graphicsw.lib /* VC2008 / VC2010 MBCS 库文件(x86) */ graphicswu.lib/* VC2008 / VC2010 Unicode 库文件(x86) */ EasyX_Help.chm/* 帮助文件*/ Setup.hta /* 安装程序项目依赖*/使用上,基本和 Turbo C 没太大区别。启动 Visual C+,创建一个控制台项目(Win32 Console Application),然后添加一个新的代码文件(.cpp),并引用 graphics.h 头文件就可以了。来看一个简单例子:【例2-1】画一个圆。#include /* 就是需要引用这个图形库*/#include void main() initgraph(640, 480); /* 这里和 TC 略有区别*/ circle(200, 200, 100); /* 画圆,圆心(200, 200),半径 100*/ getch(); /* 按任意键继续*/ closegraph(); /* 关闭图形界面*/TC绘图有不少区别的,比如颜色上,TC 只有 16 色,而这个库支持了真彩色。还有,这个库增加了鼠标、批量绘图、读取图片(点阵或矢量)等功能。2.1几个基本概念1. 颜色EasyX 使用 24bit 真彩色,不再支持调色板模式。表示颜色有以下几种办法:1) 用预定义颜色常量,如下表所示:常量值颜色常量值颜色BLACK0黑DARKGRAY0x545454深灰BLUE0xA80000蓝LIGHTBLUE0xFC5454亮蓝GREEN0x00A800绿LIGHTGREEN0x54FC54亮绿CYAN0xA8A800青LIGHTCYAN0xFCFC54亮青RED0x0000A8红LIGHTRED0x5454FC亮红MAGENTA0xA800A8紫LIGHTMAGENTA0xFC54FC亮紫BROWN0x0054A8棕YELLOW0x54FCFC黄LIGHTGRAY0xA8A8A8浅灰WHITE0xFCFCFC白表 21预定义颜色常量2) 用 16 进制的颜色表示,形式为:0xbbggrr (bb=蓝,gg=绿,rr=红)3) 用 RGB 宏合成颜色。详见 RGB。4) 用 HSLtoRGB、HSVtoRGB 转换其它色彩模型到 RGB 颜色。详见 HSLtoRGB、HSVtoRGB。以下是部分设置前景色的方法:setcolor(0xff0000);setcolor(BLUE);setcolor(RGB(0, 0, 255);setcolor(HSLtoRGB(240, 1, 0.5);2. 坐标在 EasyX 中,坐标分两种:逻辑坐标和物理坐标。1) 逻辑坐标逻辑坐标是在程序中用于绘图的坐标体系。坐标默认的原点在屏幕的左上角,X 轴向右为正,Y 轴向下为正,度量单位是像素。坐标原点可以通过 setorigin() 函数修改;坐标轴方向可以通过 setaspectratio() 函数修改;缩放比例可以通过 setaspectratio() 函数修改。在本书中,凡是没有注明的坐标,均指逻辑坐标。2) 物理坐标物理坐标是描述设备的坐标体系。坐标原点在屏幕的左上角,X 轴向右为正,Y 轴向下为正,度量单位是像素。坐标原点,坐标轴方向,缩放比例都不能改变。3. 设备所谓“设备”,简单来说,就是绘图表面。在 EasyX 中,设备分两种,一种是默认的绘图窗口,另一种是 IMAGE 对象。通过 SetWorkingImage() 函数可以设置当前用于绘图的设备。设置当前用于绘图的设备后,所有的绘图函数都会绘制在该设备上。2.2函数说明EasyX 函数共分以下几大类:1. 绘图环境相关函数;2. 颜色表示及相关函数;3. 绘制图形相关函数;4. 文字输出相关函数;5. 图像处理相关函数;6. 鼠标相关函数;7. 其它函数。函数的详细说明详见附录A。2.3简单绘图【例2-2】实现一个简单绘图。#include /* 绘图库头文件,绘图语句需要*/#include /* 控制台输入输出头文件,getch()语句需要*/void main()initgraph(640, 480);/* 初始化640x480的绘图屏幕*/line(200, 240, 440, 240);/* 画线(200,240) - (440,240) */line(320, 120, 320, 360);/* 画线(320,120) - (320,360) */getch();/* 按任意键*/closegraph();/* 关闭绘图屏幕*/说明:1. 创建的绘图屏幕640x480,表示横向有640个点,纵向有480个点。注意:左上角是原点(0,0),也就是说,y轴和数学的y轴是相反的。2. getch实现按任意键功能,按任意键后,程序继续执行。否则,程序会立刻执行closegraph以至于看不到绘制的内容。【练习题】1) 用线条画出更多的图形,要求不少于10条直线,并熟悉调试过程。2.4常用的绘图语句1. 常用的绘图语句line(x1, y1, x2, y2); /* 画直线 (x1,y1)-(x2,y2),都是整型*/circle(x, y, r); /* 画圆,圆心为(x,y),半径为r*/putpixel(x, y, c); /* 画点(x,y),颜色c*/还有很多,如画椭圆、圆弧、矩形、多边形,等等,请参考2.2节函数说明。2. 设置颜色setcolor(c); /* 设置绘图颜色,如setcolor(RED)设置为红色等*/常用的颜色常量可以用:BLACK 黑 DARKGRAY 深灰 BLUE 蓝 LIGHTBLUE 亮蓝 GREEN 绿 LIGHTGREEN 亮绿 CYAN 青 LIGHTCYAN 亮青 RED 红 LIGHTRED 亮红 MAGENTA 紫 LIGHTMAGENTA 亮紫 BROWN 棕 YELLOW 黄 LIGHTGRAY 浅灰 WHITE 白3. 配出更多的颜色颜色除了前面写的16种以外,还可以自由配色。格式:RGB(r, g, b)r / g / b 分别表示红色、绿色、蓝色,范围都是0255。例如,RGB(255,0,0) 表示纯红色。红色和绿色配成黄色,因此 RGB(255,255,0) 表示黄色。嫌调色麻烦可以用画笔里面的调色试试,调好了以后直接将数值抄过来就行。例如,画两条红色浓度为200的直线,可以写:setcolor(RGB(200,0,0);line(100,100, 200,100);line(100,120, 200,120);4. 用数字表示颜色除了用RGB(r,g,b)方式外,还可以用16进制表示颜色,格式:0xrrggbb例如,setcolor(0xff0000) 和 setcolor(RGB(255,0,0) 是等效的。5. 延时语句这个很简单 Sleep(n) 就可以表示 n 毫秒的延时。例如延时3秒,可以用 Sleep(3000);【练习题】1) 绘制更丰富的图形内容,不低于20行。2) 将延时语句适当的插入上一小节的练习题的代码中,看看执行效果。2.5结合流程控制语句来绘图1. 熟练使用循环语句来控制程序流程。【例2-3】使用for循环语句画10条直线。#include #include void main() initgraph(640, 480); for(int y=100; y200; y+=10) line(100, y, 300, y); getch(); closegraph();【例2-4】修改一下循环的范围和间隔。#include #include void main() initgraph(640, 480); for(int y=0; y256; y+) setcolor(RGB(0,0,y); line(100, y, 300, y); getch(); closegraph();2. 熟练使用判断语句来控制程序流程。【例2-5】配合if语句,实现红色、蓝色交替画线。#include #include void main() initgraph(640, 480); for(int y=100; y200; y+=10) if ( y/10 % 2 = 1) /* 判断奇数行偶数行*/ setcolor(RGB(255,0,0); else setcolor(RGB(0,0,255); line(100, y, 300, y); getch(); closegraph();【练习题】1) 画围棋棋盘。2) 画中国象棋的棋盘3) 画国际象棋的棋盘,看手册找到颜色填充语句,实现过期象棋棋盘的区块填充。2.6数学知识在绘图中的运用数学在绘图中起着重要作用。1. 绘一个全屏的渐变色问题例如,如果需要将将0255的颜色和0479的y轴对应起来:c 表示颜色,范围0255y 表示y轴,范围0479于是:c / 255 = y / 479c = y / 479 * 255 = y * 255 / 479 说明:先算乘法再算除法可以提高精度。【例2-6】绘一个全屏的渐变色。#include #include void main() initgraph(640, 480); int c; for(int y=0; y480; y+) c = y * 255 / 479; setcolor(RGB(0,0,c); line(0, y, 639, y); getch(); closegraph();2. 画一个圆形的渐变色问题首先,我们要用到圆形的基本公式:x*x + y*y = r*r;让弧度从02*3.14,然后需要根据弧度和半径算出(x,y),用pi表示圆周率;用r表示半径;用a表示弧度(小数);用c表示颜色。于是:x=r*cos(a)y=r*sin(a)c=a*255/(2*pi)【例2-7】画一个圆形的渐变色。#include #include #include void main() initgraph(640, 480); int c; double a; int x, y, r=200; for(a=0; aPI*2; a+=0.0001) x=(int)(r*cos(a) + 320 + 0.5); y=(int)(r*sin(a) + 240 + 0.5); c=(int)(a*255/(2*PI) + 0.5); setcolor(RGB(c,0,0); line(320, 240, x, y); getch(); closegraph();2.7实现简单动画所谓动画,其实是连续显示一系列图形而已。结合到程序上,我们需要以下几个步骤:1. 绘制图像;2. 延时;3. 擦掉图像;循环以上即可实现动画。【例2-8】举一个例子,我们实现一条直线从上往下移动。#include #include void main() initgraph(640, 480); for(int y=0; y480; y+) /* 绘制绿色直线*/ setcolor(GREEN); line(0, y, 639, y); Sleep(10); /* 延时*/* 绘制黑色直线(即擦掉之前画的绿线)*/ setcolor(BLACK); line(0, y, 639, y); closegraph();【例2-9】再看一个例子,实现一个圆从左往右跳动。#include #include void main() initgraph(640, 480); for(int x=100; x540; x+=20) /* 绘制黄线、绿色填充的圆*/ setcolor(YELLOW); setfillstyle(GREEN); fillcircle(x, 100, 20); Sleep(500);/* 延时*/ /* 绘制黑线、黑色填充的圆*/ setcolor(BLACK); setfillstyle(BLACK); fillcircle(x, 100, 20); closegraph();说明:移动的间距小、延时短,动画就会越细腻。但当画面较复杂时,会带来画面的闪烁。【练习题】1) 绘制一个沿 45 度移动的球,碰到窗口边界后反弹。2.8捕获按键,实现动画的简单控制最常用的一个捕获按键的函数:getch();前几课,都把这个函数当作“按任意键继续”来用,现在我们用变量保存这个按键:char c = getch();然后再做判断即可。不过程序执行到 getch() 是会阻塞的,直到用户有按键才能继续执行。可游戏中总不能因为等待按键而停止游戏执行吧?所以,要有一个函数,判断是否有用户按键:kbhit()这个函数返回当前是否有用户按键,如果有,再用 getch() 获取即可,这样是不会阻塞的。即:char c;if (kbhit()c = getch();【例2-10】如果有按键,就输出相关按键。否则,输出“.”。每隔 100 毫秒输出一次。按 ESC 退出。注:ESC 的 ASCII 码是 27。#include #include #include void main()char c = 0;while(c != 27)if (kbhit()c = getch();elsec = .;printf(%c, c);Sleep(100);结合上一课的简单动画,就可以做出来靠按键移动的图形了。【例2-11】实现 a s 控制圆的左右移动。#include #include void main()initgraph(640, 480);int x = 320;/* 画初始图形*/setcolor(YELLOW);setfillstyle(GREEN);fillcircle(x, 240, 20);char c;while(c != 27)/* 获取按键*/c = getch();/* 先擦掉上次显示的旧图形*/setcolor(BLACK);setfillstyle(BLACK);fillcircle(x, 240, 20);/* 根据输入,计算新的坐标*/switch(c)case a: x-=2; break;case d: x+=2; break;case 27: break;/* 绘制新的图形*/setcolor(YELLOW);setfillstyle(GREEN);fillcircle(x, 240, 20);/* 延时*/Sleep(10);closegraph();【练习题】请继续完成这个程序,实现以下功能: 1) 上下的控制; 2) 边界检测; 3) 结合 kbhit 实现惯性移动(即按一下方向键,圆就会一直向这个方向移动) 注:上下左右等按键的控制,会返回 2 个字符。由于该系列教程面向初学者,因此有兴趣的请查看 MSDN。2.9用函数简化相同图案的制作实际中有许多类似的图案,如果一一单独绘制,太麻烦。于是,我们需要一个公用的绘制过程,就是函数。例如,我们需要画5个三角形,位于不同的位置。我们可以将绘制单个三角形的过程写成函数,函数内是一个独立的程序段,这个绘制过程很简单。然后,在需要绘制的时候,调用这个函数即可。可以通过参数来解决细微差异(图案的坐标、颜色等)。【例2-12】画5个位于不同位置的三角形。#include #include /* 在坐标 (x,y) 处,用颜色 c 绘制三角形*/void sanjiaoxing(int x, int y, int c) /* 设置画线颜色*/ setcolor(c); /* 画三角形的三条边*/ line(x, y, x+50, y); line(x, y, x, y+50); line(x+50, y, x, y+50);void main() initgraph(640, 480); /* 初始化图形窗口*/ sanjiaoxing(100, 100, RED); sanjiaoxing(120, 160, BLUE); sanjiaoxing(140, 220, GREEN); sanjiaoxing(160, 120, BLUE); sanjiaoxing(160, 160, GREEN); sanjiaoxing(220, 140, GREEN); getch(); /* 按任意键继续*/ closegraph(); /* 关闭图形窗口*/【例2-13】结合循环等控制条件,绘制更复杂漂亮的图案。#include #include void sanjiaoxing(int x, int y, int color) /* 设置画线颜色*/ setcolor(color); /* 画三角形的三条边*/ line(x, y, x+10, y); line(x, y, x, y+10); line(x+10, y, x, y+10);void main() initgraph(640, 480); /* 初始化图形窗口*/ for(int x=0; x640; x+=10) for(int y=0; y480; y+= 10)sanjiaoxing(x, y, RGB(x*255/640, y*255/480, 0); getch(); /* 按任意键继续*/ closegraph(); /* 关闭图形窗口*/运行效果如下图:图21运行效果图【练习题】1) 绘制 Windows 自带游戏“扫雷”的初始界面。2.10绘图中的位运算位运算和绘图有什么关系?先举个例子来个感性认识:使用XOR运算可以实现擦除图形后不破坏背景,这在时钟程序中绘制表针是很有用的。稍后我们会给出这样的例子。1. 位运算的运算法则位运算主要分4种:NOT、AND、OR、XOR位运算的运算对象是二进制数(十进制要转换为二进制,计算机会自动转换)。运算法则如下:1) NOT表示“取反”,将二进制位的1变0、0变1。C语言用符号 表示。如:二进制: 1101 = 0010用十进制表示就是:13 = 22) AND表示“并且”,只有两数的对应二进制位都为1,结果的二进制位才为1;否则,结果的二进制位为0。C语言用符号 & 表示。如:二进制:1101 & 0110 = 0100用十进制表示就是:13 & 6 = 43) OR表示“或者”,两数的对应二进制位只要有一个是1,结果的二进制位就是1;否则,结果的二进制位为0。C语言用符号 | 表示。如:二进制:0101 | 0110 = 0111用十进制表示就是:5 | 6 = 74) XOR表示“异或”,两数的对应二进制位不同,结果的二进制位为1;相同,结果的二进制位为0。C语言用符号 表示。如:二进制:0101 1110 = 1011以上只是简单介绍一下,详细的还是请大家看C语言教程上的讲解。2. 位运算的应用位运算的应用很多,例如 AND 和 OR 在获取和设置标志位时经常使用。更多的,以后大家会逐渐遇到,暂时先记下有这么回事。这里着重说一下 XOR 运算,它有一个重要的特性:(a b) b = a也就是说,a b 之后可能是某些其它数字,但是只要再 b 一下,就又成了 a。一些简单的加密就用的 XOR 的这个特性。至于绘图,假如 a 是背景图案,b 是将要绘制的图案,只要用 XOR 方式绘图,连续绘两次,那么背景是不变的。【例2-14】一个简单的绘图 XOR 运算演示。#include #include void main() initgraph(640, 480); /* 初始化 640 x 480 的绘图窗口*/ setlinestyle(PS_SOLID, NULL, 10); /* 设置线宽为 10,这样效果明显*/ rectangle(100,100,200,200); /* 画一个矩形,当作背景图案*/ setwritemode(R2_XORPEN); /* 设置 XOR 绘图模式*/ setcolor(RED); /* 设置画线颜色*/ line(50,0, 200,300); /* 画线*/ getch(); /* 等待按任意键*/ line(50,0, 200,300); /* 画线(XOR 方式重复画线会恢复背景图案)*/ getch(); /* 等待按任意键*/ closegraph(); /* 关闭绘图窗口*/运行一下,看到第一次画线后,矩形与直线相交的部分,颜色变成了青色,青色就是白色和红色 XOR 的值。当再次以红色画线时,青色部分消失了,还原为完整的白色矩形框。【例2-15】写一个钟表程序,三个表针用的都是 XOR 方式绘制。#include #include #include void Draw(int hour, int minute, int second) double a_hour, a_min, a_sec; /* 时、分、秒针的弧度值*/ int x_hour, y_hour, x_min, y_min, x_sec, y_sec; /* 时、分、秒针的末端位置*/ /* 计算时、分、秒针的弧度值*/ a_sec = second * 2 * PI / 60; a_min = minute * 2 * PI / 60 + a_sec / 60; a_hour= hour * 2 * PI / 12 + a_min / 12; /* 计算时、分、秒针的末端位置*/ x_sec = 320 + (int)(120 * sin(a_sec); y_sec = 240 - (int)(120 * cos(a_sec); x_min = 320 + (int)(100 * sin(a_min); y_min = 240 - (int)(100 * cos(a_min); x_hour= 320 + (int)(70 * sin(a_hour); y_hour= 240 - (int)(70 * cos(a_hour); /* 画时针*/ setlinestyle(PS_SOLID, NULL, 10); setcolor(WHITE); line(320, 240, x_hour, y_hour); /* 画分针*/ setlinestyle(PS_SOLID, NULL, 6); setcolor(LIGHTGRAY); line(320, 240, x_min, y_min); /* 画秒针*/ setlinestyle(PS_SOLID, NULL, 2); setcolor(RED); line(320, 240, x_sec, y_sec);void main() initgraph(640, 480); /* 初始化 640 x 480 的绘图窗口*/ /* 绘制一个简单的表盘*/ circle(320, 240, 2); circle(320, 240, 60); circle(320, 240, 160); outtextxy(296, 300, BestAns); /* 设置 XOR 绘图模式*/ setwritemode(R2_XORPEN); /* 设置 XOR 绘图模式*/ /* 绘制表针*/ SYSTEMTIME ti; /* 定义变量保存当前时间*/ while(!kbhit() /* 按任意键退出钟表程序*/ GetLocalTime(&ti); /* 获取当前时间*/ Draw(ti.wHour, ti.wMinute, ti.wSecond); /* 画表针*/ Sleep(1000); /* 延时 1 秒*/ Draw(ti.wHour, ti.wMinute, ti.wSecond); /* 擦表针(擦表针和画表针的过程是一样的)*/ closegraph(); /* 关闭绘图窗口*/【练习题】1) 最后给出的绘制时钟的例子,很不完善,有不少问题。请完善该程序。例如样式上,表盘上没有刻度,没有数字,指针靠中心的一端应该长出来一点点,表盘太简单。还有就是尝试发现并改进功能实现上的问题。2.11用鼠标控制绘图 捕获鼠标消息就像捕获按键消息一样简单。对于按键,通常我们会先检查是否有按键,然后定义一个变量保存按键,再然后根据该按键的值,执行相应的程序。对于鼠标,道理是一样的。先写个代码对比一下:获取按键: 获取鼠标:char c; MOUSEMSG m;if (kbhit() if (MouseHit()c = getch(); m = GetMouseMsg();很简单吧。由于鼠标消息的内容太多,不像按键那么简单,因此需要用一个结构体来保存。通过该结构体,我们可以获取鼠标的如下信息:struct MOUSEMSG UINT uMsg; /* 当前鼠标消息*/ bool mkCtrl; /* Ctrl 键是否按下*/ bool mkShift; /* Shift 键是否按下*/ bool mkLButton; /* 鼠标左键是否按下*/ bool mkMButton; /* 鼠标中键是否按下*/ bool mkRButton; /* 鼠标右键是否按下*/ int x; /* 当前鼠标 x 坐标*/ int y; /* 当前鼠标 y 坐标*/ int wheel; /* 鼠标滚轮滚动值*/;其中,“当前鼠标消息”可能是以下值:WM_MOUSEMOVE 鼠标移动消息WM_MOUSEWHEEL 鼠标滚轮拨动消息WM_LBUTTONDOWN 左键按下消息WM_LBUTTONUP 左键弹起消息WM_LBUTTONDBLCLK 连续快按两下鼠标左键消息WM_MBUTTONDOWN 中键按下消息WM_MBUTTONUP 中键弹起消息WM_MBUTTONDBLCLK 连续快按两下鼠标中键消息WM_RBUTTONDOWN 右键按下消息WM_RBUTTONUP 右键弹起消息WM_RBUTTONDBLCLK 连续快按两下鼠标右键消息例如,判断获取的消息是否是鼠标左键按下,可以用:if (m.uMsg = WM_LBUTTONDOWN) .【例2-16】用红色的点标出鼠标移动的轨迹,按左键画一个小方块,按Ctrl+左键画一个大方块,按右键退出。#include #include #include void main() /* 初始化图形窗口*/ initgraph(640, 480); MOUSEMSG m; /* 定义鼠标消息*/ while(true) /* 获取一条鼠标消息*/ m = GetMouseMsg(); switch(m.uMsg) case WM_MOUSEMOVE: /* 鼠标移动的时候画红色的小点*/ putpixel(m.x, m.y, RED); break; case WM_LBUTTONDOWN: /* 如果点左键的同时按下了 Ctrl 键*/ if (m.mkCtrl) /* 画一个大方块*/ rectangle(m.x-10, m.y-10, m.x+10, m.y+10); else /* 画一个小方块*/ rectangle(m.x-5, m.y-5, m.x+5, m.y+5); break; case WM_RBUTTONUP: return; /* 按鼠标右键退出程序*/ /* 关闭图形窗口*/ closegraph();【练习题】1) 画一个填充的三角形,用鼠标选择三角形的三个顶点。提示:可以用 fillpoly 函数画多边形。2) 写一个“格子涂色”的游戏,要求:屏幕上有16x8的格子,屏幕底部有类似画笔中的选色区(随便放上一些常用的颜色),按一下鼠标左键选择选择区的颜色后,就作为当前颜色,然后再点屏幕上的格子,就可以用刚才的颜色填涂相应格子。2.12随机函数游戏中,许多情况都是随即发生的。还有一些图案程序,例如屏保,也是随即运动的。这就需要用随机函数。1) 随机函数随机函数很简单,只有一个:rand();该函数返回 032767 之间的一个整数。(不需要记住 32767 这个数字,大概知道这个范围就行了)该函数在头文件 中,使用前记得引用。【例2-17】简单写个程序测试一下随机函数的使用。#include #include void main() int r; for(int i=0; i10; i+) r = rand(); printf(%dn, r); 执行后,可以看到输出了 10 个随机数字。2) 指定范围的随机函数实际中,我们经常要产生指定范围的随机函数,通常我们用求余数的办法。例如,产生 09 之间的随机数,只需要将任意产生的随机数除以 10 求余数即可。求余数的运算符号是 %,我们可以这样做: r = rand() % 10;修改前面的测试程序执行后可以看到,产生的数字都是小于 10 的。如果是 16 之间的怎样求呢? r = rand() % 6 + 1;无论产生什么样范围的随机函数,都是通过各种运算将随机数的范围 0, 32767 修改为自己需要的范围。3) 随机种子做了多次试验,我们会发现一个问题:虽然产生的数字是随机的,但每次产生的数字序列都一样。为了解决这个问题,我们需要用“随机种子”。随机函数的产生原理简单来说,就是:前一个随机函数的值,决定下一个随机函数的值。根据这个原理我们可以知道:只要第一个随机函数的值确定了,那么后面数字序列就是确定的。如果我们想的得到不同的数字序列,我们需要确定第一个随机函数的值,对于设置第一个随机函数的值,叫做设置“随机种子”。易知,随机种子设置一次即可。设置随机种子的函数如下:srand(种子);通常,我们用当前时间来做随机种子:srand( (unsigned)time( NULL ) );因为使用 time 函数,所以记得引用 。4) 绘图中的应用【例2-18】在屏幕上任意位置画任意颜色的点(按任意键退出)。#include #include #include #include void main() srand( (unsigned)time( NULL ) ); initgraph(640, 480); int x, y, c; while(!kbhit() x = rand() % 640; y = rand() % 480; c = RGB(rand() % 256, rand() % 256, rand() % 256); putpixel(x, y, c); c

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论