接上篇,小球可以自由觸碰各個方向并反彈之后,下面我們來制作擋板,并讓擋板可以按照我們的規(guī)則控制起來。
以及其他的游戲控制,如基本的暫停和繼續(xù)功能。大家可以站在用戶的角度去思考需要什么功能
接著思路想,如論是控制擋板移動,還是游戲暫停繼續(xù),都需要按鍵來接受,要不停的監(jiān)控用戶是否按下鍵,并且還需要異步接受(因為同步的話會導(dǎo)致游戲暫停?。┻@里是一個難點
這里給大家介紹一個函數(shù)叫做GetAsyncKeyState,它是一個可以異步接受用戶鍵盤輸入按鍵的函數(shù),即不會卡在這里不停的等待,而是會繼續(xù)往下執(zhí)行代碼,且還有個好處就是,運行后當(dāng)前窗口即便不是選中狀態(tài),控制臺也能接收到按鍵輸入。
為了簡單流程方便大家理解主線,我這里給大家直接提供思路,游戲擋板的左右控制用A和D來控制,游戲暫停為P,繼續(xù)為C
關(guān)于GetAsyncKeyState函數(shù)的用法,簡單說該函數(shù)會返回某個鍵的按下情況,但由于返回有高低位兩部分值,因此需要將其結(jié)果與0x8000按位與獲得,如按下C鍵的代碼則為:
GetAsyncKeyState(67) & 0x8000
返回值為1則表示按下,否則沒有按下
我們可以首先完成暫停時調(diào)用的函數(shù),其思路為寫一個循環(huán),不停的sleep即可,一旦收到跳出命令,則跳出循環(huán)結(jié)束,完整的暫停函數(shù)代碼如下:
int pause() //暫停 { while(1) { Sleep(100); if(GetAsyncKeyState(67) & 0x8000 ) //按c鍵跳出循環(huán),繼續(xù) { break; } } return 0; }
然后我們在主循環(huán)中,增加按下其他按鍵的判斷和操作,分別判斷向左向右時,即將走下一步時是否碰撞到邊界,若沒有就將小球的坐標(biāo)更新。
注意,本次代碼相比于上一版,隨著需求需要適當(dāng)規(guī)范了一些代碼,比如多定義了一些變量,如小球坐標(biāo)、擋板每次移動的步伐大小等等。
代碼如下:
if(GetAsyncKeyState(65) & 0x8000) //向左 { if(Board_x1-STEP<=0) { Board_x1=0; Board_x2=100; } else { Board_x1=Board_x1-STEP; Board_x2=Board_x2-STEP; } } if(GetAsyncKeyState(68) & 0x8000) //向右 { if(Board_x2+STEP>=WIDTH-205) { Board_x1=WIDTH-305; Board_x2=WIDTH-205; } else { Board_x1=Board_x1+STEP; Board_x2=Board_x2+STEP; } } if(GetAsyncKeyState(80) & 0x8000)//暫停 { pause(); }
可以看到多個if判斷,分別判斷是否是a鍵、是否是d鍵、以及是否是p鍵,完成后編譯程序
測試運行效果如下:
這里我嘗試了左右移動和繼續(xù)、暫停的按鈕,均得到的期望的效果(雖然屏幕上沒有提示,但可以看到效果)
大家可以根據(jù)自己情況嘗試修改。完整代碼如下:
//彈球游戲 //www.sztianhecheng.cn #include <graphics.h> // 引用圖形庫頭文件 #include <conio.h> #include <stdio.h> #define WIDTH 640 #define HIGH 480 #define R 10 #define STEP 10 int Board_x1=150,Board_y1=HIGH-5,Board_x2=250,Board_y2=HIGH; int pause() //暫停 { while(1) { Sleep(100); if(GetAsyncKeyState(67) & 0x8000 ) { break; } } return 0; } int main() { int i; char ch; int score=0; char control; TCHAR ScoreBuffer[100]={"當(dāng)前分數(shù):"}; int Vx=3,Vy=3; int x=(WIDTH-200)-100,y=HIGH/2; //表示小球初始圓心坐標(biāo) initgraph(WIDTH, HIGH); // 創(chuàng)建繪圖窗口 640x480 像素 fillrectangle(WIDTH-200,0,WIDTH-195,HIGH);//繪制右墻 BeginBatchDraw(); while(1) { //繪制小球 setfillcolor(GREEN); fillcircle(x,y,R); //繪制擋板 setfillcolor(YELLOW); fillrectangle(Board_x1,Board_y1,Board_x2,Board_y2); FlushBatchDraw(); Sleep(5); //原位置擦除小球圖案 setcolor(BLACK); setfillcolor(BLACK); fillcircle(x,y,R); //原位置擦除擋板 setfillcolor(BLACK); fillrectangle(Board_x1,Board_y1,Board_x2,Board_y2); if(GetAsyncKeyState(65) & 0x8000) //向左 { if(Board_x1-STEP<=0) { Board_x1=0; Board_x2=100; } else { Board_x1=Board_x1-STEP; Board_x2=Board_x2-STEP; } } if(GetAsyncKeyState(68) & 0x8000) //向右 { if(Board_x2+STEP>=WIDTH-205) { Board_x1=WIDTH-305; Board_x2=WIDTH-205; } else { Board_x1=Board_x1+STEP; Board_x2=Board_x2+STEP; } } if(GetAsyncKeyState(80) & 0x8000)//暫停 { pause(); } x=x+Vx; y=y+Vy; if(x<=R || x>=WIDTH-203-R) { Vx=-Vx; } if(y<=R || y>=HIGH-R) { Vy=-Vy; } } EndBatchDraw(); getch(); // 按任意鍵繼續(xù) closegraph(); // 關(guān)閉繪圖窗口 return 0; }
未完待續(xù),下一篇我們繼續(xù)~
C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍橋杯競賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點擊了解:
一點編程也不會寫的:零基礎(chǔ)C語言學(xué)練課程
解決困擾你多年的C語言疑難雜癥特性的C語言進階課程
從零到寫出一個爬蟲的Python編程課程
只會語法寫不出代碼?手把手帶你寫100個編程真題的編程百練課程
信息學(xué)奧賽或C++選手的 必學(xué)C++課程
藍橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競賽課入門課程
手把手講解近五年真題的藍橋杯輔導(dǎo)課程