C語言貪吃蛇
原始碼
#include<stdio.h> //包含各種標頭檔案 #include<windows.h> #include<conio.h> #include<time.h>
void gotoxy(); //宣告游標轉移函式 void fontcolor(int x); //宣告字型顏色函式 void IF(); //宣告開始介面 void START(); //宣告開始選擇函式 void Snake(); //宣告蛇的控制函式 void food_f(); //宣告食物的隨機出現函式 void END(); //宣告遊戲結束函式
int body_x[200],body_y[200]; // 定義蛇身陣列,最大長度為100 int score=0,max=0,num=0,head_x=28,head_y=8; // 定義得分數及最高分、吃的食物數量、蛇頭的初始位置 int food_x,food_y; // 定義食物座標 int flag1=1,flag2=1,flag3=1,flag4=1; // 定義標誌變數、接受按鍵字元變數以及迴圈變數 int key3=‘w’,key2=‘d’,key1; int i;
int main() { system(“mode con cols=100 lines=40”); // 調整螢幕大小 IF(); // 呼叫初始介面 START(); // 呼叫使用者選擇函式
if(flag1==0) return 0; // 根據使用者選擇,開始開始執行 else { for(i=13;i<=16;i++) //消除選擇介面,開始遊戲 { gotoxy(40,i); printf(" "); } food_f(); // 食物的出現 Snake(); // 蛇的控制(包括吃到食物的判定等等),主要函式 END(); //結束函式 } return 0;
}
void gotoxy(int x,int y) //游標轉移函式 { COORD pos={x,y}; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos); }
void HideCursor() //隱藏游標 { CONSOLE_CURSOR_INFO cursor_info = {1, 0}; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); }
void fontcolor(int x) //字型顏色函式 { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|x); }
void fresh() //資料初始化函式,繼續遊戲的話,資料要初始化 { score=0; num=0; head_x=28; head_y=8; flag3=1; flag4=1; key3=‘w’; key2=‘d’; system(“cls”); }
void rule() { gotoxy(14,32); for(i=1;i<=40;i++) { printf("–"); } gotoxy(15,33);printf(“☆遊戲規則:”); gotoxy(15,34);printf(" 1.W,S,A,D鍵分別代表上下左右,J鍵代表確定"); gotoxy(15,35);printf(" 2.碰牆或碰到自己即死亡,遊戲中除wasd鍵按其他鍵也會死"); gotoxy(15,36);printf(" 3.蛇移動的速度會隨著身體增長而加快到最快,最大長度200,超過則遊戲結束"); gotoxy(14,37); for(i=1;i<=40;i++) { printf("–"); } }
void IF() //初始介面函式 { fontcolor(5); // SetConsoleOutputCP(936); for(i=1;i<=100;i+=2) // 畫行 { printf(“■”); } for(i=2;i<=96;i+=2) { gotoxy(i,30); printf(“■”); } for(i=1;i<=30;i++) //畫列 { gotoxy(0,i); printf(“■”); } for(i=1;i<=30;i++) { gotoxy(98,i); printf(“■”); } for(i=2;i<=96;i+=2) //畫資料顯示區 { fontcolor(3); gotoxy(i,4); printf(“■”); }
rule();
gotoxy(25,2); //畫得分情況
fontcolor(2);
printf("Your Score: %d\t\tThe Highest Score: %d",score,max);
}
void START() // 使用者選擇是否開始遊戲函式 {
gotoxy(25,2);
fontcolor(2);
printf("Your Score: %d\t\tThe Highest Score: %d",score,max);
gotoxy(40,13);
printf("Are you ready ?"); //一開始樣子
gotoxy(45,15);
printf("→ GO");
gotoxy(45,16);
printf(" EXIT");
while(1) //使用者按鍵以後的樣子
{
key1=getch();
if(key1=='w')
{
Beep(800,150);
gotoxy(45,15);
printf("→ GO");
gotoxy(45,16);
printf(" EXIT");
flag1=1;
}
if(key1=='s')
{
Beep(800,150);
gotoxy(45,15);
printf(" GO");
gotoxy(45,16);
printf("→ EXIT");
flag1=0;
}
if(key1=='j') {Beep(800,150);gotoxy(40,18);fontcolor(13);break;}
}
}
void food_f() //定義食物的出現函式 { srand(time(0)); //設定隨機數種子為time(0) do { food_x=rand()%95+2; //食物橫座標的範圍為2到96 food_y=rand()%25+5; //食物縱座標的範圍為5,29
if(num>0) //使食物不出現在蛇的身體上,即食物座標不能與身體座標相等
{
for(i=0;i<=num;i++)
{
if(body_x[i]==food_x&&body_y[i]==food_y) //如果有相等的那麼,迴圈,重新產生
{
flag3=1;break;
}
else flag3=0;
}
}
else flag3=0;
} while(flag3);
if(food_x%2!=0) food_x++; //使食物出現的橫座標為偶數,不然有可能吃不到
gotoxy(food_x,food_y);
Beep(600,150);fontcolor(14); //輸出食物
printf("■");
}
void MOVE() //實現蛇的移動函式,最難的地方 { gotoxy(head_x,head_y);fontcolor(12);printf(“●”); //在蛇頭前面輸出一個 gotoxy(body_x[num],body_y[num]); printf(" "); //在蛇尾減去一個 if(num<=27) Sleep(300-num*10);else Sleep(30); //使蛇的移動速度改變 if(num>0) //將蛇身體的後一個座標與前一個座標相等,實現移動,關鍵 { for(i=num;i>=1;i–) { body_x[i]=body_x[i-1];body_y[i]=body_y[i-1]; } } }
void JUDGE() //定義吃到食物的判定 { if((head_xfood_x)&&(head_yfood_y)) { Beep(100,150); //資料發生改變 score+=100; num++;
if(key2=='w') //不同方向吃到食物,座標變換情況不同
{
if(num>1) // num>1和<1的情況有所不同,分開討論
{
body_x[num]=body_x[num-1]; //如果num>1,且從上吃到食物,那麼新增的身體的座標是前一個身體的座標的縱座標+1,橫座標不變
body_y[num]=body_y[num-1]+1;
}
else // 如果<1的話,是不變的
{
body_x[num]=body_x[num-1];
body_y[num]=body_y[num-1];
}
}
if(key2=='s') //其他情況類似
{
if(num>1)
{
body_x[num]=body_x[num-1];
body_y[num]=body_y[num-1]-1;}
else
{
body_x[num]=body_x[num-1];
body_y[num]=body_y[num-1];
}
}
if(key2=='a')
{
if(num>1)
{
body_x[num]=body_x[num-1]+2;
body_y[num]=body_y[num-1];}
else
{
body_x[num]=body_x[num-1];
body_y[num]=body_y[num-1];
}
}
if(key2=='d')
{
if(num>1)
{
body_x[num]=body_x[num-1]-2;
body_y[num]=body_y[num-1];}
else
{
body_x[num]=body_x[num-1];
body_y[num]=body_y[num-1];
}
}
gotoxy(25,2); //重新整理得分情況
fontcolor(2);
printf("Your Score: %d",score);
food_f(); // 使食物再次出現
}
}
void Snake() //實現蛇的控制,使遊戲順利進行 { while(1) {
body_x[0]=head_x;body_y[0]=head_y;
if(kbhit()) key2=getch(); //kbhit()函式可以非阻塞的得到一個字元
switch(key2) //蛇的移動方向的控制
{
case 'w': head_y--;break;
case 's': head_y++;break;
case 'a': head_x-=2;break;
case 'd': head_x+=2;;break;
}
for(i=0;i<=num;i++) //判斷是否碰到自己
{
if((head_x==body_x[i])&&(head_y==body_y[i]))
{
flag2=0;
break;
}
}
if(head_x==98||head_x==0||head_y==4||head_y==30) //判斷是否撞牆死亡
{
flag2=0;
}
MOVE(); //開始移動
JUDGE();
if(flag2==0||num==200) // 死亡或長度過長的話,退出迴圈
{
flag2=1;
break;
}
}
}
void END() //結束函式 {
if(score>=max) max=score; // 看是否破紀錄
for(i=100;i<=500;i+=100) //結束音樂
{
Beep(i,200);
}
system("cls"); //清屏,畫結束介面
IF();
gotoxy(30,15);
fontcolor(12);
printf("You dead! Do you want to continue?");
gotoxy(40,18);fontcolor(156);printf("☆ Yes");
gotoxy(40,19);fontcolor(2);printf(" No");
while(1) //使用者選擇是否繼續遊戲
{
key3=getch();
if(key3=='w')
{
Beep(800,150);
gotoxy(40,18);fontcolor(156);printf("☆ Yes");
gotoxy(40,19);fontcolor(2);printf(" No");
flag4=1;
}
if(key3=='s')
{
Beep(800,150);
gotoxy(40,18);fontcolor(2);printf(" Yes");
gotoxy(40,19);fontcolor(156);printf("☆ No");
flag4=0;
}
if(key3=='j')
{
Beep(800,150);
if(flag4==0)
{
gotoxy(35,25);
fontcolor(13);
break;
}
else //繼續的話,初始化資料,從來即可
{
fresh();
IF();
food_f();
Snake();
END();
}
}
}
}