




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
..1:創(chuàng)建新項(xiàng)目自己動(dòng)手建立項(xiàng)目試試,并輸入以下代碼:#include<stdio.h>
voidmain<>
{
printf<"HelloWorld!">;
}然后,輸入以下代碼試試〔無(wú)需理解代碼含義:
#include<graphics.h>
#include<conio.h>
voidmain<>
{
initgraph<640,480>;
line<200,240,440,240>;
line<320,120,320,360>;
getch<>;
closegraph<>;
}
執(zhí)行后應(yīng)該可以看到屏幕正中央有一個(gè)十字2:簡(jiǎn)單繪圖,學(xué)習(xí)單步執(zhí)行#include<graphics.h>//繪圖庫(kù)頭文件,繪圖語(yǔ)句需要
#include<conio.h>//控制臺(tái)輸入輸出頭文件,getch<>語(yǔ)句需要
voidmain<>
{
initgraph<640,480>;//初始化640x480的繪圖屏幕
line<200,240,440,240>;//畫(huà)線<200,240>-<440,240>
line<320,120,320,360>;//畫(huà)線<320,120>-<320,360>
getch<>;//按任意鍵
closegraph<>;//關(guān)閉繪圖屏幕
}
解釋一下:
1.創(chuàng)建的繪圖屏幕640x480,表示橫向有640個(gè)點(diǎn),縱向有480個(gè)點(diǎn)。注意:左上角是原點(diǎn)<0,0>,也就是說(shuō),y軸和數(shù)學(xué)的y軸是相反的。
2.getch實(shí)現(xiàn)按任意鍵功能,按任意鍵后,程序繼續(xù)執(zhí)行。否則,程序會(huì)立刻執(zhí)行closegraph以至于看不到繪制的內(nèi)容。
[作業(yè)]
用線條畫(huà)出更多的圖形,要求不少于10條直線。
[學(xué)習(xí)單步執(zhí)行]
完成作業(yè)后〔務(wù)必完成,開(kāi)始試著單步執(zhí)行剛才的程序,由于繪圖和多線程等因素的限制,請(qǐng)務(wù)必按照以下步驟嘗試〔熟練了以后就不用了:
1.將VC取消最大化,并縮小窗口,能看到代碼就行。
2.按一下F10〔單步執(zhí)行,會(huì)看到屏幕上出現(xiàn)一個(gè)黃色的小箭頭,指示將要執(zhí)行的代碼。
3.當(dāng)箭頭指向initgraph語(yǔ)句時(shí),按F10,能看到窗口發(fā)生了變化。
4.將新的繪圖窗口和VC并排放,相互不要有覆蓋。這步很重要,否則繪圖內(nèi)容將會(huì)被VC窗口覆蓋。
5.F10執(zhí)行g(shù)etch后,記得激活繪圖窗口,并按任意鍵,否則程序不會(huì)繼續(xù)執(zhí)行。
6.closegraph后,直接按F5執(zhí)行全部剩余程序,結(jié)束。
單步執(zhí)行很重要,可以讓你知道程序執(zhí)行到哪里是什么效果,哪條語(yǔ)句執(zhí)行出了問(wèn)題等等。3:熟悉更多的繪圖語(yǔ)句
[常用的繪圖語(yǔ)句]
line<x1,y1,x2,y2>;//畫(huà)直線<x1,y1>-<x2,y2>,都是整形
circle<x,y,r>;//畫(huà)圓,圓心為<x,y>,半徑為r
putpixel<x,y,c>;//畫(huà)點(diǎn)<x,y>,顏色c
還有很多,如畫(huà)橢圓、圓弧、矩形、多邊形,等等,請(qǐng)參考繪圖幫助文件〔目錄頁(yè)的繪圖庫(kù)的下載里面有
[設(shè)置顏色]
setcolor<c>;//設(shè)置繪圖顏色,如setcolor<RED>設(shè)置為紅色等
常用的顏色常量可以用:
BLACK黑DARKGRAY深灰
BLUE藍(lán)LIGHTBLUE亮藍(lán)
GREEN綠LIGHTGREEN亮綠
CYAN青LIGHTCYAN亮青
RED紅LIGHTRED亮紅
MAGENTA紫LIGHTMAGENTA亮紫
BROWN棕YELLOW黃
LIGHTGRAY淺灰WHITE白
[配出更多的顏色]
顏色除了前面寫(xiě)的16種以外,還可以自由配色。格式:
RGB<r,g,b>
r/g/b分別表示紅色、綠色、藍(lán)色,范圍都是0~255。
例如,RGB<255,0,0>表示純紅色。
紅色和綠色配成黃色,因此RGB<255,255,0>表示黃色。
嫌調(diào)色麻煩可以用畫(huà)筆里面的調(diào)色試試,調(diào)好了以后直接將數(shù)值抄過(guò)來(lái)就行。
例如,畫(huà)兩條紅色濃度為200的直線,可以寫(xiě):
setcolor<RGB<200,0,0>>;
line<100,100,200,100>;
line<100,120,200,120>;
[用數(shù)字表示顏色]
除了用RGB<r,g,b>方式外,還可以用16進(jìn)制表示顏色,格式:
0xrrggbb
例如,setcolor<0xff0000>和setcolor<RGB<255,0,0>>是等效的。
[延時(shí)語(yǔ)句]
這個(gè)很簡(jiǎn)單Sleep<n>就可以表示n毫秒的延時(shí)。例如延時(shí)3秒,可以用Sleep<3000>;
[作業(yè)]
1.簡(jiǎn)單看一下繪圖庫(kù)的幫助文件,了解更多的繪圖語(yǔ)句。
2.繪制更豐富的圖形內(nèi)容,不低于20行。
3.將延時(shí)語(yǔ)句適當(dāng)?shù)牟迦肷蟼€(gè)作業(yè)的代碼中,看看執(zhí)行效果。
注:繪圖語(yǔ)句不需要記住,用的時(shí)候翻翻手冊(cè)就行。-4:結(jié)合流程控制語(yǔ)句來(lái)繪圖[范例]
例如,畫(huà)10條直線的代碼:
#include<graphics.h>
#include<conio.h>
voidmain<>
{
initgraph<640,480>;
for<inty=100;y<200;y+=10>
line<100,y,300,y>;
getch<>;
closegraph<>;
}
換一下循環(huán)的范圍和間隔,看看效果。
還可以用來(lái)畫(huà)漸變色,例如:
#include<graphics.h>
#include<conio.h>
voidmain<>
{
initgraph<640,480>;
for<inty=0;y<256;y++>
{
setcolor<RGB<0,0,y>>;
line<100,y,300,y>;
}
getch<>;
closegraph<>;
}
[熟悉if語(yǔ)句]
這步需要自學(xué),看看自己手邊的書(shū),是怎樣講if語(yǔ)句的,簡(jiǎn)單看看就行。
配合if語(yǔ)句,實(shí)現(xiàn)紅色、藍(lán)色交替畫(huà)線:
#include<graphics.h>
#include<conio.h>
voidmain<>
{
initgraph<640,480>;
for<inty=100;y<200;y+=10>
{
if<y/10%2==1>
//判斷奇數(shù)行偶數(shù)行
setcolor<RGB<255,0,0>>;
else
setcolor<RGB<0,0,255>>;
line<100,y,300,y>;
}
getch<>;
closegraph<>;
}
[作業(yè)]
1.畫(huà)圍棋棋盤(pán)。
2.畫(huà)中國(guó)象棋的棋盤(pán)
3.畫(huà)國(guó)際象棋的棋盤(pán),看手冊(cè)找到顏色填充語(yǔ)句,實(shí)現(xiàn)過(guò)期象棋棋盤(pán)的區(qū)塊填充。
4.自學(xué)while語(yǔ)句。
學(xué)到這里,已經(jīng)可以畫(huà)出很多東西了。把自己想象中的圖案繪制一下吧。5:數(shù)學(xué)知識(shí)在繪圖中的運(yùn)用1.最簡(jiǎn)單的,來(lái)個(gè)全屏的漸變色吧,是上一課的擴(kuò)展。就是需要將0~255的顏色和0~479的y軸對(duì)應(yīng)起來(lái)
c表示顏色,范圍0~255
y表示y軸,范圍0~479
于是:
c/255=y/479
c=y/479*255=y*255/479〔先算乘法再算除法可以提高精度
看代碼:
#include<graphics.h>
#include<conio.h>
voidmain<>
{
initgraph<640,480>;
intc;
for<inty=0;y<480;y++>
{
c=y*255/479;
setcolor<RGB<0,0,c>>;
line<0,y,639,y>;
}
getch<>;
closegraph<>;
}
試試效果吧。
2.畫(huà)一個(gè)圓形的漸變色
首先,我們要用到圓形的基本公式:
x*x+y*y=r*r
讓弧度從0~2*3.14,然后需要根據(jù)弧度和半徑算出<x,y>,
用pi表示圓周率
用r表示半徑
用a表示弧度〔小數(shù)
用c表示顏色
于是:
x=r*cos<a>
y=r*sin<a>
c=a*255/<2*pi>
看看代碼:
#include<graphics.h>
#include<conio.h>
#include<math.h>
voidmain<>
{
initgraph<640,480>;
intc;
doublea;
intx,y,r=200;
for<a=0;a<PI*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<>;
}6:實(shí)現(xiàn)簡(jiǎn)單動(dòng)畫(huà)所謂動(dòng)畫(huà),其實(shí)是連續(xù)顯示一系列圖形而已。
結(jié)合到程序上,我們需要以下幾個(gè)步驟:
1.繪制圖像
2.延時(shí)
3.擦掉圖像
循環(huán)以上即可實(shí)現(xiàn)動(dòng)畫(huà)。
舉一個(gè)例子,我們實(shí)現(xiàn)一條直線從上往下移動(dòng):
#include<graphics.h>
#include<conio.h>
voidmain<>
{
initgraph<640,480>;
for<inty=0;y<480;y++>
{
//繪制綠色直線
setcolor<GREEN>;
line<0,y,639,y>;
//延時(shí)
Sleep<10>;
//繪制黑色直線〔即擦掉之前畫(huà)的綠線
setcolor<BLACK>;
line<0,y,639,y>;
}
closegraph<>;
}
再看一個(gè)例子,實(shí)現(xiàn)一個(gè)圓從左往右跳動(dòng):
#include<graphics.h>
#include<conio.h>
voidmain<>
{
initgraph<640,480>;
for<intx=100;x<540;x+=20>
{
//繪制黃線、綠色填充的圓
setcolor<YELLOW>;
setfillstyle<GREEN>;
fillellipse<x,100,20,20>;
//演示
Sleep<500>;
//繪制黑線、黑色填充的圓
setcolor<BLACK>;
setfillstyle<BLACK>;
fillellipse<x,100,20,20>;
}
closegraph<>;
}
也就是說(shuō),移動(dòng)的間距小、延時(shí)短,動(dòng)畫(huà)就會(huì)越細(xì)膩。但當(dāng)畫(huà)面較復(fù)雜時(shí),會(huì)帶來(lái)畫(huà)面的閃爍〔怎樣消除閃爍是以后的話題。7:捕獲按鍵,實(shí)現(xiàn)動(dòng)畫(huà)的簡(jiǎn)單控制最常用的一個(gè)捕獲按鍵的函數(shù):getch<>
前幾課,都把這個(gè)函數(shù)當(dāng)做"按任意鍵繼續(xù)"來(lái)用,現(xiàn)在我們用變量保存這個(gè)按鍵:
charc=getch<>;
然后再做判斷即可。
不過(guò)程序執(zhí)行到getch<>是會(huì)阻塞的,直到用戶有按鍵才能繼續(xù)執(zhí)行??捎螒蛑锌偛荒芤?yàn)榈却存I而停止游戲執(zhí)行吧?所以,要有一個(gè)函數(shù),判斷是否有用戶按鍵:kbhit<>
這個(gè)函數(shù)返回當(dāng)前是否有用戶按鍵,如果有,再用getch<>獲取即可,這樣是不會(huì)阻塞的。
即:
charc;
if<kbhit<>>
c=getch<>;
舉一個(gè)簡(jiǎn)單的例子,如果有按鍵,就輸出相關(guān)按鍵。否則,輸出"."。每隔100毫秒輸出一次。按ESC退出。
注:ESC的ASCII碼是27。
完整代碼如下:
#include<graphics.h>
#include<stdio.h>
#include<conio.h>
voidmain<>
{
charc=0;
while<c!=27>
{
if<kbhit<>>
c=getch<>;
else
c='.';
printf<"%c",c>;
Sleep<100>;
}
}
結(jié)合上一課的簡(jiǎn)單動(dòng)畫(huà),就可以做出來(lái)靠按鍵移動(dòng)的圖形了吧,看以下代碼,實(shí)現(xiàn)as控制圓的左右移動(dòng):
#include<graphics.h>
#include<conio.h>
voidmain<>
{
initgraph<640,480>;
intx=320;
//畫(huà)初始圖形
setcolor<YELLOW>;
setfillstyle<GREEN>;
fillellipse<x,240,20,20>;
charc;
while<c!=27>
{
//獲取按鍵
c=getch<>;
//先擦掉上次顯示的舊圖形
setcolor<BLACK>;
setfillstyle<BLACK>;
fillellipse<x,240,20,20>;
//根據(jù)輸入,計(jì)算新的坐標(biāo)
switch<c>
{
case'a':x-=2;break;
case'd':x+=2;break;
case27:break;
}
//繪制新的圖形
setcolor<YELLOW>;
setfillstyle<GREEN>;
fillellipse<x,240,20,20>;
//延時(shí)
Sleep<10>;
}
closegraph<>;
}
[作業(yè)]
請(qǐng)繼續(xù)完成這個(gè)程序,實(shí)現(xiàn)以下功能:
1.上下的控制;
2.邊界檢測(cè);
3.結(jié)合kbhit實(shí)現(xiàn)慣性移動(dòng)〔即按一下方向鍵,圓就會(huì)一直向這個(gè)方向移動(dòng)
注:上下左右等按鍵的控制,會(huì)返回2個(gè)字符。由于該系列教程面向初學(xué)者,因此有興趣的請(qǐng)查看MSDN。8:用函數(shù)簡(jiǎn)化相同圖案的制作實(shí)際中有許多類似的圖案,如果一一單獨(dú)繪制,太麻煩。于是,我們需要一個(gè)公用的繪制過(guò)程,就是函數(shù)。
例如,我們需要畫(huà)5個(gè)三角形,位于不同的位置。我們可以將繪制單個(gè)三角形的過(guò)程寫(xiě)成函數(shù),函數(shù)內(nèi)是一個(gè)獨(dú)立的程序段,這個(gè)繪制過(guò)程很簡(jiǎn)單。
然后,在需要繪制的時(shí)候,調(diào)用這個(gè)函數(shù)即可??梢酝ㄟ^(guò)參數(shù)來(lái)解決細(xì)微差異〔圖案的坐標(biāo)、顏色等,例如:
#include<graphics.h>
#include<conio.h>
//在坐標(biāo)<x,y>處,用顏色c繪制三角形
voidsanjiaoxing<intx,inty,intc>
{
//設(shè)置畫(huà)線顏色
setcolor<c>;
//畫(huà)三角形的三條邊
line<x,y,x+50,y>;
line<x,y,x,y+50>;
line<x+50,y,x,y+50>;
}
voidmain<>
{
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<>;//按任意鍵繼續(xù)
closegraph<>;//關(guān)閉圖形窗口
}
再結(jié)合循環(huán)等控制條件,就能繪制更復(fù)雜漂亮的圖案了。試試運(yùn)行下面程序,理解一下函數(shù)的用處:
#include<graphics.h>
#include<conio.h>
voidsanjiaoxing<intx,inty,intcolor>
{
//設(shè)置畫(huà)線顏色
setcolor<color>;
//畫(huà)三角形的三條邊
line<x,y,x+10,y>;
line<x,y,x,y+10>;
line<x+10,y,x,y+10>;
}
voidmain<>
{
initgraph<640,480>;//初始化圖形窗口
for<intx=0;x<640;x+=10>
for<inty=0;y<480;y+=10>
sanjiaoxing<x,y,RGB<x*255/640,y*255/480,0>>;
getch<>;//按任意鍵繼續(xù)
closegraph<>;//關(guān)閉圖形窗口
}運(yùn)行效果:本節(jié)作業(yè):
1.繪制Windows自帶游戲"掃雷"的初始界面。9:繪圖中的位運(yùn)算位運(yùn)算和繪圖有什么關(guān)系?先舉個(gè)例子來(lái)個(gè)感性認(rèn)識(shí):使用XOR運(yùn)算可以實(shí)現(xiàn)擦除圖形后不破壞背景,這在時(shí)鐘程序中繪制表針是很有用的。稍后我們會(huì)給出這樣的例子。
一、位運(yùn)算的運(yùn)算法則
位運(yùn)算主要分4種:NOT、AND、OR、XOR
位運(yùn)算的運(yùn)算對(duì)象是二進(jìn)制數(shù)〔十進(jìn)制要轉(zhuǎn)換為二進(jìn)制,計(jì)算機(jī)會(huì)自動(dòng)轉(zhuǎn)換。
運(yùn)算法則如下:
1.NOT
表示"取反",將二進(jìn)制位的1變0、0變1。
C語(yǔ)言用符號(hào)~表示。
如:
二進(jìn)制:~1101=0010
用十進(jìn)制表示就是:~13=2
2.AND
表示"并且",只有兩數(shù)的對(duì)應(yīng)二進(jìn)制位都為1,結(jié)果的二進(jìn)制位才為1;否則,結(jié)果的二進(jìn)制位為0。
C語(yǔ)言用符號(hào)&表示。
如:
二進(jìn)制:1101&0110=0100
用十進(jìn)制表示就是:13&6=4
3.OR
表示"或者",兩數(shù)的對(duì)應(yīng)二進(jìn)制位只要有一個(gè)是1,結(jié)果的二進(jìn)制位就是1;否則,結(jié)果的二進(jìn)制位為0。
C語(yǔ)言用符號(hào)|表示。
如:
二進(jìn)制:0101|0110=0111
用十進(jìn)制表示就是:5|6=7
4.XOR
表示"異或",兩數(shù)的對(duì)應(yīng)二進(jìn)制位不同,結(jié)果的二進(jìn)制位為1;相同,結(jié)果的二進(jìn)制位為0。
C語(yǔ)言用符號(hào)^表示。
如:
二進(jìn)制:0101^1110=1011
以上只是簡(jiǎn)單介紹一下,詳細(xì)的還是請(qǐng)大家看課本上的講解。
二、位運(yùn)算的應(yīng)用
位運(yùn)算的應(yīng)用很多,例如AND和OR在獲取和設(shè)置標(biāo)志位時(shí)經(jīng)常使用。更多的,以后大家會(huì)逐漸遇到,暫時(shí)先記下有這么回事。
這里著重說(shuō)一下XOR運(yùn)算,它有一個(gè)重要的特性:
<a^b>^b=a
也就是說(shuō),a^b之后可能是某些其它數(shù)字,但是只要再^b一下,就又成了a。
一些簡(jiǎn)單的加密就用的XOR的這個(gè)特性。
至于繪圖,假如a是背景圖案,b是將要繪制的圖案,只要用XOR方式繪圖,連續(xù)繪兩次,那么背景是不變的。
三、演示
我們來(lái)一個(gè)簡(jiǎn)單的繪圖XOR運(yùn)算演示:
#include<graphics.h>
#include<conio.h>
voidmain<>
{
initgraph<640,480>;
//初始化640x480的繪圖窗口
setlinestyle<PS_SOLID,NULL,10>;//設(shè)置線寬為10,這樣效果明顯
rectangle<100,100,200,200>;//畫(huà)一個(gè)矩形,當(dāng)做背景圖案
setwritemode<R2_XORPEN>;//設(shè)置XOR繪圖模式
setcolor<RED>;
//設(shè)置畫(huà)線顏色
line<50,0,200,300>;
//畫(huà)線
getch<>;
//等待按任意鍵
line<50,0,200,300>;
//畫(huà)線〔XOR方式重復(fù)畫(huà)線會(huì)恢復(fù)背景圖案
getch<>;
//等待按任意鍵
closegraph<>;
//關(guān)閉繪圖窗口
}
運(yùn)行一下,看到第一次畫(huà)線后,矩形與直線相交的部分,顏色變成了青色,青色就是白色和紅色XOR的值。當(dāng)再次以紅色畫(huà)線時(shí),青色部分消失了,還原為完整的白色矩形框。
四、完整的范例
來(lái)一個(gè)相對(duì)完整的范例吧,就是鐘表程序,三個(gè)表針用的都是XOR方式繪制,請(qǐng)大家運(yùn)行體會(huì)一下XOR的作用:
#include<graphics.h>
#include<conio.h><\o"累計(jì)分享1次"1>回復(fù)1樓2010-05-2309:57舉報(bào)
|BestAns吧主9#include<math.h>
voidDraw<inthour,intminute,intsecond>
{
doublea_hour,a_min,a_sec;
//時(shí)、分、秒針的弧度值
intx_hour,y_hour,x_min,y_min,x_sec,y_sec;//時(shí)、分、秒針的末端位置
//計(jì)算時(shí)、分、秒針的弧度值
a_sec=second*2*PI/60;
a_min=minute*2*PI/60+a_sec/60;
a_hour=hour*2*PI/12+a_min/12;
//計(jì)算時(shí)、分、秒針的末端位置
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>>;
//畫(huà)時(shí)針
setlinestyle<PS_SOLID,NULL,10>;
setcolor<WHITE>;
line<320,240,x_hour,y_hour>;
//畫(huà)分針
setlinestyle<PS_SOLID,NULL,6>;
setcolor<LIGHTGRAY>;
line<320,240,x_min,y_min>;
//畫(huà)秒針
setlinestyle<PS_SOLID,NULL,2>;
setcolor<RED>;
line<320,240,x_sec,y_sec>;
}
voidmain<>
{
initgraph<640,480>;
//初始化640x480的繪圖窗口
//繪制一個(gè)簡(jiǎn)單的表盤(pán)
circle<320,240,2>;
circle<320,240,60>;
circle<320,240,160>;
outtextxy<296,300,"BestAns">;
//設(shè)置XOR繪圖模式
setwritemode<R2_XORPEN>;//設(shè)置XOR繪圖模式
//繪制表針
SYSTEMTIMEti;
//定義變量保存當(dāng)前時(shí)間
while<!kbhit<>>
//按任意鍵退出鐘表程序
{
GetLocalTime<&ti>;
//獲取當(dāng)前時(shí)間
Draw<ti.wHour,ti.wMinute,ti.wSecond>;
//畫(huà)表針
Sleep<1000>;
//延時(shí)1秒
Draw<ti.wHour,ti.wMinute,ti.wSecond>;
//擦表針〔擦表針和畫(huà)表針的過(guò)程是一樣的
}
closegraph<>;
//關(guān)閉繪圖窗口
}
五、作業(yè)
最后給出的繪制時(shí)鐘的例子,很不完善,有不少問(wèn)題。請(qǐng)完善該程序。例如樣式上,表盤(pán)上沒(méi)有刻度,沒(méi)有數(shù)字,指針靠中心的一端應(yīng)該長(zhǎng)出來(lái)一點(diǎn)點(diǎn),表盤(pán)太簡(jiǎn)單。還有就是嘗試發(fā)現(xiàn)并改進(jìn)功能實(shí)現(xiàn)上的問(wèn)題。10:用鼠標(biāo)控制繪圖/游戲程序捕獲鼠標(biāo)消息就像捕獲按鍵消息一樣簡(jiǎn)單。
對(duì)于按鍵,通常我們會(huì)先檢查是否有按鍵,然后定義一個(gè)變量保存按鍵,再然后根據(jù)該按鍵的值,執(zhí)行相應(yīng)的程序。
對(duì)于鼠標(biāo),道理是一樣的。
先寫(xiě)個(gè)代碼對(duì)比一下:
獲取按鍵:
獲取鼠標(biāo):
charc;
MOUSEMSGm;
if<kbhit<>>
if<MouseHit<>>
c=getch<>;
m=GetMouseMsg<>;
很簡(jiǎn)單吧。由于鼠標(biāo)消息的內(nèi)容太多,不像按鍵那么簡(jiǎn)單,因此需要用一個(gè)結(jié)構(gòu)體來(lái)保存。通過(guò)該結(jié)構(gòu)體,我們可以獲取鼠標(biāo)的如下信息:
structMOUSEMSG
{
UINTuMsg;
//當(dāng)前鼠標(biāo)消息
boolmkCtrl;
//Ctrl鍵是否按下
boolmkShift;
//Shift鍵是否按下
boolmkLButton;//鼠標(biāo)左鍵是否按下
boolmkMButton;//鼠標(biāo)中鍵是否按下
boolmkRButton;//鼠標(biāo)右鍵是否按下
intx;
//當(dāng)前鼠標(biāo)x坐標(biāo)
inty;
//當(dāng)前鼠標(biāo)y坐標(biāo)
intwheel;
//鼠標(biāo)滾輪滾動(dòng)值
};
其中,"當(dāng)前鼠標(biāo)消息"可能是以下值:
WM_MOUSEMOVE
鼠標(biāo)移動(dòng)消息
WM_MOUSEWHEEL
鼠標(biāo)滾輪撥動(dòng)消息
WM_LBUTTONDOWN
左鍵按下消息
WM_LBUTTONUP
左鍵彈起消息
WM_LBUTTONDBLCLK左鍵雙擊消息
WM_MBUTTONDOWN
中鍵按下消息
WM_MBUTTONUP
中鍵彈起消息
WM_MBUTTONDBLCLK中鍵雙擊消息
WM_RBUTTONDOWN
右鍵按下消息
WM_RBUTTONUP
右鍵彈起消息
WM_RBUTTONDBLCLK右鍵雙擊消息
例如,判斷獲取的消息是否是鼠標(biāo)左鍵按下,可以用:
if<m.uMsg==WM_LBUTTONDOWN>...
下面舉一個(gè)綜合的例子〔我偷點(diǎn)懶,直接粘貼的繪圖庫(kù)幫助里面的鼠標(biāo)范例,該程序會(huì)用紅色的點(diǎn)標(biāo)出鼠標(biāo)移動(dòng)的軌跡,按左鍵畫(huà)一個(gè)小方塊,按Ctrl+左鍵畫(huà)一個(gè)大方塊,按右鍵退出:
#include<graphics.h>
#include<time.h>
#include<conio.h>
voidmain<>
{
//初始化圖形窗口
initgraph<640,480>;<\o"累計(jì)分享1次"1>回復(fù)1樓2010-05-2309:59舉報(bào)
|BestAns吧主9
MOUSEMSGm;
//定義鼠標(biāo)消息
while<true>
{
//獲取一條鼠標(biāo)消息
m=GetMouseMsg<>;
switch<m.uMsg>
{
caseWM_MOUSEMOVE:
//鼠標(biāo)移動(dòng)的時(shí)候畫(huà)紅色的小點(diǎn)
putpixel<m.x,m.y,RED>;
break;
caseWM_LBUTTONDOWN:
//如果點(diǎn)左鍵的同時(shí)按下了Ctrl鍵
if<m.mkCtrl>
//畫(huà)一個(gè)大方塊
rectangle<m.x-10,m.y-10,m.x+10,m.y+10>;
else
//畫(huà)一個(gè)小方塊
rectangle<m.x-5,m.y-5,m.x+5,m.y+5>;
break;
caseWM_RBUTTONUP:
return;
//按鼠標(biāo)右鍵退出程序
}
}
//關(guān)閉圖形窗口
closegraph<>;
}
[本節(jié)作業(yè)]
1.畫(huà)一個(gè)填充的三角形,要用鼠標(biāo)點(diǎn)選三角形的三個(gè)頂點(diǎn)。提示:可以用fillpoly函數(shù)畫(huà)多邊形。
2.寫(xiě)一個(gè)"涂格子〔也叫點(diǎn)燈"的游戲。詳細(xì)規(guī)則可以試玩網(wǎng)上的各種版本。
3.如果有精力,嘗試寫(xiě)一個(gè)掃雷吧〔這個(gè)有點(diǎn)難度,能實(shí)現(xiàn)多少就實(shí)現(xiàn)多少,無(wú)法實(shí)現(xiàn)的功能先放下。11:隨機(jī)函數(shù)[隨機(jī)函數(shù)簡(jiǎn)介]游戲中,許多情況都是隨即發(fā)生的。還有一些圖案程序,例如屏保,也是隨即運(yùn)動(dòng)的。這就需要用隨機(jī)函數(shù)。隨機(jī)函數(shù)很簡(jiǎn)單,只有一個(gè):rand<>該函數(shù)返回0~32767之間的一個(gè)整數(shù)。<不需要記住32767這個(gè)數(shù)字,大概知道這個(gè)范圍就行了>該函數(shù)在頭文件<stdlib.h>中,使用前記得引用。[簡(jiǎn)單測(cè)試]來(lái)寫(xiě)個(gè)程序測(cè)試一下:#include<stdio.h>#include<stdlib.h>voidmain<>{
intr;
for<inti=0;i<10;i++>
{
r=rand<>;
printf<"%d\n",r>;
}}執(zhí)行后,可以看到輸出了10個(gè)隨機(jī)數(shù)字。[指定范圍的隨機(jī)函數(shù)]實(shí)際中,我們經(jīng)常要產(chǎn)生指定范圍的隨機(jī)函數(shù),通常我們用求余數(shù)的辦法。例如,產(chǎn)生0~9之間的隨機(jī)數(shù),只需要將任意產(chǎn)生的隨機(jī)數(shù)除以10求余數(shù)即可。求余數(shù)的運(yùn)算符號(hào)是%,我們可以這樣做:
r=rand<>%10;修改前面的測(cè)試程序執(zhí)行后可以看到,產(chǎn)生的數(shù)字都是小于10的。如果是1~6之間的怎樣求呢?
r=rand<>%6+1;無(wú)論產(chǎn)生什么樣范圍的隨機(jī)函數(shù),都是通過(guò)各種運(yùn)算將隨機(jī)數(shù)的范圍[0,32767]修改為自己需要的范圍。[隨機(jī)種子]做了多次試驗(yàn),我們會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題:雖然產(chǎn)生的數(shù)字是隨機(jī)的,但每次產(chǎn)生的數(shù)字序列都一樣。為了解決這個(gè)問(wèn)題,我們需要用"隨機(jī)種子"。隨機(jī)函數(shù)的產(chǎn)生原理簡(jiǎn)單來(lái)說(shuō),就是:前一個(gè)隨機(jī)函數(shù)的值,決定下一個(gè)隨機(jī)函數(shù)的值。根據(jù)這個(gè)原理我們可以知道:只要第一個(gè)隨機(jī)函數(shù)的值確定了,那么后面數(shù)字序列就是確定的。如果我們想的得到不同的數(shù)字序列,我們需要確定第一個(gè)隨機(jī)函數(shù)的值,對(duì)于設(shè)置第一個(gè)隨機(jī)函數(shù)的值,叫做設(shè)置"隨機(jī)種子"。易知,隨機(jī)種子設(shè)置一次即可。設(shè)置隨機(jī)種子的函數(shù)如下:srand<種子>;通常,我們用當(dāng)前時(shí)間來(lái)做隨機(jī)種子:srand<<unsigned>time<NULL>>;因?yàn)槭褂胻ime函數(shù),所以記得引用<time.h>。[繪圖中的應(yīng)用]來(lái)一個(gè)簡(jiǎn)單的程序,在屏幕上任意位置畫(huà)任意顏色的點(diǎn)<按任意鍵退出>:#include<graphics.h>#include<stdlib.h>#include<conio.h>#include<time.h>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<>;}[作業(yè)]1.回顧一下第6課"實(shí)現(xiàn)簡(jiǎn)單動(dòng)畫(huà)"的作業(yè):繪制一個(gè)沿45度移動(dòng)的球,碰到窗口邊界后反彈。將這個(gè)球改為任意方向運(yùn)動(dòng),碰到邊界后任意反彈。12:數(shù)組[一維數(shù)組]
數(shù)組可以實(shí)現(xiàn)批量操作。比如,我們產(chǎn)生10個(gè)隨機(jī)數(shù),產(chǎn)生后先保存起來(lái),然后輸出最大的:
intn[10];
inti;
for<i=0;i<10;i++>
n[i]=rand<>%1000;
//按生成的順序,逆序輸出
for<i=9;i>=0;i-->
printf<"%d\n",n[i]>;
//找出最大的
intmax=-1;
for<i=0;i<10;i++>
{
if<n[i]>max>
max=n[i];
}
printf<"最大的數(shù)字是:%d\n",max>;
看明白這個(gè)程序后,我們繼續(xù)。
下面,我們繪制一個(gè)從屏幕上邊任意位置往下落的白色點(diǎn):
#include<graphics.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
voidmain<>
{
srand<<unsigned>time<NULL>>;
initgraph<640,480>;
intx=rand<>%640;
//點(diǎn)的x坐標(biāo)
inty=0;
//點(diǎn)的y坐標(biāo)
while<!kbhit<>>
{
//擦掉前一個(gè)點(diǎn)
putpixel<x,y,BLACK>;
//計(jì)算新坐標(biāo)
y+=3;
if<y>=480>break;
//繪制新點(diǎn)
putpixel<x,y,WHITE>;
Sleep<10>;
}
closegraph<>;
}
現(xiàn)在利用數(shù)組,來(lái)產(chǎn)生100個(gè)隨機(jī)下落的點(diǎn)。并且每個(gè)點(diǎn)落到底部后,就回到頂部重新往下落:
#include<graphics.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
voidmain<>
{
srand<<unsigned>time<NULL>>;
initgraph<640,480>;
//定義點(diǎn)的坐標(biāo)數(shù)組
intx[100];
//點(diǎn)的x坐標(biāo)
inty[100];
//點(diǎn)的y坐標(biāo)
inti;
//初始化點(diǎn)的初始坐標(biāo)
for<i=0;i<100;i++>
{
x[i]=rand<>%640;<\o"累計(jì)分享0次"0>回復(fù)1樓2010-05-2811:12舉報(bào)
|BestAns吧主9
y[i]=rand<>%480;
}
while<!kbhit<>>
{
for<i=0;i<100;i++>
{
//擦掉前一個(gè)點(diǎn)
putpixel<x[i],y[i],BLACK>;
//計(jì)算新坐標(biāo)
y[i]+=3;
if<y[i]>=480>y[i]=0;
//繪制新點(diǎn)
putpixel<x[i],y[i],WHITE>;
}
Sleep<10>;
}
closegraph<>;
}
[二維數(shù)組]
理解了一維數(shù)組,再看二維數(shù)組甚至多維數(shù)組,就簡(jiǎn)單多了,看下面程序理解一下二維數(shù)組:
程序要求:屏幕上有16x8的方格,按隨機(jī)順序在將1~128的數(shù)字寫(xiě)到每個(gè)格子上。
考慮:我們需要記錄這些格子,哪些寫(xiě)過(guò)數(shù)字,哪些沒(méi)寫(xiě)數(shù)字。
我們用一個(gè)二維數(shù)組來(lái)記錄:
boolcell[16][8];
寫(xiě)過(guò)數(shù)字后,我們將相應(yīng)數(shù)組的值設(shè)置為true,看程序:
#include<graphics.h>
#include<stdlib.h>
#include<conio.h>
#include<stdio.h>
#include<time.h>
voidmain<>
{
intx,y;
charnum[4];
srand<<unsigned>time<NULL>>;
initgraph<640,480>;
//畫(huà)格子
for<x=0;x<=480;x+=30>
for<y=0;y<=240;y+=30>
{
line<x,0,x,240>;
line<0,y,480,y>;
}
//定義二維數(shù)組
boolcell[16][8];
//初始化二維數(shù)組
for<x=0;x<16;x++>
for<y=0;y<8;y++>
cell[x][y]=false;
//在每個(gè)格子上寫(xiě)數(shù)字
for<inti=1;i<=128;i++>
{
//找到一個(gè)沒(méi)有寫(xiě)數(shù)字的隨機(jī)格子
do
{
x=rand<>%16;
y=rand<>%8;
}while<cell[x][y]==true>;
//標(biāo)記該格子已用
cell[x][y]=true;
//在格子上寫(xiě)數(shù)字
sprintf<num,"%d",i>;
outtextxy<x*30,y*30,num>;
}
getch<>;
closegraph<>;
}
以上幾個(gè)范例,無(wú)論從實(shí)用上還是美觀上都很差,我只是希望大家能舉一反三,寫(xiě)出更多漂亮的程序。
[作業(yè)]
1.回顧一下上一節(jié)課的作業(yè),繪制一個(gè)任意反彈的球。這次,將程序修改成屏幕上有10個(gè)任意反彈的球。
2.如果反彈的不是球,而是點(diǎn)呢?再將某些點(diǎn)之間用線連起來(lái),就可以做一個(gè)屏保"變幻線"的程序了。試試做一個(gè)。
3.看完前面的12節(jié)課,像貪吃蛇、俄羅斯方塊這樣的程序都可以做了吧,有時(shí)間就嘗試寫(xiě)一下。如果遇到問(wèn)題,貼吧里貼出來(lái),大家一起討論。13:getimage/putimage/IMAGE的用法getimage/putimage這一組命令和IMAGE對(duì)象可以實(shí)現(xiàn)加載圖片或保存指定區(qū)域等功能,下面逐個(gè)介紹?!灿悬c(diǎn)類似tc中的imagesize[加載圖片]實(shí)現(xiàn)加載圖片主要分三步:1.定義IMAGE對(duì)象2.讀取圖片至IMAGE對(duì)象3.顯示IMAGE對(duì)象很簡(jiǎn)單,我們看一下完整的代碼:#include<graphics.h>#include<conio.h>voidmain<>{
initgraph<640,480>;
IMAGEimg;
//定義IMAGE對(duì)象
getimage<&img,"C:\\test.jpg">;
//讀取圖片
putimage<0,0,&img>;
//顯示IMAGE對(duì)象
getch<>;
closegraph<>;}記得把要顯示的圖片是C:\test.jpg,你可以修改為自己的圖片路徑。[保存屏幕區(qū)域]和加載圖片類似,我們可以從屏幕的某個(gè)區(qū)域加載圖像至IMAGE對(duì)象,然后再putimage到需要的地方。獲取屏幕區(qū)域的代碼格式:getimage<IMAGE&img,intx,inty,intw,inth>;參數(shù)說(shuō)明:
img:保存該屏幕區(qū)域的IMAGE對(duì)象
x,y:區(qū)域的左上角坐標(biāo)
w,h:區(qū)域的寬和高〔注意:不是右下角坐標(biāo)看代碼:#include<graphics.h>#include<conio.h>voidmain<>{
initgraph<640,480>;
//定義IMAGE對(duì)象
IMAGEimg;
//繪制內(nèi)容
circle<100,100,20>;
line<70,100,130,100>;
line<100,70,100,130>;
//保存區(qū)域至img對(duì)象
getimage<&img,70,70,60,60>;
//將img對(duì)對(duì)象顯示在屏幕的某個(gè)位置
putimage<200,200,&img>;
getch<>;
closegraph<>;}[移動(dòng)復(fù)雜的圖案]復(fù)雜的圖案如果要移動(dòng),每次都重新繪制顯然效率很低,移動(dòng)的時(shí)候會(huì)出現(xiàn)嚴(yán)重的屏幕閃爍。而getimage/putimage的效率十分高,我們可以將復(fù)雜的圖案用getimage保存下來(lái),然后再逐步putimage實(shí)現(xiàn)復(fù)雜圖案的移動(dòng)。這個(gè)代碼就不舉例了,作為作業(yè)大家練習(xí)吧。[更多的功能]getimage/putimage有許多重載,這里就不多介紹了,詳細(xì)看看幫助中的描述吧。[作業(yè)]1.用線條、圓等各種基礎(chǔ)繪圖語(yǔ)句畫(huà)一個(gè)"汽車(chē)",然后用getimage/putimage實(shí)現(xiàn)該"汽車(chē)"的平滑移動(dòng)。2.自己學(xué)一下幫助中BeginBatchDraw/FlushBatchDraw/EndBatchDraw三個(gè)函數(shù),可以進(jìn)一步優(yōu)化"平滑移動(dòng)"的效果。這三個(gè)命令挺簡(jiǎn)單的,一看就懂。14:通過(guò)位運(yùn)算實(shí)現(xiàn)顏色的分離與處理[顏色基礎(chǔ)]
在EasyX庫(kù)中,顏色是一個(gè)int類型的數(shù)據(jù),轉(zhuǎn)換為16進(jìn)制后的顏色格式是0xbbggrr,其中,bb/gg/rr分別表示兩位十六進(jìn)制的藍(lán)/綠/紅顏色值,每種顏色的范圍是0x0~0xff,轉(zhuǎn)換為十進(jìn)制就是0~255。
舉幾個(gè)顏色標(biāo)示的例子:
顏色
直接表示
RGB宏標(biāo)示
純綠色
0x00ff00
RGB<0,255,0>
青色
0xffff00
RGB<255,255,0>
注:青=藍(lán)+綠
中灰色
0x7f7f7f
RGB<127,127,127>
黃色
0x00ffff
RGB<0,255,255>
注:黃=紅+綠
例如設(shè)置繪圖顏色為黃色,可以多種方法,例如:
setcolor<YELLOW>;
setcolor<RGB<0,255,255>>;
setcolor<0x00ffff>;
[獲取顏色]
getpixel是用來(lái)獲取屏幕顏色的函數(shù),其返回值為int類型的顏色。例如:
intc=getpixel<100,100>;
該語(yǔ)句將返回坐標(biāo)<100,100>位置的顏色。
[顏色分離與處理]
有時(shí)候我們需要修改顏色某一位的值,這時(shí),可以通過(guò)位運(yùn)算來(lái)實(shí)現(xiàn)。
比如,我們想把某一個(gè)點(diǎn)的顏色的紅色部分去掉,可以這么做:
intc=getpixel<100,100>;
c&=0xffff00;
putpixel<100,100>;
我們來(lái)看一個(gè)完整的程序,這個(gè)程序,將圖片左半部中的紅色"去掉"了,就像是顯示器"缺色"的效果:
#include<graphics.h>
#include<conio.h>
voidmain<>
{
initgraph<640,480>;
//讀取圖片
IMAGEimg;
getimage<&img,"c:\\test.jpg">;
putimage<0,0,&img>;
intc;
for<intx=0;x<320;x++>
for<inty=0;y<480;y++>
{
c=getpixel<x,y>;
c=<0xff0000-<c&0xff0000>>|<0x00ff00-<c&0x00ff00>>|<0x0000ff-<c&0x0000ff>>;
putpixel<x,y,c>;
}
getch<>;
closegraph<>;
}
找到這行:
c&=0xffff00;
我們修改為:
c=<0xff0000-<c&0xff0000>>|<0x00ff00-<c&0x00ff00>>|<0x0000ff-<c&0x0000ff>>;
在執(zhí)行看看效果,就成了照片的底片效果。
[作業(yè)]
1.實(shí)現(xiàn)提高/降低圖像亮度的程序。
2.自己搜索"灰度算法",實(shí)現(xiàn)彩色圖像轉(zhuǎn)換為灰度圖像。<\o"累計(jì)分享0次"0>回復(fù)1樓2010-06-2714:37舉報(bào)
|BestAns吧主9關(guān)于效率問(wèn)題,
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 合同管理新規(guī):勞動(dòng)合同效力變化分析
- 購(gòu)銷(xiāo)合同擔(dān)保書(shū)
- 蘇教版三年級(jí)語(yǔ)文教學(xué)計(jì)劃
- 2 不同材料的餐具 教學(xué)設(shè)計(jì)-2024-2025學(xué)年科學(xué)二年級(jí)上冊(cè)教科版
- 2 折筆帽(教學(xué)設(shè)計(jì))蘇教版一年級(jí)下冊(cè)綜合實(shí)踐活動(dòng)
- 藥店連鎖品牌加盟合同轉(zhuǎn)讓協(xié)議
- 股東合作發(fā)展合同范本大全
- 10 我們當(dāng)?shù)氐娘L(fēng)俗 第一課時(shí) 教學(xué)設(shè)計(jì)-2023-2024學(xué)年道德與法治四年級(jí)下冊(cè)統(tǒng)編版
- 4 少讓父母為我操心 教學(xué)設(shè)計(jì)-2023-2024學(xué)年道德與法治四年級(jí)上冊(cè)統(tǒng)編版
- 2023-2024學(xué)年人教版(2015)小學(xué)信息技術(shù)四年級(jí)下冊(cè)個(gè)性表格巧制作(教學(xué)設(shè)計(jì))
- 2024-2025年天津河西區(qū)七年級(jí)上學(xué)期期末道德與法治試題(含答案)
- 預(yù)制板粘貼碳纖維加固計(jì)算表格
- 2025年海南農(nóng)墾自然資源開(kāi)發(fā)集團(tuán)有限公司筆試題
- 2023CSCO兒童及青少年白血病診療指南
- 醫(yī)療垃圾轉(zhuǎn)運(yùn)流程
- 礦棉板模板施工合同
- DB31∕T 1148-2019 水量計(jì)量差錯(cuò)的退補(bǔ)水量核算方法
- 2025蛇年元旦晚會(huì)
- 延長(zhǎng)石油社招筆試題庫(kù)
- 《傳媒法的原則》課件
- 工地早班會(huì)活動(dòng)記錄表(普工、塔司、信號(hào)工)
評(píng)論
0/150
提交評(píng)論