EasyX教程.docx
《EasyX教程.docx》由会员分享,可在线阅读,更多相关《EasyX教程.docx(41页珍藏版)》请在冰豆网上搜索。
EasyX教程
一创建新项目
VC写程序要有项目的概念,一个项目可以有多个.cpp文件,多个项目构成一个工作区。
先记住这两个英文单词吧:
•Workspace:
工作区
•Project:
项目
现在开始创建一个新项目。
•VC6创建新项目请参考这个视频:
.easyx./news/View.aspx?
id=65
•VC2008创建新项目请参考这个视频:
.easyx./news/View.aspx?
id=85
•VC2010与VC2008相似。
看明白后,自己动手建立项目试试,并输入以下代码:
尤其是之前用tc的同学,请务必创建新项目试一试。
成功执行后,会看到屏幕上有“HelloWorld!
”几个字符。
然后,再重新输入以下代码试试(无需理解代码含义):
执行后应该可以看到屏幕正中央有一个十字。
看到该十字后,本节课结束。
二简单绘图,学习单步执行
学会简单绘图,并学会简单调试。
先看看上一课的代码,我加上了注释
#include
//绘图库头文件,绘图语句需要
#include
//控制台输入输出头文件,
getch()语句需要
voidmain()
{
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以至于看不到绘制的容。
[作业]
用线条画出更多的图形,要求不少于10条直线。
[学习单步执行]
完成作业后(务必完成),开始试着单步执行刚才的程序,由于绘图和多线程等因素的限制,请务必按照以下步骤尝试(熟练了以后就不用了):
1.将VC取消最大化,并缩小窗口,能看到代码就行。
2.按一下F10(单步执行),会看到屏幕上出现一个黄色的小箭头,指示将要执行的代码。
3.当箭头指向initgraph语句时,按F10,能看到窗口发生了变化。
4.将新的绘图窗口和VC并排放,相互不要有覆盖。
这步很重要,否则绘图容将会被VC窗口覆盖。
5.F10执行getch后,记得激活绘图窗口,并按任意键,否则程序不会继续执行。
6.closegraph后,直接按F5执行全部剩余程序,结束。
单步执行很重要,可以让你知道程序执行到哪里是什么效果,哪条语句执行出了问题等等。
更详细的调试资料,请看这里:
pan.baidu./s/1eR6HT
该文档写的调试的东西比较多,看一下大概有个了解,以后都会用到(不过以后我就不再讲了)
[作业2]
仍然是写一个用直线绘制的图形,并熟悉调试过程。
注:
1.许多学校都忽略了调试部分,如果你不曾用过调试,请务必熟练该过程。
2.win-tc不带有任何调试功能,即便你不用vc,也请不要使用win-tc。
调试是相当相当重要的。
三学会更多的绘图语句
[常用的绘图语句]
•line(x1,y1,x2,y2);//画直线(x1,y1)-(x2,y2),都是整形
•circle(x,y,r);//画圆,圆心为(x,y),半径为r
•putpixel(x,y,c);//画点(x,y),颜色c
还有很多,如画椭圆、圆弧、矩形、多边形,等等,请参考绘图帮助文件(第
一课的绘图库的下载里面有)
[设置颜色]setlinecolor(c);//设置画线颜色,如setlinecolor(RED)设置画线颜色为红色
常用的颜色常量可以用:
•BLACK黑DARKGRAY深灰
•BLUE蓝LIGHTBLUE亮蓝
•GREEN绿LIGHTGREEN亮绿
•CYAN青LIGHTCYAN亮青
•RED红LIGHTRED亮红
•MAGENTA紫LIGHTMAGENTA亮紫
•BROWN棕YELLOW黄
•LIGHTGRAY浅灰WHITE白
[配出更多的颜色]颜色除了前面写的16种以外,还可以自由配色。
格式:
RGB(r,g,b)
r/g/b分别表示红色、绿色、蓝色,围都是0~255。
例如,RGB(255,0,0)表示纯红色。
红色和绿色配成黄色,因此RGB(255,255,0)表示黄色。
嫌调色麻烦可以用画笔里面的调色试试,调好了以后直接将数值抄过来就行。
例如,画两条红色浓度为200的直线,可以这么写:
[用数字表示颜色]
除了用RGB(r,g,b)方式外,还可以用16进制表示颜色,格式:
0xbbggrr例如,setlinecolor(0x0000ff)和setlinecolor(RGB(255,0,0))是等效的。
[延时语句]
这个很简单,Sleep(n)就可以表示n毫秒的延时。
例如延时3秒,可以用
Sleep(3000);
[作业]
1.简单看一下绘图库的帮助文件,了解更多的绘图语句。
2.绘制更丰富的图形容,不低于20行。
3.将延时语句适当的插入上个作业的代码中,看看执行效果。
注:
绘图语句不需要记住,用的时候翻翻手册就行。
四结合流程控制语句来绘图
熟练使用循环、判断语句
[熟悉for语句]
这步需要自学,看看自己手边的书,是怎样讲for语句的,简单看看就行。
[例]
例如,画10条直线的代码:
换一下循环的围和间隔,看看效果。
还可以用来画渐变色,例如:
[熟悉if语句]
这步需要自学,看看自己手边的书,是怎样讲if语句的,简单看看就行。
配合if语句,实现红色、蓝色交替画线:
1.画围棋棋盘。
2.画中国象棋的棋盘
3.画国际象棋的棋盘,看手册找到颜色填充语句,实现国际象棋棋盘的区块填充。
4.自学while语句。
学到这里,已经可以画出很多东西了。
把自己想象中的图案绘制一下吧。
五数学知识在绘图中的运用
理解数学的重要性
1.最简单的,来个全屏的渐变色吧,是上一课的扩展。
就是需要将0~255的颜色和0~479的y轴对应起来c表示颜色,围0~255y表示y轴,围0~479
于是:
c/255=y/479
c=y/479*255=y*255/479(先算乘法再算除法可以提高精度)看代码:
试试效果吧。
2.画一个圆形的渐变色
首先,我们要用到圆形的基本公式:
x*x+y*y=r*r
让弧度从0~2*3.14,然后需要根据弧度和半径算出(x,y),用pi表示圆周率用r表示半径
用a表示弧度(小数)用c表示颜色
于是:
x=r*cos(a)y=r*sin(a)
c=a*255/(2*pi)
看看代码:
[作业]
这次没什么作业,只是理解一下数学的重要性而已。
如果读者还在念书,请重视数学。
六实现简单动画
所谓动画,其实是连续显示一系列图形而已。
结合到程序上,我们需要以下几个步骤:
1.绘制图像
2.延时
3.擦掉图像
循环以上即可实现动画。
举一个例子,我们实现一条直线从上往下移动:
再看一个例子,实现一个圆从左往右跳动:
#include
也就是说,移动的间距小、延时短,动画就会越细腻。
但当画面较复杂时,会带来画面的闪烁(怎样消除闪烁是以后的话题)。
[作业]
绘制一个沿45度移动的球,碰到窗口边界后反弹。
七捕获按键,实现动画的简单控制
最常用的一个捕获按键的函数:
getch()
前几课,都把这个函数当做“按任意键继续”来用,现在我们用变量保存这个按键:
charc=getch();
然后再做判断即可。
不过程序执行到getch()是会阻塞的,直到用户有按键才能继续执行。
可游戏中总不能因为等待按键而停止游戏执行吧?
所以,要有一个函数,判断是否有用户按键:
kbhit()
这个函数返回当前是否有用户按键,如果有,再用getch()获取即可,这样是不会阻塞的。
即:
举一个简单的例子,如果有按键,就输出相关按键。
否则,输出“.”。
每隔100毫秒输出一次。
按ESC退出。
注:
ESC的ASCII码是27。
完整代码如下:
printf("%c",c);
Sleep(100);
}
}
结合上一课的简单动画,就可以做出来靠按键移动的图形了吧,看以下代码,实现as控制圆的左右移动:
//绘制新的图形
setcolor(YELLOW);
setfillcolor(GREEN);
fillcircle(x,240,20);
//延时
Sleep(10);
}
closegraph();
}
[作业]
请继续完成这个程序,实现以下功能:
1.上下的控制;
2.边界检测;
3.结合kbhit实现惯性移动(即按一下方向键,圆就会一直向这个方向移动)
注:
上下左右等按键的控制,会返回2个字符。
由于该系列教程面向初学者,因此有兴趣的请查看MSDN。
八用函数简化相同图案的制作
实际中有许多类似的图案,如果一一单独绘制,太麻烦。
于是,我们需要一个公用的绘制过程,就是函数。
例如,我们需要画5个三角形,位于不同的位置。
我们可以将绘制单个三角形的过程写成函数,函数是一个独立的程序段,这个绘制过程很简单。
然后,在需要绘制的时候,调用这个函数即可。
可以通过参数来解决细微差异(图案的坐标、颜色等),例如:
}
再结合循环等控制条件,就能绘制更复杂漂亮的图案了。
试试运行下面程序,理解一下函数的用处:
运行效果:
本节作业:
1.绘制Windows自带游戏“扫雷”的初始界面。
2.这个作业有点独特,仔细看下面这个数学过程:
1.随机生成3个点P[0]、P[1]、P[2];
2.随机生成1个点P;
3.绘制点P;
4.随机生成[0,2]的整数n;
5.令P=P与P[n]的中点;
6.重复执行步骤(3)~(5)三万次。
问题是:
以上步骤执行完以后,这三万个点在屏幕上会是个什么情况?
有规律吗?
很难想出来吧,那就写个程序把这个过程模拟一下,看看究竟是什么~~
九绘图中的位运算
位运算和绘图有什么关系?
先举个例子来个感性认识:
使用XOR运算可以实现擦除图形后不破坏背景,这在时钟程序中绘制表针是很有用的。
稍后我们会给出这样的例子。
一、位运算的运算法则
位运算主要分4种:
NOT、AND、OR、XOR,位运算的运算对象是二进制数(十进制要转换为二进制,计算机会自动转换)。
运算法则如下:
1.NOT
表示“取反”,将二进制位的1变0、0变1。
C语言用符号~表示。
如:
二进制:
~1101=0010
用十进制表示就是:
~13=2
2.AND
表示“并且”,只有两数的对应二进制位都为1,结果的二进制位才为1;否则,结果的二进制位为0。
C语言用符号&表示。
如:
二进制:
1101&0110=0100
用十进制表示就是:
13&6=4
3.OR
表示“或者”,两数的对应二进制位只要有一个是1,结果的二进制位就是1;否则,结果的二进制位为0。
C语言用符号|表示。
如:
二进制:
0101|0110=0111
用十进制表示就是:
5|6=7
4.XOR
表示“异或”,两数的对应二进制位不同,结果的二进制位为1;相同,结果的二进制位为0。
C语言用符号^表示。
如:
二进制:
0101^1110=1011
以上只是简单介绍一下,详细的还是请大家看课本上的讲解。
2、位运算的应用
位运算的应用很多,例如AND和OR在获取和设置标志位时经常使用。
更多的,以后大家会逐渐遇到,暂时先记下有这么回事。
这里着重说一下XOR运算,它有一个重要的特性:
(a^b)^b=a
也就是说,a^b之后可能是某些其它数字,但是只要再^b一下,就又成了a。
一些简单的加密就用的XOR的这个特性。
至于绘图,假如a是背景图案,b是将要绘制的图案,只要用XOR方式绘图,连续绘两次,那么背景是不变的。
3、演示我们来一个简单的绘图XOR运算演示:
#include
#include
voidmain()
{
initgraph(640,480);
//初始化640x
480的绘图窗口
setlinestyle(PS_SOLID,10);
//设置线宽为10
这样效果明显
setlinecolor(GREEN);为绿色
//设置画线颜色
,
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的值。
当再次以红色画线时,青色部分消失了,还原为完整的白色矩形框。
4、完整的例
来一个相对完整的例吧,就是钟表程序,三个表针用的都是XOR方式绘制,请大家运行体会一下XOR的作用:
5、作业
最后给出的绘制时钟的例子,很不完善,有不少问题。
请完善该程序。
例如样式上,表盘上没有刻度,没有数字,指针靠中心的一端应该长出来一点点,表盘太简单。
还有就是尝试发现并改进功能实现上的问题。
十用鼠标控制绘图/游戏程序
捕获鼠标消息就像捕获按键消息一样简单。
对于按键,通常我们会先检查是否有按键,然后定义一个变量保存按键,再然后根据该按键的值,执行相应的程序。
对于鼠标,道理是一样的。
先写个代码对比一下:
获取按键:
获取鼠标:
charc;MOUSEMSGm;if(kbhit())if(MouseHit())c=getch();m=GetMouseMsg();
很简单吧。
由于鼠标消息的容太多,不像按键那么简单,因此需要用一个
结构体来保存。
通过该结构体,我们可以获取鼠标的如下信息:
structMOUSEMSG
{
UINTuMsg;//当前鼠标消息boolmkCtrl;//Ctrl键是否按下
boolmkShift;//Shift键是否按下boolmkLButton;//鼠标左键是否按下boolmkMButton;//鼠标中键是否按下
boolmkRButton;//鼠标右键是否按下intx;//当前鼠标x坐标inty;//当前鼠标y坐标
intwheel;//鼠标滚轮滚动值
};
其中,“当前鼠标消息”可能是以下值:
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)...
下面举一个综合的例子(我偷点懒,直接粘贴的绘图库帮助里面的鼠标例),
该程序会用红色的点标出鼠标移动的轨迹,按左键画一个小方块,按Ctrl+左键画一个大方块,按右键退出:
#include#includevoidmain(){//初始化图形窗口initgraph(640,480);MOUSEMSGm;//定义鼠标消息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;caseWM_RBUTTONUP:
return;
//按鼠标右键退出程序}}//关闭图形窗口
closegraph();}
[本节作业]
1.画一个填充的三角形,要用鼠标点选三角形的三个顶点。
提示:
可以用fillpoly函数画多边形。
2.写一个“格子涂色”的游戏,要求:
屏幕上有16x8的格子,屏幕底部有类似画笔中的选色区(随便放上一些常用的颜色),鼠标点击选择区的颜色后,就作为当前颜色,然后再点屏幕上的格子,就可以用刚才的颜色填涂相应格子。
十一随机函数简介
游戏中,许多情况都是随即发生的。
还有一些图案程序,例如屏保,也是随即运动的。
这就需要用随机函数。
随机函数很简单,只有一个:
rand()
该函数返回0~32767之间的一个整数。
(不需要记住32767这个数字,大概知道这个围就行了)
该函数在头文件中,使用前记得引用。
[简单测试]
来写个程序测试一下:
#include
#include
voidmain()
{
intr;for(inti=0;i<10;i++)
{r=rand();printf("%d\n",r);
}
}
执行后,可以看到输出了10个随机数字。
[指定围的随机函数]实际中,我们经常要产生指定围的随机函数,通常我们用求余数的办法。
例如,产生0~9之间的随机数,只需要将任意产生的随机数除以10求余数即可。
求
余数的运算符号是%,我们可以这样做:
r=rand()%10;修改前面的测试程序执行后可以看到,产生的数字都是小于10的。
如果是1~6之间的怎样求呢?
r=rand()%6+1;
无论产生什么样围的随机函数,都是通过各种运算将随机数的围[0,
32767]修改为自己需要的围。
[随机种子]
做了多次试验,我们会发现一个问题:
虽然产生的数字是随机的,但每次产生的数字序列都一样。
为了解决这个问题,我们需要用“随机种子”。
随机函数的产生原理简单来说,就是:
前一个随机函数的值,决定下一个随机函数的值。
根据这个原理我们可以知道:
只要第一个随机函数的值确定了,那么后面数字序列就是确定的。
如果我们想的得到不同的数字序列,我们需要确定第一个随机函数的值,对于设置第一个随机函数的值,叫做设置“随机种子”。
易知,随机种子设置一次即可。
设置随机种子的函数如下:
srand(种子);
通常,我们用当前时间来做随机种子:
srand((unsigned)time(NULL));
因为使用time函数,所以记得引用。
[绘图中的应用]
来一个简单的程序,在屏幕上任意位置画任意颜色的点(按任意键退出):
#include
#include
#include
#include
voidmain()
{
srand((unsigned)time(NULL));initgraph(640,480);
intx,y,c;
while(!
kbhit())
{x=rand()%640;y=rand()%480;
c=RGB(rand()%256,rand()%256,rand()%256);putpixel(x,y,c);
}
closegraph();}
[作业]
1.回顾一下第6课“实现简单动画”的作业:
绘制一个沿45度移动的球,碰到窗口边界后反弹。
将这个球改为任意方向运动,碰到边界后任意