日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

贪吃蛇原型实现基本思路

發(fā)布時(shí)間:2025/4/14 63 豆豆
生活随笔 收集整理的這篇文章主要介紹了 贪吃蛇原型实现基本思路 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

貪吃蛇的原型是在windows控制臺(tái)下即在字符模式下利用C++編寫(xiě)貪吃蛇。?

主要實(shí)現(xiàn)的效果就是,用戶利用'w'、's'、'a'、'd'分別表示上下左右,當(dāng)蛇碰到障礙物時(shí)通不過(guò),當(dāng)碰到食物時(shí),分?jǐn)?shù)加1,同時(shí),在另外一個(gè)地方生成新的食物,并且身體會(huì)增加一個(gè)字符的長(zhǎng)度。?

在實(shí)現(xiàn)該原型前必須實(shí)現(xiàn)兩項(xiàng)技術(shù):?

  • 字符上色,這個(gè)利用了網(wǎng)上的代碼
  • 字符位置控制



什么意思呢?主要是因?yàn)榭紤]到在通常情況下,在控制臺(tái)下編寫(xiě)的程序,默認(rèn)都是黑白色的,顏色單一,而且蛇和障礙物、食物之間無(wú)法被互相區(qū)分,所以加上更多的顏色,視覺(jué)上會(huì)更舒服些。字符位置控制呢,是必不可缺的。這個(gè)是因?yàn)樵诿钚心J较?#xff0c;程序是默認(rèn)順序接收用戶輸入的,偶爾可以跳至同一行稍前些的位置。但是,由于蛇要到處爬,所以這就遇到一個(gè)問(wèn)題,如何讓輸入光標(biāo)跳至窗口下的任意位置成了開(kāi)發(fā)的基礎(chǔ)和前提。具體的我后面會(huì)講到我的解決方案。?

我的實(shí)現(xiàn)思路:?

首先,我要?jiǎng)?chuàng)建一個(gè)游戲背景,具體指的是貪吃蛇的移動(dòng)范圍。這個(gè)呢,我用二維的數(shù)組來(lái)表示。每個(gè)單元格有幾個(gè)參數(shù)---是否存在障礙物、是否存在食物,如果有的話,就用true,否則為false。?

1 //這個(gè)是背景的單元格數(shù)據(jù)結(jié)構(gòu)
2 const length = 40;
3 const width = 20;
4 struct square{
5 bool blocked; //是否有障礙物
6 bool food; //是否有食物
7 int x; //單元格在背景中的相對(duì)橫坐標(biāo)
8 int y; //單元格在背景中的相對(duì)縱坐標(biāo)
9 }bg[length][width]; //直接創(chuàng)建游戲背景
10
11 //設(shè)置背景
12 void setBG(int length, int width){
13 HANDLE hOut;
14 COORD OutChar;
15 OutChar.X = 10;
16 OutChar.Y = 10;
17 int i = 0;
18 int j = 0;
19 for(i = 0; i < width; i++){
20 for(j = 0; j < length; j++){
21 bg[i][j].x = i;
22 bg[i][j].y = j;
23 bg[i][j].blocked = false;
24 bg[i][j].food = false;
25 OutChar.X = j+10;
26 hOut = GetStdHandle(STD_OUTPUT_HANDLE);
27 SetConsoleCursorPosition(hOut,OutChar);
28 cout << col(BG_WHITE,true) << " ";
29 }
30 cout << endl;
31 OutChar.Y = i+10;
32 SetConsoleCursorPosition(hOut,OutChar);
33 }
34 }

接下來(lái),就是要在背景上創(chuàng)建障礙物,在創(chuàng)建它們之前,首先得解決如何在指定的單元格式繪制單元。思路很簡(jiǎn)單,就是編寫(xiě)一個(gè)函數(shù)將光標(biāo)定位到相應(yīng)的坐標(biāo)位置,然后輸入一個(gè)空白的上色字符就解決了。然后就可以利用這個(gè)函數(shù)在真正的背景上相應(yīng)的位置構(gòu)建障礙物了。同時(shí)可以實(shí)現(xiàn)隨機(jī)創(chuàng)建任意個(gè)、任意位置的障礙物了。

