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)有一毛錢(qián)關(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-08
C++中常見(jiàn)容器類的使用方法詳解(vector/deque/map/set)
C++中常見(jiàn)的容器類有vector、list、deque、map、set、unordered_map和unordered_set。下面將舉例直接說(shuō)明各個(gè)容器的使用方法,希望對(duì)大家有所幫助2023-03-03

