c語言雙人貪吃蛇-基於圖形庫實現
阿新 • • 發佈:2019-01-24
/* 蛇蛇大作戰 作者:施瑞文 */ #include <conio.h> #include <graphics.h> #include <time.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <mmsystem.h> #pragma comment(lib,"winmm.lib") #define R 30 #define fram_width 30 //寬度 #define fram_height 30 //高度 #define SIZE 16 //方格邊長 //玩家1 #define UP 'w' //72 上 #define DOWN 's' //80 下 #define LEFT 'a' //75 左 #define RIGHT 'd' //77 右 //玩家2 #define DOWN2 'k' //72,80,75,77是方向鍵對應的鍵值 下 #define LEFT2 'j' //左 #define RIGHT2 'l' //右 #define UP2 'i' //上 char ch = 'a';//用於記錄方向,傳統模式 char c = LEFT2; //記錄玩家2方向 int m; //全域性變數,用於迴圈計數 int score = 0; //玩家1分數和傳統模式分數 int score2 = 0; //玩家2分數 char maxScore[5] = "0"; //記錄傳統模式歷史最高分 struct Food //食物結構體 { int x; //食物的橫座標 int y; //食物的縱座標 }food; struct Snake { //玩家1貪吃蛇 int len; //蛇的長度 int x[780]; //蛇的每一節的橫座標 int y[780]; //蛇的每一節的縱座標 int count; //蛇吃到的食物數量 int speed; //蛇的速度 }snake; struct newSnake //玩家2 { int len; int x[780]; int y[780]; int count; int speed; }new_snake; void initmap(); //畫邊框 void menu(); //選單 void getfood(); //隨機產生食物 void chushihua(); //初始化蛇 void eatfood(); //判斷蛇是否吃到食物 int die(); //判斷蛇是否死亡 void move(); //遷移蛇的座標,移動蛇 void turn(char t); //轉向 void print(); //列印蛇 void play(); //開始傳統模式遊戲 void start(); //開始特效 int StringToInt(char a[], int n); //將字串轉化為整數 void wall(); //傳統模式的障礙物 void score_rule(); //顯示分數和規則 //雙人PK模式 void double_initmap(); //雙人PK地圖 void new_chushihua(); //初始化玩家2的蛇 void double_play(); //開始雙人PK模式遊戲 void double_eatfood(); //判斷是否吃到食物 void double_turn(char t); //轉向 void double_print(); //列印玩家2的蛇 void double_move1(); //雙人模式玩家1移動 void double_move2(); //雙人模式玩家2移動 void double_getfood();//雙人模式隨機產生食物 void double_score_rule();//雙人模式 顯示分數和操作規則 int double_die(); //雙人模式判斷玩家1是否死亡 int double_die2(); //雙人模式判斷玩家2是否死亡 int win(int grade); //判斷贏家 void main() { do { initgraph(640, 480); //產生畫板 PlaySound("F:\\Snake_bgm\\start.WAV", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);//播放音樂 menu(); //進入選單 closegraph(); //關閉畫板 } while (1); system("pause"); } int StringToInt(char a[], int n)//將字串轉化為整數 { if (n == 1) return a[0] - 48; else return StringToInt(a, n - 1) * 10 + a[n - 1] - 48; } void start()//開始特效 { int x, y, i; for (i = 0; i<30; i++) { x = i; for (y = x; y<R - x; y++) { setfillcolor(BROWN); fillrectangle(x*SIZE, y*SIZE, x*SIZE + SIZE, y*SIZE + SIZE); } x = (R - 1 - i); for (y = i; y <= x; y++) { setfillcolor(BROWN); fillrectangle(x*SIZE, y*SIZE, x*SIZE + SIZE, y*SIZE + SIZE); } x = i; for (y = x; y<R - x; y++) { setfillcolor(BROWN); fillrectangle(y*SIZE, x*SIZE, y*SIZE + SIZE, x*SIZE + SIZE); } x = (R - 1 - i); for (y = i; y <= x; y++) { setfillcolor(BROWN); fillrectangle(y*SIZE, x*SIZE, y*SIZE + SIZE, x*SIZE + SIZE); } Sleep(50); } for (i = 0; i<30; i++) { x = i; for (y = x; y<R - x; y++) { setfillcolor(BLACK); solidrectangle(x*SIZE, y*SIZE, x*SIZE + SIZE, y*SIZE + SIZE); } x = (R - 1 - i); for (y = i; y <= x; y++) { setfillcolor(BLACK); solidrectangle(x*SIZE, y*SIZE, x*SIZE + SIZE, y*SIZE + SIZE); } x = i; for (y = x; y<R - x; y++) { setfillcolor(BLACK); solidrectangle(y*SIZE, x*SIZE, y*SIZE + SIZE, x*SIZE + SIZE); } x = (R - 1 - i); for (y = i; y <= x; y++) { setfillcolor(BLACK); solidrectangle(y*SIZE, x*SIZE, y*SIZE + SIZE, x*SIZE + SIZE); } Sleep(50); } } void double_getfood()//雙人模式隨機產生食物 { int flag; while (1) { flag = 1; food.x = rand() % (fram_width - 2) + 1; food.y = rand() % (fram_height - 2) + 1; for (m = 0; m<snake.len; m++) { if (food.x == snake.x[m] && food.y == snake.y[m]) //判斷食物是否落到蛇身上 { flag = 0; break; } } if (flag == 0) continue; for (m = 0; m<new_snake.len; m++) { if (food.x == new_snake.x[m] && food.y == new_snake.y[m]) { flag = 0; break; } } if (flag == 0) continue; if (flag == 1) { if ((new_snake.count + snake.count) % 5 == 0 && (new_snake.count + snake.count) != 0)//每產生5個小食物後產生1個大食物 { setfillcolor(WHITE); fillcircle(food.x*SIZE + SIZE / 2, food.y*SIZE + SIZE / 2, SIZE / 2); } else { setfillcolor(WHITE); fillcircle(food.x*SIZE + SIZE / 2, food.y*SIZE + SIZE / 2, SIZE / 4); } break; } } } void getfood()//產生食物 { int flag; while (1) { flag = 1; food.x = rand() % (fram_width - 2) + 1; food.y = rand() % (fram_height - 2) + 1; for (m = 1; m<fram_width / 3; m++) { if ((food.x == m && food.y == fram_height / 4) || (food.x == m && food.y == 3 * fram_height / 4))//判斷食物是否落到蛇身上 { flag = 0; break; } } if (flag == 0) continue; for (m = 2 * fram_width / 3; m<fram_width; m++) { if (food.x == m && food.y == fram_height / 2)//判斷食物是否落到障礙物上 { flag = 0; break; } } if (flag == 0) continue; for (m = 0; m<snake.len; m++) { if (food.x == snake.x[m] && food.y == snake.y[m]) { flag = 0; break; } } if (flag == 0) continue; if (flag == 1) { if (snake.count % 5 == 0 && snake.count != 0) { setfillcolor(WHITE); fillcircle(food.x*SIZE + SIZE / 2, food.y*SIZE + SIZE / 2, SIZE / 2); } else { setfillcolor(WHITE); fillcircle(food.x*SIZE + SIZE / 2, food.y*SIZE + SIZE / 2, SIZE / 4); } break; } } } void double_eatfood()//雙人模式判斷是否吃到食物 { if (snake.x[0] == food.x&&snake.y[0] == food.y)//如果玩家1吃到食物 { snake.len++; if ((snake.count + new_snake.count) % 5 == 0 && (snake.count + new_snake.count) != 0) { score += 15; } else score += 5; snake.count++; double_getfood(); } else if (new_snake.x[0] == food.x&&new_snake.y[0] == food.y)//如果玩家2吃到食物 { new_snake.len++; if ((snake.count + new_snake.count) % 5 == 0 && (snake.count + new_snake.count) != 0) { score2 += 15; } else score2 += 5; new_snake.count++; double_getfood(); } } void eatfood()//傳統模式 判斷是否吃到食物 { if (snake.x[0] == food.x&&snake.y[0] == food.y) { snake.len++; if (snake.count % 5 == 0 && snake.count != 0) { score += 20; if (snake.speed>100) snake.speed -= 50; else snake.speed = 100; } else score += 5; snake.count++; getfood();//吃完還有 } } void new_chushihua()//初始化玩家2 { //產生蛇頭 new_snake.x[0] = (fram_width) / 3; new_snake.y[0] = (fram_height) / 3; new_snake.speed = 300; moveto(new_snake.x[0] * SIZE, new_snake.y[0] * SIZE); setfillcolor(BLUE); fillcircle(new_snake.x[0] * SIZE + SIZE / 2, new_snake.y[0] * SIZE + SIZE / 2, SIZE / 2); //產生蛇身 fillcircle(new_snake.x[0] * SIZE + SIZE / 2, new_snake.y[0] * SIZE + SIZE / 2, SIZE / 2); new_snake.len = 4; for (int k = 1; k < new_snake.len; k++)//依次給後一節蛇身賦值 { //將前一節座標賦給後一節 new_snake.x[k] = new_snake.x[k - 1] + 1; new_snake.y[k] = new_snake.y[k - 1]; moveto(new_snake.x[k] * SIZE, new_snake.y[k] * SIZE); setfillcolor(YELLOW);//填充顏色 fillcircle(new_snake.x[k]*SIZE+SIZE/2, new_snake.y[k]*SIZE+SIZE/2, SIZE/2);//畫蛇 } } void chushihua() { //產生蛇頭 snake.x[0] = (fram_width) / 2; snake.y[0] = (fram_height) / 2; snake.speed = 300; moveto(snake.x[0] * SIZE, snake.y[0] * SIZE); setfillcolor(GREEN); fillcircle(snake.x[0] * SIZE + SIZE / 2, snake.y[0] * SIZE + SIZE / 2, SIZE / 2); //產生蛇身 //fillcircle(snake.x[0] * SIZE + SIZE / 2, snake.y[0] * SIZE + SIZE / 2, SIZE / 2); snake.len = 4; for (int k = 1; k < snake.len; k++) { //將前一節座標賦給後一節 snake.x[k] = snake.x[k - 1] + 1; snake.y[k] = snake.y[k - 1]; moveto(snake.x[k] * SIZE, snake.y[k] * SIZE); setfillcolor(RED);//填充顏色 fillcircle(snake.x[k]*SIZE+SIZE/2, snake.y[k]*SIZE+SIZE/2, SIZE/2);//畫蛇 } } void move()//遷移座標,移動蛇 { //每次移動將蛇尾巴畫為背景色 moveto(snake.x[snake.len - 1] * SIZE, snake.y[snake.len - 1] * SIZE); setfillcolor(BLACK); solidrectangle(snake.x[snake.len - 1] * SIZE, snake.y[snake.len - 1] * SIZE, snake.x[snake.len - 1] * SIZE + SIZE, snake.y[snake.len - 1] * SIZE + SIZE); if (snake.y[0] == 0) //穿牆 snake.y[0] = fram_height - 2; else if (snake.y[0] == fram_height - 1) snake.y[0] = 0; for (m = snake.len - 1; m > 0; m--) { //將後一節座標賦值給前一節座標 snake.x[m] = snake.x[m - 1]; snake.y[m] = snake.y[m - 1]; } } void double_move1()//雙人模式移動玩家1 { //每次移動將蛇尾巴畫為背景色 moveto(snake.x[snake.len - 1] * SIZE, snake.y[snake.len - 1] * SIZE); setfillcolor(BLACK); solidrectangle(snake.x[snake.len - 1] * SIZE, snake.y[snake.len - 1] * SIZE, snake.x[snake.len - 1] * SIZE + SIZE, snake.y[snake.len - 1] * SIZE + SIZE); if (snake.y[0] == 0) //穿牆 snake.y[0] = fram_height - 2; else if (snake.y[0] == fram_height - 1) snake.y[0] = 0; else if (snake.x[0] == 0) snake.x[0] = fram_width - 2; else if (snake.x[0] == fram_width - 1) snake.x[0] = 0; for (m = snake.len - 1; m > 0; m--) { //將後一節座標賦值給前一節座標 snake.x[m] = snake.x[m - 1]; snake.y[m] = snake.y[m - 1]; } } void double_move2()//雙人模式移動玩家2 { //int k; //每次移動將蛇尾巴畫為背景色 moveto(new_snake.x[new_snake.len - 1] * SIZE, new_snake.y[new_snake.len - 1] * SIZE); setfillcolor(BLACK); solidrectangle(new_snake.x[new_snake.len - 1] * SIZE, new_snake.y[new_snake.len - 1] * SIZE, new_snake.x[new_snake.len - 1] * SIZE + SIZE, new_snake.y[new_snake.len - 1] * SIZE + SIZE); if (new_snake.y[0] == 0) //穿牆 new_snake.y[0] = fram_height - 2; else if (new_snake.y[0] == fram_height - 1) new_snake.y[0] = 0; else if (new_snake.x[0] == 0) new_snake.x[0] = fram_width - 2; else if (new_snake.x[0] == fram_width - 1) new_snake.x[0] = 0; for (m = new_snake.len - 1; m > 0; m--) { //將後一節座標賦值給前一節座標 new_snake.x[m] = new_snake.x[m - 1]; new_snake.y[m] = new_snake.y[m - 1]; } } void double_turn(char t) { if (t == UP2) new_snake.y[0]--; else if (t == DOWN2) new_snake.y[0]++; else if (t == LEFT2) new_snake.x[0]--; else if (t == RIGHT2) new_snake.x[0]++; } void turn(char t) { if (t == UP) snake.y[0]--; else if (t == DOWN) snake.y[0]++; else if (t == LEFT) snake.x[0]--; else if (t == RIGHT) snake.x[0]++; } void print()//列印蛇 { //列印蛇頭 moveto(snake.x[0] * SIZE, snake.y[0] * SIZE); setfillcolor(GREEN); fillcircle(snake.x[0] * SIZE + SIZE / 2, snake.y[0] * SIZE + SIZE / 2, SIZE / 2); //列印蛇身 for (m = 1; m<snake.len; m++) { setfillcolor(RED); fillcircle(snake.x[m] * SIZE + SIZE / 2, snake.y[m] * SIZE + SIZE / 2, SIZE / 2); } } void double_print()//雙人模式 同時列印兩條蛇 { int len = new_snake.len<snake.len ? new_snake.len : snake.len;//len取兩者中的較小值 moveto(new_snake.x[0] * SIZE, new_snake.y[0] * SIZE); setfillcolor(BLUE); fillcircle(new_snake.x[0] * SIZE + SIZE / 2, new_snake.y[0] * SIZE + SIZE / 2, SIZE / 2);//畫玩家2的蛇頭 moveto(snake.x[0] * SIZE, snake.y[0] * SIZE); setfillcolor(GREEN); fillcircle(snake.x[0] * SIZE + SIZE / 2, snake.y[0] * SIZE + SIZE / 2, SIZE / 2);//畫玩家1的蛇頭 for (m = 1; m<len; m++)//同時畫玩家1和玩家2的蛇身 { setfillcolor(RED); fillcircle(snake.x[m] * SIZE + SIZE / 2, snake.y[m] * SIZE + SIZE / 2, SIZE / 2); setfillcolor(YELLOW); fillcircle(new_snake.x[m] * SIZE + SIZE / 2, new_snake.y[m] * SIZE + SIZE / 2, SIZE / 2); } for (m = len; m<(new_snake.len>snake.len ? new_snake.len : snake.len); m++) { if (new_snake.len>snake.len)//如果玩家2的蛇比玩家1的蛇長,則把玩家2比玩家1多處的那部分補全 { setfillcolor(YELLOW); fillcircle(new_snake.x[m] * SIZE + SIZE / 2, new_snake.y[m] * SIZE + SIZE / 2, SIZE / 2); } else//如果玩家1的蛇比玩家2的蛇長,則把玩家1比玩家2多處的那部分補全 { setfillcolor(RED); fillcircle(snake.x[m] * SIZE + SIZE / 2, snake.y[m] * SIZE + SIZE / 2, SIZE / 2); } } } int win(int grade)//判斷輸贏 { if (score >= grade)//如果玩家1率先達到50分,則玩家1勝利 return 1; else if (score2 >= grade)//否則玩家2勝利 return 2; } void wall()//畫障礙物 { for (m = 1; m<fram_width / 3; m++) { setfillcolor(BROWN); fillrectangle(m*SIZE, fram_height / 4 * SIZE, m*SIZE + SIZE, fram_height / 4 * SIZE + SIZE); } for (m = 2 * fram_width / 3; m<fram_width; m++) { setfillcolor(BROWN); fillrectangle(m*SIZE, fram_height / 2 * SIZE, m*SIZE + SIZE, fram_height / 2 * SIZE + SIZE); } for (m = 1; m<fram_width / 3; m++) { setfillcolor(BROWN); fillrectangle(m*SIZE, 3 * fram_height / 4 * SIZE, m*SIZE + SIZE, 3 * fram_height / 4 * SIZE + SIZE); } } void double_score_rule()//分數與規則 { settextcolor(WHITE); outtextxy(31 * SIZE, 3 * SIZE, "玩家1:"); setfillcolor(GREEN); fillcircle(34 * SIZE + SIZE / 2, 3 * SIZE + SIZE / 2, SIZE / 2); //產生蛇身 for (int k = 35; k <38; k++) { setfillcolor(RED); fillcircle(k * SIZE + SIZE / 2, 3 * SIZE + SIZE / 2, SIZE / 2); } char count1[5]; itoa(score, count1, 10);//將整數轉化為字串 settextcolor(WHITE); outtextxy(31 * SIZE, 5 * SIZE, "分數:"); setfillcolor(BLACK); solidrectangle(34 * SIZE, 5 * SIZE, 38 * SIZE + SIZE, 5 * SIZE + SIZE); outtextxy(34 * SIZE, 5 * SIZE, count1); settextcolor(WHITE); outtextxy(31 * SIZE, 7 * SIZE, "玩家2:"); setfillcolor(BLUE); fillcircle(new_snake.x[0] * SIZE + SIZE / 2, new_snake.y[0] * SIZE + SIZE / 2, SIZE / 2); //產生蛇身 fillcircle(34 * SIZE + SIZE / 2, 7 * SIZE + SIZE / 2, SIZE / 2); for (int j = 35; j < 38; j++) { setfillcolor(YELLOW); fillcircle(j * SIZE + SIZE / 2, 7 * SIZE + SIZE / 2, SIZE / 2); } char count2[5]; itoa(score2, count2, 10); settextcolor(WHITE); outtextxy(31 * SIZE, 9 * SIZE, "分數:"); setfillcolor(BLACK); solidrectangle(34 * SIZE, 9 * SIZE, 38 * SIZE + SIZE, 9 * SIZE + SIZE); outtextxy(34 * SIZE, 9 * SIZE, count2); line(30 * SIZE, 11 * SIZE, 40 * SIZE, 11 * SIZE); settextcolor(RED); outtextxy(31 * SIZE, 13 * SIZE, "玩家1:"); settextcolor(GREEN); outtextxy(31 * SIZE, 14 * SIZE, " w: 上 s: 下"); outtextxy(31 * SIZE, 15 * SIZE, " a: 左 d: 右"); settextcolor(RED); outtextxy(31 * SIZE, 17 * SIZE, "玩家2:"); settextcolor(GREEN); outtextxy(31 * SIZE, 18 * SIZE, " i: 上 k: 下"); outtextxy(31 * SIZE, 19 * SIZE, " j: 左 l: 右"); settextcolor(RED); outtextxy(31 * SIZE, 21 * SIZE, "規則:"); settextcolor(WHITE); outtextxy(31 * SIZE, 23 * SIZE, "1.率先達到目標分者"); outtextxy(31 * SIZE, 24 * SIZE, " 勝利。"); outtextxy(31 * SIZE, 25 * SIZE, "2.遊戲過程中若碰到"); outtextxy(31 * SIZE, 26 * SIZE, " 對方身體,則減15"); outtextxy(31 * SIZE, 27 * SIZE, " 分,並在初始位置"); outtextxy(31 * SIZE, 28 * SIZE, " 復活"); } void score_rule() { char count[5]; FILE *fp; fp = fopen("maxscore", "a+");//讀取檔案中的內容 if (fp != NULL) { settextcolor(GREEN); while (fgets(maxScore, 5, fp) != NULL)//將檔案中的內容寫入maxScore陣列中 outtextxy(35 * SIZE, 5 * SIZE, maxScore);//將最高分顯示在畫板上 fclose(fp); } itoa(score, count, 10);//將整數轉化為字串 settextcolor(WHITE); outtextxy(31 * SIZE, 3 * SIZE, "分數:"); setfillcolor(BLACK); solidrectangle(34 * SIZE, 3 * SIZE, 38 * SIZE + SIZE, 3 * SIZE + SIZE); outtextxy(34 * SIZE, 3 * SIZE, count); outtextxy(31 * SIZE, 5 * SIZE, "最高分:"); line(30 * SIZE, 9 * SIZE, 40 * SIZE, 9 * SIZE); outtextxy(31 * SIZE, 11 * SIZE, " w: 上"); outtextxy(31 * SIZE, 13 * SIZE, " s: 下"); outtextxy(31 * SIZE, 15 * SIZE, " a: 左"); outtextxy(31 * SIZE, 17 * SIZE, " d: 右"); } void double_initmap() { for (int i = 1; i < fram_width - 1; i++) { setfillcolor(BLACK); fillrectangle(i*SIZE, 0, i*SIZE + SIZE, SIZE); setfillcolor(BLACK); fillrectangle(i*SIZE, SIZE*(fram_width - 1), i*SIZE + SIZE, SIZE*(fram_width - 1) + SIZE); } for (int j = 0; j < fram_height; j++) { setfillcolor(BLACK); fillrectangle(0, j*SIZE, SIZE, j*SIZE + SIZE); setfillcolor(BLACK); fillrectangle(SIZE*(fram_height - 1), j*SIZE, SIZE*(fram_height - 1) + SIZE, j*SIZE + SIZE); } } void initmap() { //產生圍欄 for (int i = 1; i < fram_width - 1; i++) { setfillcolor(BLACK); fillrectangle(i*SIZE, 0, i*SIZE + SIZE, SIZE); setfillcolor(BLACK); fillrectangle(i*SIZE, SIZE*(fram_width - 1), i*SIZE + SIZE, SIZE*(fram_width - 1) + SIZE); } for (int j = 0; j < fram_height; j++) { setfillcolor(BROWN); fillrectangle(0, j*SIZE, SIZE, j*SIZE + SIZE); setfillcolor(BROWN); fillrectangle(SIZE*(fram_height - 1), j*SIZE, SIZE*(fram_height - 1) + SIZE, j*SIZE + SIZE); } } int double_die1() { for (int i = 1; i<new_snake.len; i++) { if (snake.x[0] == new_snake.x[i] && snake.y[0] == new_snake.y[i]) { return 1; } } return 0; } int double_die2() { for (int i = 1; i<snake.len; i++) { if (new_snake.x[0] == snake.x[i] && new_snake.y[0] == snake.y[i]) { return 1; } } return 0; } int die() { for (int i = 1; i<snake.len; i++) { if (snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i]) { return 1; } } for (m = 1; m<fram_width / 3; m++) { if ((snake.x[0] == m && snake.y[0] == fram_height / 4) || (snake.x[0] == m && snake.y[0] == 3 * fram_height / 4)) { return 1; } } for (m = 2 * fram_width / 3; m<fram_width; m++) { if (snake.x[0] == m && snake.y[0] == fram_height / 2) { return 1; } } if (snake.x[0] == 0 || snake.x[0] == fram_width - 1) { return 1; } return 0; } void menu() { char str[100]; InputBox(str, 100, "請選擇:\n\n 1.傳統模式\n\n 2.雙人PK\n\n 3.退出遊戲", "蛇蛇大作戰", "", 250, 100, false); if (strcmp(str, "1") == 0) { PlaySound("F:\\Snake_bgm\\bgm1.WAV", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP); start(); initmap(); wall(); score_rule(); srand(time(NULL)); play(); } else if (strcmp(str, "2") == 0) { PlaySound("F:\\Snake_bgm\\double_play.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP); start(); double_initmap(); srand(time(NULL)); double_play(); } else if (strcmp(str, "3") == 0) { exit(0); } } void double_play()//開始雙人PK遊戲 { char str[5]; int len; int grade; while(1) { int flag=1; InputBox(str, 5, "請輸入目標分數(1~1000)\n只能輸入數字", "蛇蛇大作戰", "", 200, 100, false); len=strlen(str); str[len]='\0'; if(str[0]==NULL) continue; for(int i=0;i<len;i++) if(str[i]<'0'||str[i]>'9') { flag=0; break; } if(!flag) continue; grade=StringToInt(str,len); if(grade>0&&grade<=1000) break; } settextcolor(WHITE); outtextxy(31 * SIZE, 1 * SIZE, "目標分數:"); settextcolor(BROWN); outtextxy(36 * SIZE, 1 * SIZE, str); char k = 'a'; char t = LEFT2; //k和t分別記錄蛇前一時刻移動的方向 new_snake.count = 0; snake.count = 0; score = 0; score2 = 0; new_chushihua(); chushihua(); //初始化 int move1 = 0, move2 = 0;//標記按鍵的歸屬 char key, key1 = LEFT, key2 = LEFT2;//初始方向 double_getfood();//產生食物 while (1) { double_eatfood();//判斷是否吃到食物 double_move2(); double_move1();//移動蛇 move1 = 0; move2 = 0; if (kbhit())//如果有按鍵 { key = getch();//獲取按鍵值 switch (key)//判斷按鍵 { case UP2: case DOWN2: case LEFT2: case RIGHT2:key2 = key; move2 = 1; break;//如果按鍵屬於玩家2,move2=1; case UP: case DOWN: case LEFT: case RIGHT:key1 = key; move1 = 1; break;//如果按鍵屬於玩家1,move1=1; } } if (move1 == 1)//如果move1=1,即按鍵屬於玩家1 { if (k == LEFT && key1 == RIGHT) //防止反向咬到自己 key1 = LEFT; else if (k == UP && key1 == DOWN) key1 = UP; else if (k == RIGHT && key1 == LEFT) key1 = RIGHT; else if (k == DOWN && key1 == UP) key1 = DOWN; turn(key1);//轉向 } if (move2 == 1)//如果move2=1,即按鍵屬於玩家2 { if (t == UP2 && key2 == DOWN2) //防止反向咬到自己 key2 = UP2; else if (t == DOWN2 && key2 == UP2) key2 = DOWN2; else if (t == LEFT2 && key2 == RIGHT2) key2 = LEFT2; else if (t == RIGHT2 && key2 == LEFT2) key2 = RIGHT2; double_turn(key2);//轉向 } if (move2 == 0)//如果按鍵屬於玩家1,則玩家2的蛇繼續維持上一時刻的方向 double_turn(t); if (move1 == 0)//如果按鍵屬於玩家2,則玩家1的蛇繼續維持上一時刻的方向 turn(k); k = key1; t = key2;//獲取上一時刻的方向 if (double_die1())//判斷玩家1是否死亡 { if (score >= 15)//如果分數大於15分 score -= 15; else //如果分數小於15分,則分數清零 score = 0; for (m = 0; m<snake.len; m++)//死亡後,將遺體用背景色覆蓋 { setfillcolor(BLACK); solidrectangle(snake.x[m] * SIZE, snake.y[m] * SIZE, snake.x[m] * SIZE + SIZE, snake.y[m] * SIZE + SIZE); } k=key1=LEFT; chushihua();//初始化蛇 } if (double_die2())//如果玩家2死亡 { if (score2 >= 15) score2 -= 15; else score2 = 0; for (m = 0; m<new_snake.len; m++) { setfillcolor(BLACK); solidrectangle(new_snake.x[m] * SIZE, new_snake.y[m] * SIZE, new_snake.x[m] * SIZE + SIZE, new_snake.y[m] * SIZE + SIZE); } t=key2=LEFT2; new_chushihua(); } double_print();//畫蛇 double_initmap(); double_score_rule(); if (win(grade) == 1)//如果玩家1勝利 { PlaySound("F:\\Snake_bgm\\win.WAV", NULL, SND_FILENAME | SND_ASYNC); settextcolor(YELLOW); LOGFONT f; gettextstyle(&f); // 獲取當前字型設定 f.lfHeight = 48; // 設?米痔甯叨任? 48 _tcscpy(f.lfFaceName, _T("黑體")); // 設定字型為“黑體”(高版本 VC 推薦使用 _tcscpy_s 函式) f.lfQuality = ANTIALIASED_QUALITY; // 設定輸出效果為抗鋸齒 settextstyle(&f); // 設定字型樣式 outtextxy(8 * SIZE, 12 * SIZE, _T("玩家1勝利!")); outtextxy(8 * SIZE, 15 * SIZE, _T("按空格鍵繼續!")); while (getch() != ' ') { ; } break; } else if (win(grade) == 2)//如果玩家2勝利 { PlaySound("F:\\Snake_bgm\\win.WAV", NULL, SND_FILENAME | SND_ASYNC); settextcolor(YELLOW); LOGFONT f; gettextstyle(&f); // 獲取當前字型設定 f.lfHeight = 48; // 設?米痔甯叨任? 48 _tcscpy(f.lfFaceName, _T("黑體")); // 設定字型為“黑體”(高版本 VC 推薦使用 _tcscpy_s 函式) f.lfQuality = ANTIALIASED_QUALITY; // 設定輸出效果為抗鋸齒 settextstyle(&f); // 設定字型樣式 outtextxy(8 * SIZE, 12 * SIZE, _T("玩家2勝利!")); outtextxy(8 * SIZE, 15 * SIZE, _T("按空格鍵繼續!")); while (getch() != ' ') { ; } break; } Sleep(150); } } void play() //開始傳統模式遊戲 { char k = 'a';//k記錄前一時刻移動的方向 char ch = 'a'; snake.count = 0; score = 0; chushihua(); getfood(); while (1) { if (kbhit()) { while (1)//如果按其他鍵,則暫停 { ch = getch(); if (ch == 'w' || ch == 'a' || ch == 's' || ch == 'd') break; else continue; } } eatfood(); move(); if (k == 'a'&&ch == 'd') //防止反向咬到自己 ch = 'a'; else if (k == 'w'&&ch == 's') ch = 'w'; else if (k == 'd'&&ch == 'a') ch = 'd'; else if (k == 's'&&ch == 'w') ch = 's'; turn(ch); k = ch; if (die()) { PlaySound("F:\\Snake_bgm\\gameover.WAV", NULL, SND_FILENAME | SND_ASYNC); settextcolor(YELLOW); LOGFONT f; gettextstyle(&f); // 獲取當前字型設定 f.lfHeight = 48; // 設?米痔甯叨任? 48 _tcscpy(f.lfFaceName, _T("黑體")); // 設定字型為“黑體”(高版本 VC 推薦使用 _tcscpy_s 函式) f.lfQuality = ANTIALIASED_QUALITY; // 設定輸出效果為抗鋸齒 settextstyle(&f); // 設定字型樣式 outtextxy(8 * SIZE, 12 * SIZE, _T("Game Over!")); outtextxy(8 * SIZE, 15 * SIZE, _T("按空格鍵繼續!")); FILE *fp; int len; len = strlen(maxScore); maxScore[len] = '\0'; int maxscore; char ms[5]; maxscore = StringToInt(maxScore, len);//將字串轉化為整數 if (score>maxscore)//如果破紀錄 { fp = fopen("maxscore", "w");//將新紀錄寫入檔案,並將檔案中的原內容清空 if (fp != NULL) { itoa(score, ms, 10); fputs(ms, fp); } fclose(fp); } while (getch() != ' ') { ; } break; } print(); initmap();//畫邊框 wall();//畫障礙物 score_rule();//顯示分數和規則 Sleep(snake.speed);//速度 } }