1 //構(gòu)造障礙物
2 void createBlock(int x, int y, unsigned short color){
3 HANDLE hOut;
4 COORD OutChar;
5 OutChar.X = x;
6 OutChar.Y = y;
7 hOut = GetStdHandle(STD_OUTPUT_HANDLE);
8 SetConsoleCursorPosition(hOut,OutChar); //定位光標(biāo)輸入
9 cout << col(color, true) << " "; //一個(gè)顏色為color的空白字符
10 }
11
12 //生成單個(gè)障礙物
13 void createWall(int x,int y){
14 createBlock(x+10,y+10,BG_GREEN);
15 bg[x][y].blocked = true;
16 }
17
18 //判斷所指坐標(biāo)是否被占用
19 bool checkExisted(int x,int y){
20 if(bg[x][y].blocked == true || bg[x][y].food == true){
21 return false;
22 }
23 return true;
24 }
25
26 //隨機(jī)生成障礙物
27 void rand_createWall(void){
28 srand((unsigned)time(NULL));
29 int n = rand() % 70+10;
30 int pos_x = 0;
31 int pos_y = 0;
32 int i = 0;
33 for(i = 0; i < n; i++){
34 pos_x = rand() % length;
35 pos_y = rand() % (width-1);
36 if(checkExisted(pos_x,pos_y) == true){ //防止障礙物重疊
37 createWall(pos_x,pos_y);
38 }else{
39 n++;
40 }
41 //createWall(pos_x,pos_y);
42 }
43 }

同理,食物的創(chuàng)建也一樣。

1 //創(chuàng)建食物
2 void createFood(int x,int y){
3 createBlock(x+10,y+10,BG_BLUE);
4 bg[x][y].food = true;
5 }
6
7 //隨機(jī)創(chuàng)建食物
8 void rand_createFood(void){
9 srand((unsigned)time(NULL));
10 int n = 1;//rand() % 20;
11 int pos_x = 0;
12 int pos_y = 0;
13 int i = 0;
14 for(i = 0; i < n; i++){
15 pos_x = rand() % length;
16 pos_y = rand() % (width-1);
17 if(checkExisted(pos_x,pos_y) == true){ //防止在障礙物上生成食物
18 createFood(pos_x,pos_y);
19 }else{
20 n++;
21 }
22 }
23 }



背景、障礙物和食物都創(chuàng)建好了,接下來(lái)就要構(gòu)建蛇的模型了。由于考慮到蛇在吃完食物后,身體會(huì)變長(zhǎng),所以我采用了順序表的數(shù)據(jù)結(jié)構(gòu)來(lái)記錄蛇的信息。那如何來(lái)表現(xiàn)蛇的移動(dòng)呢?我的思路是,將身體靠近頭的信息傳遞到次靠近頭的,同時(shí)將新的下一步要走的坐標(biāo)信息傳給頭部,同時(shí)有擦除掉尾部信息即可。?

1 //物體信息,這是蛇的單元模型
2 const objLen = 5;
3 struct obj{
4 int x;
5 int y;
6 }snake[objLen];
7
8 //創(chuàng)建蛇
9 LinList<struct obj> newSnake;
10 void createSnake(void){
11 int i = 0;
12 for(i = 0; i < objLen; i++){
13 snake[i].x = i;
14 snake[i].y = 0;
15 newSnake.Insert(snake[i],i);
16 }
17 }
18
19 //繪制蛇
20 void drawSnake(int len){
21 int i = 0;
22 struct obj t;
23 for(i = 0; i < len; i++){
24 t = newSnake.GetData(i);
25 createBlock(t.x,t.y,BG_RED);
26 }
27 }
28
29 //增長(zhǎng)蛇的身體
30 void insreaseSnake(int x,int y){
31 struct obj t;
32 t.x = x;
33 t.y = y;
34 newSnake.Insert(t,0);
35 createBlock(x,y,BG_RED);
36 }
37
38 //傳遞蛇的信息
39 void transSnake(int x,int y,int len){
40 int i = 0;
41 struct obj t1,t2;
42 for(i = 0; i < len-1; i++){
43 t1 = newSnake.GetData(i);
44 t2 = newSnake.GetData(i+1);
45 newSnake.Delete(i);
46 t1.x = t2.x;
47 t1.y = t2.y;
48 newSnake.Insert(t1,i);
49 }
50 newSnake.Delete(newSnake.Size()-1);
51 t1.x = x;
52 t1.y = y;
53 newSnake.Insert(t1,newSnake.Size()-1);
54 }

這里的相對(duì)位置是指以背景左上方的點(diǎn)為原點(diǎn)即(0,0),右下方為(length-1,width-1)。?

接著呢,就是要獲取用戶的方向控制操作,并執(zhí)行它們。由于采用的二維數(shù)組的方式表示蛇的形狀以及游戲背景,所以當(dāng)接收到命令如果是‘上’時(shí),橫坐標(biāo)不變,而縱坐標(biāo)減1,同時(shí)擦除原形狀,如此一來(lái),蛇就向上爬了。擦除函數(shù)的原理很簡(jiǎn)單,就是將對(duì)應(yīng)的背景單元格的信息全部還原為初始值,就可以了。?

