VC-easyx繪圖游戲簡(jiǎn)易教程_第1頁(yè)
VC-easyx繪圖游戲簡(jiǎn)易教程_第2頁(yè)
VC-easyx繪圖游戲簡(jiǎn)易教程_第3頁(yè)
VC-easyx繪圖游戲簡(jiǎn)易教程_第4頁(yè)
VC-easyx繪圖游戲簡(jiǎn)易教程_第5頁(yè)
已閱讀5頁(yè),還剩25頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論