1.個人認爲,學編程最重要的是多動手寫代碼,只有你真正去寫,你才能發現自己的問題所在,發現並改正,你的能力就能得到提升。對於大多數人而言,你踏踏實實把所學到的知識理解並運用好,你就能成爲一個不錯的程序員。
2.寫一些小遊戲用於練習是一個很不錯的選擇,代碼量不算多,也不算少,既可以鞏固知識,又可以提升興趣。
3.遊戲最重要的是邏輯實現而並非畫面表現,所以黑窗口也無所謂,明白原理才最重要。
廢話不多說,開始。
1)蛇移動的原理
蛇的移動是靜態的移動,就是不斷重繪蛇的位置,由於重繪速度很快,在人眼看來就是在移動。
2)蛇移動的規律
蛇的移動可以看作只有蛇頭在變化。比如,蛇向右移動,其實就是蛇頭向右移動一格,原來蛇頭的位置就變爲第一節蛇身的位置,原來第一節蛇身的位置,就變爲第二節蛇身的位置,其餘類推。
3)用到的知識
數組,結構體,指針
4)大概思路
定義一個結構體表示“點”(x,y),用一個數組來儲存蛇,每一節蛇其實就是一個座標點。知道蛇的座標就很容易了,只需在對應的座標畫蛇就可以了。
如何移動到對應的座標:用到一個API函數------gotoxy(int x,int y),會將光標移到對應的位置。
如何獲取用戶的輸入:kbhit()函數可以獲取用戶輸入的按鍵,返回按鍵的ASCII,非阻塞。
5)遊戲效果
代碼有具體註釋,大概200多行,很合適練手。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<conio.h> 4 #include<Windows.h> 5 //遊戲畫面大小 6 #define HEIGHT 25//高 7 #define WIDE 45//寬 8 typedef struct 9 { 10 int x;//x座標 11 int y;//y座標 12 13 }Point; 14 15 char direction='w';//方向 16 int point=0;//分數 17 18 void init(Point*snake,int bodyNum);//初始化,設定蛇身的座標 19 void move(Point*snake,int *bodyNum);// 20 void printSnake(Point * snake,int bodyNum);//打印蛇 21 char controlMove();//控制移動 22 23 void change(Point*snake,int bodyNum);//改變蛇的座標 24 void clean(Point*snake,int bodyNum);//在屏幕上清除之前的蛇 25 26 void printWall();//打印牆壁 27 int isDead(Point*snake,int bodyNum);//判斷蛇是否死亡 是返回1 非返回0 28 void food(Point*snake,int bodyNum);//隨機產生食物 29 int eatFood(Point*snake,int *bodyNum);//判斷是否吃到食物 是返回1 非返回0 30 31 void HideCursor();//隱藏光標 32 void gotoxy (int x,int y);//光標位置移動到指定的座標 33 34 void HideCursor() 35 { 36 CONSOLE_CURSOR_INFO cursor_info = {1, 0}; 37 SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); 38 } 39 void gotoxy (int x,int y) 40 { 41 HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE); 42 COORD pos; 43 pos.X=x; 44 pos.Y=y; 45 SetConsoleCursorPosition(handle,pos); 46 } 47 48 int main() 49 { 50 Point snake[64];//表示蛇 51 int bodyNum=6;//蛇身的個數,初始化6個 52 srand(time(NULL));//設置隨機種子 53 54 HideCursor(); 55 init(snake,bodyNum); 56 printWall(); 57 food(snake,bodyNum); 58 printSnake(snake,bodyNum); 59 60 while(1) 61 { 62 move(snake,&bodyNum); 63 Sleep(200-point);//分數越高速度越快 64 } 65 66 } 67 68 void init(Point*snake,int bodyNum) 69 { 70 int i; 71 snake[0].x=HEIGHT/2; 72 snake[0].y=WIDE/2; 73 for(i=1;i<bodyNum;i++) 74 { //讓蛇一開始在畫面中間 75 snake[i].x=HEIGHT/2+i; 76 snake[i].y=WIDE/2; 77 } 78 } 79 80 void move(Point*snake,int *bodyNum) 81 { 82 char dir=controlMove();//獲取用戶輸入的按鍵 83 clean(snake,*bodyNum);//清除之前的蛇 84 change(snake,*bodyNum);//每次移動時都改變座標 85 //改變蛇頭的座標 86 switch(dir) 87 { 88 case 'w': 89 snake[0].y--; 90 break; 91 case 's': 92 snake[0].y++; 93 break; 94 case 'a': 95 snake[0].x--; 96 break; 97 case 'd': 98 snake[0].x++; 99 break; 100 default: 101 break; 102 } 103 104 if(eatFood(snake,bodyNum))//如果吃到食物 105 { 106 107 if(point>100) 108 point+=5; 109 else 110 point+=10; 111 112 food(snake,*bodyNum);//隨機產生新的食物 113 } 114 115 printSnake(snake,*bodyNum);//打印新的蛇 116 if(isDead(snake,*bodyNum))//如果死亡 117 { 118 gotoxy(WIDE,HEIGHT); 119 printf("\n\n\nGAVE OVER"); 120 exit(0);//退出遊戲 121 } 122 } 123 124 void printSnake(Point * snake,int bodyNum) 125 { 126 int i; 127 gotoxy(snake[0].x,snake[0].y);//蛇頭位置 128 printf("@"); //蛇頭 129 for(i=1;i<bodyNum;i++) 130 { 131 132 gotoxy(snake[i].x,snake[i].y); 133 printf("*");//蛇身 134 } 135 } 136 137 char controlMove()//控制移動 138 { 139 char input; 140 if(kbhit())//檢測是否有輸入 有返回1 沒有返回0 (非阻塞函數) 141 { 142 input=getch();//返回按下的鍵 143 if(input=='w'||input=='s'||input=='a'||input=='d') 144 direction=input; 145 } 146 return direction; 147 } 148 149 void change(Point*snake,int bodyNum) 150 { 151 int i; 152 //移動 原來的蛇頭座標變爲第一節蛇身,其餘依此類推, 153 for(i=bodyNum-1;i>0;i--) 154 snake[i]=snake[i-1]; 155 } 156 157 158 159 void clean(Point*snake,int bodyNum) 160 { 161 int i; 162 for(i=0;i<bodyNum;i++) 163 { 164 gotoxy(snake[i].x,snake[i].y); 165 printf(" "); 166 167 } 168 } 169 void printWall() 170 { 171 int i; 172 for(i=0;i<WIDE;i++) 173 { 174 gotoxy(i,0); 175 printf("#"); 176 gotoxy(i,HEIGHT); 177 printf("#"); 178 } 179 for(i=0;i<HEIGHT;i++) 180 { 181 gotoxy(0,i); 182 printf("#"); 183 gotoxy(WIDE,i); 184 printf("#"); 185 } 186 } 187 188 int isDead(Point*snake,int bodyNum) 189 { 190 int i; 191 if(snake[0].x==WIDE||snake[0].x==0) 192 return 1; 193 if(snake[0].y==HEIGHT||snake[0].y==0) 194 return 1; 195 for(i=1;i<bodyNum;i++) 196 { 197 if(snake[0].x==snake[i].x&&snake[0].y==snake[i].y) 198 return 1; 199 } 200 return 0; 201 } 202 203 void food(Point*snake,int bodyNum) 204 { 205 int x,y; 206 x=rand()%(WIDE-1); 207 y=rand()%(HEIGHT-1); 208 gotoxy(x,y); 209 printf("o"); 210 //將食物的座標存在數組中 211 snake[bodyNum].x=x; 212 snake[bodyNum].y=y; 213 } 214 215 int eatFood(Point*snake,int *bodyNum) 216 { 217 218 if(snake[0].x==snake[*bodyNum].x&&snake[0].y==snake[*bodyNum].y) 219 { 220 gotoxy(snake[*bodyNum].x,snake[*bodyNum].y); 221 printf(" "); 222 snake[*bodyNum]=snake[*bodyNum-1]; 223 snake[*bodyNum].x++; 224 (*bodyNum)++; 225 return 1; 226 } 227 return 0; 228 }
有不懂的,可以問我。
今後會繼續更新小遊戲系列。