《見縫插圓》顧名思義,就是在我們繪制的C語(yǔ)言窗口里面畫隨機(jī)圓,圓與圓之間不能相交或相切,那就要自己找“縫隙”咯!
今天用C語(yǔ)言制一些漂亮的隨機(jī)圖案,如圖所示,隨機(jī)生成的圓互不相交且盡量填滿畫布,按空格鍵可以切換不同的繪制模式:
首先利用數(shù)組實(shí)現(xiàn)多個(gè)圓的生成和繪制,并使得圓和圓之間不相交;然后學(xué)習(xí)函數(shù)的概念,并應(yīng)用函數(shù)改進(jìn)代碼,添加了新圓半徑最大化的功能;最后利用函數(shù)封裝了多種繪制模式,并通過(guò)鍵盤按鍵進(jìn)行互動(dòng)。
源碼示例:
// 求解兩個(gè)點(diǎn)之間的距離
float Dist2Points(float x1,float y1,float x2,float y2)
{
float result;
result = sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2));
return result;
}
// 判斷兩個(gè)圓是否相交
int isTwoCirclesIntersect(float x1,float y1,float r1,float x2,float y2,float r2)
{
if (Dist2Points(x1,y1,x2,y2)
return 1;
return 0;
}
// 填充黃色圓繪制
void DrawCircles1(float x,float y,float r)
{
setlinecolor(RGB(0,0,0));
setfillcolor(RGB(255,255,0));
fillcircle(x,y,r);
}
// 填充隨機(jī)顏色圓繪制
void DrawCircles2(float x,float y,float r)
{
float h = rand()%360;
COLORREF color = HSVtoRGB(h,0.6,0.8);
setlinecolor(RGB(255,255,255));
setfillcolor(color);
fillcircle(x,y,r);
}
// 填充隨機(jī)顏色同心圓繪制
void DrawCircles3(float x,float y,float r)
{
while (r>0)
{
float h = rand()%360;
COLORREF color = HSVtoRGB(h,0.6,0.8);
setlinecolor(RGB(255,255,255));
setfillcolor(color);
fillcircle(x,y,r);
r=r-5;
}
}
// 隨機(jī)顏色同心圓線條繪制
void DrawCircles4(float x,float y,float r)
{
while (r>0)
{
float h = rand()%360;
COLORREF color = HSVtoRGB(h,0.9,0.8);
setlinecolor(color);
circle(x,y,r);
r=r-5;
}
}
int main() // 主函數(shù)
{
int width = 600; // 窗口寬度
int height = 600; // 窗口高度
initgraph(width,height); // 新開一個(gè)窗口
setbkcolor(RGB(255,255,255)); // 背景顏色為白色
cleardevice(); // 以背景顏色清空背景
srand(time(0)); // 隨機(jī)種子函數(shù)
int xArray[1000]; // 數(shù)組存儲(chǔ)所有圓心的x坐標(biāo)
int yArray[1000]; // 數(shù)組存儲(chǔ)所有圓心的y坐標(biāo)
int rArray[1000]; // 數(shù)組存儲(chǔ)所有圓的半徑
int rmin = 8; // 圓的最小半徑
int rmax = 50; // 圓的最大半徑
int circleNum = 0; // 生成的圓的個(gè)數(shù)
float x,y,r; // 新增圓的圓心坐標(biāo)、半徑
int isNewCircleOK; // 用于判斷新生成的圓是否可以了
int i,j;
int drawMode = 3; // 用于設(shè)定4種不同的繪制模式,開始設(shè)為3
while (circleNum<1000) // 當(dāng)圓的個(gè)數(shù)小于100時(shí),循環(huán)運(yùn)行
{
isNewCircleOK = 0; // 假設(shè)開始不OK
while (isNewCircleOK==0) // 當(dāng)新生成的圓不Ok時(shí),重復(fù)生成新圓進(jìn)行比較
{
if (kbhit()) // 當(dāng)按鍵時(shí)
{
char input = _getch(); // 獲得用戶按鍵
if (input==' ') // 空格鍵
{
circleNum = 0; // 圓的個(gè)數(shù)為0,相當(dāng)于畫面清除所有已有的圓圈
cleardevice(); // 清屏
drawMode = drawMode+1; // 進(jìn)行下一種繪圖模式
if (drawMode>4) // 如果大于4,重新回到第1種繪圖模式
drawMode = 1;
}
}
x = rand() % width; // 新圓的圓心x坐標(biāo)
y = rand() % height; // 新圓的圓心y坐標(biāo)
r = rmin; // 新圓的半徑開始設(shè)為最小半徑
for (i=0;i// 對(duì)已有圓遍歷
if (isTwoCirclesIntersect(xArray[i],yArray[i],rArray[i],x,y,r))
break; // 如果已有圓和新圓相交,跳出循環(huán),此時(shí)i
if (i==circleNum) // 如果上面for語(yǔ)句都不跳出,說(shuō)明i等于circleNum
isNewCircleOK = 1; // 這個(gè)新生成的圓和已有圓都不相交
}
isNewCircleOK = 0; // 繼續(xù)設(shè)為不OK,下面要讓這個(gè)新圓的半徑最大
while (isNewCircleOK==0 && r// 當(dāng)不ok,并且新圓的半徑小于最大半徑時(shí)
{
r++; // 讓半徑+1
for (j=0;j// 對(duì)所有舊圓遍歷
{
if (isTwoCirclesIntersect(xArray[j],yArray[j],rArray[j],x,y,r))
{
isNewCircleOK = 1; // 一旦和一個(gè)舊圓相交,這時(shí)新圓Ok
break; // 因?yàn)樾聢A半徑已經(jīng)達(dá)到最大的情況,這時(shí)跳出循環(huán)
}
}
}
xArray[circleNum] = x; // 把新圓的圓心坐標(biāo)添加到數(shù)組中
yArray[circleNum] = y; //
rArray[circleNum] = r; // 把新圓的半徑添加到數(shù)組中
circleNum++; // 圓的個(gè)數(shù)+1
// 根據(jù)不同繪圖模式進(jìn)行繪制
if (drawMode==1)
DrawCircles1(x,y,r);
if (drawMode==2)
DrawCircles2(x,y,r);
if (drawMode==3)
DrawCircles3(x,y,r);
if (drawMode==4)
DrawCircles4(x,y,r);
Sleep(10); // 暫停若干毫秒
}
_getch(); // 等待按鍵輸入
closegraph(); // 關(guān)閉窗口
return 0;
}
這一章主要講解了二維數(shù)組、函數(shù)封裝,按鍵操作等語(yǔ)法知識(shí),利用C語(yǔ)言游戲開發(fā)框架,實(shí)現(xiàn)了見縫插圓游戲。
希望對(duì)大家有幫助!
審核編輯 :李倩
-
C語(yǔ)言
+關(guān)注
關(guān)注
180文章
7614瀏覽量
137468 -
代碼
+關(guān)注
關(guān)注
30文章
4823瀏覽量
68916
原文標(biāo)題:C語(yǔ)言實(shí)現(xiàn)見縫插圓游戲!零基礎(chǔ)代碼思路+源碼分享
文章出處:【微信號(hào):cyuyanxuexi,微信公眾號(hào):C語(yǔ)言編程學(xué)習(xí)基地】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論