C語(yǔ)言數(shù)組實(shí)現(xiàn)打磚塊游戲
本文實(shí)例為大家分享了C語(yǔ)言數(shù)組實(shí)現(xiàn)打磚塊游戲的具體代碼,供大家參考,具體內(nèi)容如下
這次我們使用數(shù)組來(lái)改進(jìn)打磚塊游戲。
反彈的球
首先我們實(shí)現(xiàn)一個(gè)可以在熒幕上反彈的小球。使用二維數(shù)組 int canvas[High][Width] ( 和js的canvas沒(méi)有一毛錢關(guān)系)來(lái)儲(chǔ)存畫(huà)布上的所有元素,值為0時(shí)輸出空格,值為1時(shí)輸出小球。
設(shè)小球坐標(biāo)為(ball_x, ball_y),則有canvas[ball_x][ball_y] = 1 ,且暫時(shí)將其他元素的值設(shè)為0。
每次更新小球位置時(shí)將原位置元素設(shè)為0,將新位置元素設(shè)為1即可。
注意:gotoxy函數(shù)用于清屏重畫(huà),很久以前講過(guò)的。
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <cwindow.h> // 畫(huà)面尺寸設(shè)定 #define High 15 #define Width 20 //全局變量 int ball_x,ball_y;?? ?//小球坐標(biāo) int ball_vx,ball_vy;//小球速度 int canvas[High][Width] = [0]; void gotoxy(int x, int y)?? ?//移動(dòng)光標(biāo)便于清屏重畫(huà) { ?? ?HANDLE handle = GetStdHandle(STD_UOTPUT_HANDLE); ?? ?CROOD pos; ?? ?pos.X = x; ?? ?pos.Y = y; ?? ?SetConsoleCursorPosition(handle, pos); } void startup()?? ??? ??? ??? ?//數(shù)據(jù)初始化 { ?? ?ball_x = 0; ?? ?ball_y = Width/2; ?? ?ball_vx = 1; ?? ?ball_vy = 1; ?? ?canvas[ball_x][ball_y] = 1; } void show() { ?? ?gotoxy(0, 0); ?? ?int i,j; ?? ?for(i=0; i<High; i++) ?? ?{ ?? ??? ?for(j=0; j<Width; j++) ?? ??? ?{ ?? ??? ??? ?if (canvas[i][j] == 0) ?? ??? ??? ??? ?printf(" ");//輸出空格 ?? ??? ??? ?else if (canvas[i][j] == 1) ?? ??? ??? ??? ?printf("O");//輸出小球 ?? ??? ?} ?? ??? ?printf("|\n");//每畫(huà)完一行顯示邊界并換行 ?? ?} ?? ?for(j=0; j<Width; j++) ?? ??? ?printf("-");//最后畫(huà)下邊界 } void updateWithoutInput()?? ?//無(wú)關(guān)輸入的更新 { ?? ?//小球移動(dòng) ?? ?canvas[ball_x][ball_y] = 0; ?? ?ball_x = ball_x + ball_vx; ?? ?ball_y = ball_y + ball_vy; ?? ?//反彈判斷 ?? ?if ((ball_x == 0)||(ball_x == High - 1)) ?? ??? ?ball_vx = -ball_vx; ?? ?if ((ball_y == 0)||(ball_y == Width - 1)) ?? ??? ?ball_vy = -ball_vy; ?? ??? ??? ? ?? ?canvas[ball_x][ball_y] = 1; ?? ?//休眠時(shí)間,避免刷新過(guò)快 ?? ?sleep(50); } void updateWithInput() {} int main() { ?? ?startup(); ?? ?while(1) ?? ?{ ?? ??? ?show(); ?? ??? ?updateWithoutInput(); ?? ??? ?updateWithInput(); ?? ?} ?? ?return 0; }
這里要注意的是:
- updateWithInput留空,因?yàn)楝F(xiàn)在還沒(méi)有用戶操作的功能實(shí)現(xiàn)。
- main是死循環(huán),所以測(cè)試時(shí)要注意,當(dāng)然也可以改進(jìn)。
增加擋板
現(xiàn)在我們可以新定義,當(dāng)數(shù)組中某一元素值為2時(shí),輸出擋板“ * ”。
并且為updateWithInput增加移動(dòng)擋板的功能,每次移動(dòng)一個(gè)單位作為其速度(當(dāng)然可以改成別的數(shù))。
擋板的刷新方式和小球一樣,先將原位置清零然后把新位置元素改為2。
需要增加的內(nèi)容如下:
//全局變量 int position_x,position_y; //擋板中心坐標(biāo) int ridus;?? ?//擋板半徑,就是延伸的長(zhǎng)度 int left,right;?? ?//擋板左右位置 //初始化 ridus = 5; position_x = High - 1; position_y = Width/2; left = position_y - ridus; right = position_x + ridus; int k; for(k=left; k<=right; k++) ?? ?canvas[position_x][k] = 2; //輸出部分 ... else if (canvas[i][j] == 2) ?? ?printf("*"); ... //更新部分(與輸入無(wú)關(guān)) if (ball_x == High - 2) { ?? ?//判斷是否擋住 ?? ?if ((ball_y >= left)&&(ball_y <= right)) ?? ?{ ?? ??? ?printf("\a"); ?? ?} ?? ?else?? ?//未擋住 ?? ?{ ?? ??? ?printf("游戲失敗\n"); ?? ??? ?printf("pause"); ?? ??? ?exit(0); ?? ?} } //與輸入有關(guān)的更新 void updateWithInput() { ?? ?char input; ?? ?if (kbhit())?? ?//判斷是否有輸入 ?? ??? ?input = getch(); ?? ?if ((input == 'a')&&(left > 0))//左移 ?? ?{ ?? ??? ?canvas[position_x][right] = 0; ?? ??? ?position_y --; ?? ??? ?left = position_y - ridus; ?? ??? ?right = position_x + ridus; ?? ??? ?canvas[position_x][left] = 2; ?? ?} ?? ?if ((input == 'd')&&(right < Width -1))//右移 ?? ?{ ?? ??? ?canvas[position_x][left] = 0; ?? ??? ?position_y ++; ?? ??? ?left = position_y - ridus; ?? ??? ?right = position_x + ridus; ?? ??? ?canvas[position_x][right] = 2;?? ? ?? ?} }
打磚塊
這部分內(nèi)容就和之前的內(nèi)容一樣了。
需要增加的內(nèi)容有:
1. 初始磚塊
2. 小球碰到磚塊的判定
3. 碰到磚塊后的更新(磚塊消失、小球反彈)
具體代碼如下:
//初始化 int k,i; for(k=0; k<Width; k++) ?? ?for(i=0; i<high/4; i++)?? ?//這里是畫(huà)磚塊,可以根據(jù)修改 i 的范圍改變磚塊的排數(shù) ?? ??? ?canvas[i][k] = 3; //輸出 ... else if (canvas[i][j] == 3) ?? ?printf("#"); ... //碰到磚塊后 if (canvas[ball_x + ball_vx][ball_y + ball_vy] == 3) { ?? ?canvas[ball_x + ball_vx][ball_y + ball_vy] = 0; ?? ?ball_vx = -ball_vx; ?? ?ball_vy = -ball_vy; ?? ?printf("\a"); }
最后
1. 坐標(biāo)系是x軸向下,y 軸向右。
2. 實(shí)際對(duì)碰撞的判定是在斜方向上,當(dāng)然可以改進(jìn)判定內(nèi)容。
3. 游戲勝利條件還沒(méi)有完善。
全代碼:
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <cwindow.h> // 畫(huà)面尺寸設(shè)定 #define High 15 #define Width 20 //全局變量 int ball_x,ball_y;?? ?//小球坐標(biāo) int ball_vx,ball_vy;//小球速度 int canvas[High][Width] = [0]; int position_x,position_y; //擋板中心坐標(biāo) int ridus;?? ?//擋板半徑,就是延伸的長(zhǎng)度 int left,right;?? ?//擋板左右位置 void gotoxy(int x, int y)?? ?//移動(dòng)光標(biāo)便于清屏重畫(huà) { ?? ?HANDLE handle = GetStdHandle(STD_UOTPUT_HANDLE); ?? ?CROOD pos; ?? ?pos.X = x; ?? ?pos.Y = y; ?? ?SetConsoleCursorPosition(handle, pos); } void startup()?? ??? ??? ??? ?//數(shù)據(jù)初始化 { ?? ?ball_x = 0; ?? ?ball_y = Width/2; ?? ?ball_vx = 1; ?? ?ball_vy = 1; ?? ?canvas[ball_x][ball_y] = 1; ?? ?ridus = 5; ?? ?position_x = High - 1; ?? ?position_y = Width/2; ?? ?left = position_y - ridus; ?? ?right = position_x + ridus; ?? ?int k,i; ?? ?for(k=left; k<=right; k++) ?? ?canvas[position_x][k] = 2; ?? ?for(k=0; k<Width; k++) ?? ??? ?for(i=0; i<high/4; i++)?? ?//這里是畫(huà)磚塊,可以根據(jù)修改 i 的范圍改變磚塊的排數(shù) ?? ??? ??? ?canvas[i][k] = 3; } void show() { ?? ?gotoxy(0, 0); ?? ?int i,j; ?? ?for(i=0; i<High; i++) ?? ?{ ?? ??? ?for(j=0; j<Width; j++) ?? ??? ?{ ?? ??? ??? ?if (canvas[i][j] == 0) ?? ??? ??? ??? ?printf(" ");//輸出空格 ?? ??? ??? ?else if (canvas[i][j] == 1) ?? ??? ??? ??? ?printf("O");//輸出小球 ?? ??? ??? ?else if (canvas[i][j] == 2) ?? ??? ??? ??? ?printf("*"); ?? ??? ??? ?else if (canvas[i][j] == 3) ?? ??? ??? ??? ?printf("#"); ?? ??? ?} ?? ??? ?printf("|\n");//每畫(huà)完一行顯示邊界并換行 ?? ?} ?? ?for(j=0; j<Width; j++) ?? ??? ?printf("-");//最后畫(huà)下邊界 } void updateWithoutInput()?? ?//無(wú)關(guān)輸入的更新 { ?? ?if (canvas[ball_x + ball_vx][ball_y + ball_vy] == 3) ?? ?{ ?? ??? ?canvas[ball_x + ball_vx][ball_y + ball_vy] = 0; ?? ??? ?ball_vx = -ball_vx; ?? ??? ?ball_vy = -ball_vy; ?? ??? ?printf("\a"); ?? ?} ?? ?if (ball_x == High - 2) ?? ?{ ?? ??? ?//判斷是否擋住 ?? ??? ?if ((ball_y >= left)&&(ball_y <= right)) ?? ??? ?{ ?? ??? ??? ?printf("\a"); ?? ??? ?} ?? ??? ?else?? ?//未擋住 ?? ??? ?{ ?? ??? ??? ?printf("游戲失敗\n"); ?? ??? ??? ?printf("pause"); ?? ??? ??? ?exit(0); ?? ??? ?} ?? ?} ?? ?//小球移動(dòng) ?? ?canvas[ball_x][ball_y] = 0; ?? ?ball_x = ball_x + ball_vx; ?? ?ball_y = ball_y + ball_vy; ?? ?//反彈判斷 ?? ?if ((ball_x == 0)||(ball_x == High - 1)) ?? ??? ?ball_vx = -ball_vx; ?? ?if ((ball_y == 0)||(ball_y == Width - 1)) ?? ??? ?ball_vy = -ball_vy; ?? ??? ??? ? ?? ?canvas[ball_x][ball_y] = 1; ?? ?//休眠時(shí)間,避免刷新過(guò)快 ?? ?sleep(50); } void updateWithInput() { ?? ?char input; ?? ?if (kbhit())?? ?//判斷是否有輸入 ?? ??? ?input = getch(); ?? ?if ((input == 'a')&&(left > 0))//左移 ?? ?{ ?? ??? ?canvas[position_x][right] = 0; ?? ??? ?position_y --; ?? ??? ?left = position_y - ridus; ?? ??? ?right = position_x + ridus; ?? ??? ?canvas[position_x][left] = 2; ?? ?} ?? ?if ((input == 'd')&&(right < Width -1))//右移 ?? ?{ ?? ??? ?canvas[position_x][left] = 0; ?? ??? ?position_y ++; ?? ??? ?left = position_y - ridus; ?? ??? ?right = position_x + ridus; ?? ??? ?canvas[position_x][right] = 2;?? ? ?? ?} } int main() { ?? ?startup(); ?? ?while(1) ?? ?{ ?? ??? ?show(); ?? ??? ?updateWithoutInput(); ?? ??? ?updateWithInput(); ?? ?} ?? ?return 0; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
在QT5中實(shí)現(xiàn)求兩個(gè)輸入值的和并輸出(實(shí)例)
下面小編就為大家?guī)?lái)一篇在QT5中實(shí)現(xiàn)求兩個(gè)輸入值的和并輸出(實(shí)例)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08C++中常見(jiàn)容器類的使用方法詳解(vector/deque/map/set)
C++中常見(jiàn)的容器類有vector、list、deque、map、set、unordered_map和unordered_set。下面將舉例直接說(shuō)明各個(gè)容器的使用方法,希望對(duì)大家有所幫助2023-03-03