1 //清除物體移動(dòng)軌跡
2 void removeTrack(int x, int y){
3 HANDLE hOut;
4 COORD OutChar;
5 OutChar.X = x;
6 OutChar.Y = y;
7 hOut = GetStdHandle(STD_OUTPUT_HANDLE);
8 SetConsoleCursorPosition(hOut,OutChar);
9 cout << col(BG_WHITE,true) << " ";
10 }
11
12 //移動(dòng)物體
13 int x = 10;
14 int y = 10;
15 int tail_x = 0;
16 int tail_y = 0;
17 void moveBlock(char direction){
18 HANDLE hOut2;
19 COORD OutChar2;
20 OutChar2.X = x;
21 OutChar2.Y = y;
22 struct obj t;
23 t = newSnake.GetData(0);
24 tail_x = t.x;
25 tail_y = t.y;
26 hOut2 = GetStdHandle(STD_OUTPUT_HANDLE);
27 removeTrack(t.x,t.y);
28 switch(direction){
29 case 'w':{
30 OutChar2.Y--;
31 y--;
32 SetConsoleCursorPosition(hOut2,OutChar2);
33 break;
34 }
35 case 's':{
36 OutChar2.Y++;
37 y++;
38 SetConsoleCursorPosition(hOut2,OutChar2);
39 break;
40 }
41 case 'a':{
42 OutChar2.X--;
43 x--;
44 SetConsoleCursorPosition(hOut2,OutChar2);
45 break;
46 }
47 case 'd':{
48 OutChar2.X++;
49 x++;
50 SetConsoleCursorPosition(hOut2,OutChar2);
51 break;
52 }
53 }
54
55 transSnake(x,y,newSnake.Size());
56 drawSnake(newSnake.Size());
57 }

做完這個(gè),不要以為就這樣結(jié)束了,因?yàn)槲覀冞€沒(méi)對(duì)蛇的運(yùn)動(dòng)范圍作出限制,而且還要實(shí)現(xiàn)蛇的觸發(fā)事件即碰到食物后身體變長(zhǎng),食物數(shù)增加1。?

1 //判斷是否碰到障礙物或邊界
2 bool checkView(char direction){
3 if(direction == 'w' && y >= 10){
4 if(y == 10 || bg[x-10][y-10-1].blocked == true){return false;}
5 }
6 else if(direction == 's' && y < 10+width){
7 if(y == 10+width-2 || bg[x-10][y-10+1].blocked == true){return false;}
8 }
9 else if(direction == 'a' && x >= 10){
10 if(x == 10 || bg[x-10-1][y-10].blocked == true){return false;}
11 }
12 else if(direction == 'd' && x < 10+length){
13 if(x == 10+length-1 || bg[x-10+1][y-10].blocked == true){return false;}
14 }
15 return true;
16 }
17
18 //判斷是否吃到食物
19 bool checkFood(int x, int y){
20 if(bg[x-10][y-10].food == true){return true;}
21 return false;
22 }

下面就是游戲原型的主函數(shù):

1 int main()
2 {
3 HANDLE hOut;
4 COORD OutChar;
5
6 OutChar.X = 0;
7 OutChar.Y = 0;
8 hOut = GetStdHandle(STD_OUTPUT_HANDLE);
9 SetConsoleCursorPosition(hOut,OutChar);
10
11 /*
12 struct square **bgR = new square*[width];
13 struct square *bgC = new square[length];
14 for(int i = 0; i < width; i++){
15 bgR[i] = bgC;
16 }
17 */
18 //設(shè)置背景
19 setBG(length,width);
20 //設(shè)置障礙物
21 rand_createWall();
22 //設(shè)置食物
23 rand_createFood();
24 //創(chuàng)建蛇
25 createSnake();
26 //移動(dòng)物體
27 char direction;
28 int score = 0;
29 for(;;){
30 direction = getch();
31 if(checkView(direction) == true){//判斷能否移動(dòng)
32 moveBlock(direction);
33 if(checkFood(x,y) == true){//判斷是否吃到食物
34 bg[x-10][y-10].food = false;
35 score++;
36 insreaseSnake(tail_x,tail_y);//增長(zhǎng)身體
37 rand_createFood();//吃完后隨機(jī)在創(chuàng)建一個(gè)食物
38 }
39 }
40 OutChar.X = 0;
41 OutChar.Y = 0;
42 hOut = GetStdHandle(STD_OUTPUT_HANDLE);
43 SetConsoleCursorPosition(hOut,OutChar);
44 cout << col(BG_WHITE,true) << "Scores: " << score;
45 }
46 return 0;
47 }

這個(gè)貪吃蛇原型是我一時(shí)興起弄的,考慮的也比較簡(jiǎn)單。





轉(zhuǎn)載于:https://www.cnblogs.com/bilipan/archive/2012/03/30/2425442.html

總結(jié)

以上是生活随笔為你收集整理的贪吃蛇原型实现基本思路的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。