-------------------------------------------------------------------------------------------
七彩貪喫蛇小遊戲V1.0
使用純C語言編寫的控制檯貪喫蛇小遊戲,可設置遊戲難度,有連擊分數加成,蛇身顏色自動隨機變化,緩衝防閃,數據存儲保護,排行榜與音效等功能,VC++與VS編譯均通過,只使用VC自帶庫。
-------------------------------------------------------------------------------------------
純C語言編寫,手感十足。
---目前最高紀錄爲107400分,0 0 一盤大概玩了半小時。。。。
---實乃無聊時必備解壓小遊戲之良品~~~
---個人製作,遊戲可能會有少許bug,敬請諒解,轉載請註明
-------------------------------------------------------------------------------------------
遊戲截圖:
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------
源代碼:
//貪喫蛇彩色版源代碼,2018/3/8,僅供互相交流學習
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>
#include<math.h>
#include<time.h>
#include "StdAfx.h"
int snakeleng = 4; //全局變量,蛇長度
int last_dir = 'd'; //上一次蛇頭和默認朝向
int markmax[101][2]; //存儲蛇的座標信息
int n=1,l=0,g=150,e=30,h=15; //l遊戲分數,g遊戲速度,n遊戲等級,e,h食物座標
int speedflag; //遊戲調速自定義
unsigned char c; //全局接收鍵盤按鍵變量
int randcolor();
void checking();
void msg_init();
void gotoxy(int x,int y);
void HideCursor();
void GUI();
void localtime();
void marksort();
void srandcolor(int randcolor);
void keyreceive();
void gamespeedset();
void snakemsg();
void initsnake();
void printmark();
void foodrandom();
void ready_game();
void read_next_coord();
void markrank();
void food_check();
void checking();
void game_opinion();
struct body
{
int x;
int y;
};
struct body snake_body[500]; //蛇身的長度結構體,最長500
void msg_init()
{
n=1;
l=0;
g=150;
snakeleng = 4;
}
void gotoxy(int x,int y)
{
COORD c;
c.X=x-1;
c.Y=y-1;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
void HideCursor()//隱藏光標
{
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void GUI()
{
int j=1,i=0;
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN);
for(i=0;i<24;i++)
{
gotoxy(57,j++);
printf("■");
gotoxy(1,j);
printf("■");
gotoxy(81,j);
printf("■");
gotoxy(1,25);
printf("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■");
gotoxy(1,1);
printf("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■");
}
}
void localtime() //載入並刷新系統RTC時間
{
time_t now;
struct tm *timenow;
char time_end[1024];
char time_start[1024];
time(&now);
timenow = localtime(&now);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
strftime(time_end,1024,"%Y年%m月%d日",timenow);
strftime(time_start,1024,"%H:%M:%S",timenow);
gotoxy(63,17);
printf("%s",time_end);
gotoxy(63,19);
printf("%s",time_start);
}
void marksort() //分數排序
{
int i,x,temp;
for(x=0;x<10;x++) //先將排行榜的分數中最小的篩選出來
{
if(markmax[9][0]>markmax[x][0])
{
temp=markmax[9][0];
markmax[9][0]=markmax[x][0];
markmax[x][0]=temp;
temp=markmax[9][1];
markmax[9][1]=markmax[x][1];
markmax[x][1]=temp;
}
}
if(l>markmax[9][0]) //如果大於最小的纔會開始排序
{
markmax[9][0]=l;
markmax[9][1]=snakeleng+1;
for(x=0;x<10;x++) //排序並交換排行位置
{
for(i=x;i<10;i++)
{
if(markmax[x][0]<markmax[i][0])
{
temp=markmax[x][0];
markmax[x][0]=markmax[i][0];
markmax[i][0]=temp;
temp=markmax[x][1];
markmax[x][1]=markmax[i][1];
markmax[i][1]=temp;
}
}
}
}
}
int randcolor()
{
int randcolor;
srand((int)time(0));
randcolor=rand()%10;
return randcolor;
}
void srandcolor(int randcolor)
{
switch(randcolor) //產生隨機顏色
{
case 0:
SetConsoleTextAttribute(handle, FOREGROUND_GREEN ); break;
case 1:
SetConsoleTextAttribute(handle, FOREGROUND_RED ); break;
case 2:
SetConsoleTextAttribute(handle, FOREGROUND_BLUE ); break;
case 3:
SetConsoleTextAttribute(handle, FOREGROUND_GREEN | FOREGROUND_RED); break;
case 4:
SetConsoleTextAttribute(handle, FOREGROUND_GREEN | FOREGROUND_BLUE); break;
case 5:
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN ); break;
case 6:
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED ); break;
case 7:
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_BLUE ); break;
case 8:
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED); break;
case 9:
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE); break;
}
}
void keyreceive() //遊戲中鍵盤監聽和驅動模塊
{
if(kbhit())
c=getch(); //判斷按鍵模塊
if((c==75||c=='a'||c=='A')&&last_dir!='d')
{
snake_body[0].x=snake_body[0].x-2;
last_dir = 'a';
}
else if((c==75||c=='a'||c=='A')&&last_dir=='d')
{
snake_body[0].x=snake_body[0].x+2;
last_dir = 'd';
}
if((c==77||c=='d'||c=='D')&&last_dir!='a')
{
last_dir = 'd';
snake_body[0].x=snake_body[0].x+2;
}
else if((c==77||c=='d'||c=='D')&&last_dir=='a')
{
last_dir = 'a';
snake_body[0].x=snake_body[0].x-2;
}
if((c==80||c=='s'||c=='S')&&last_dir!='w')
{
snake_body[0].y=snake_body[0].y+1;
last_dir = 's';
}
else if((c==80||c=='s'||c=='S')&&last_dir=='w')
{
snake_body[0].y=snake_body[0].y-1;
last_dir = 'w';
}
if((c==72||c=='w'||c=='W')&&last_dir!='s')
{
snake_body[0].y=snake_body[0].y-1;
last_dir = 'w';
}
else if((c==72||c=='w'||c=='W')&&last_dir=='s')
{
snake_body[0].y=snake_body[0].y+1;
last_dir = 's';
}
if(c==32) //空格鍵暫停及設置模塊
{
while(1)
{
gotoxy(11,25);
srandcolor(randcolor());
printf("遊戲暫停中,方向鍵繼續,'i'鍵進入設置");
Sleep(1000);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN);
gotoxy(1,25);
printf("■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■");//防抖動
Sleep(1000);
if(kbhit())
{
c=getch();
if(c=='i'||c=='I')
{
game_opinion(); //設置模塊
GUI();
}
break;
}
}
}
srandcolor(randcolor());
gotoxy(snake_body[0].x,snake_body[0].y); //蛇的關節處變化,更加美觀
printf("●");
}
void gamespeedset() //速度設定模塊
{
if(speedflag==0)
{
if(l>=1500&&l<=4000)
{
g=120;
n=2;
}
if(l>4000&&l<=6000)
{
g=100;
n=3;
}
if(l>6000&&l<=15000)
{
g=80;
n=4;
}
if(l>15000&&l<=30000)
{
g=50;
n=5;
}
if(l>30000)
{
g=30;
n=6;
}
}
if(speedflag==1) //調速則保持速度
{
switch(n)
{
case 1:g=150;break;
case 2:g=120;break;
case 3:g=100;break;
case 4:g=80;break;
case 5:g=50;break;
case 6:g=30;break;
}
}
Sleep(g);
}
void snakemsg() //信息顯示模塊
{
gotoxy(63,4);
printf("當前難度等級:%d",n);
gotoxy(63,8);
printf("遊戲分數:%d",l);
gotoxy(63,6);
printf("蛇身長度:%d",snakeleng+1);
gotoxy(63,21);
printf("Dz by Yuan");
gotoxy(63,12);
printf("方向鍵控制小蛇");
gotoxy(63,10);
printf("最高記錄:%d",markmax[0][0]);
gotoxy(63,14);
printf("空格鍵暫停並設置 ");
gotoxy(63,23);
printf("Defend Your Time");
}
void initsnake() //初始化蛇
{
int i,temp=7;
system("cls");
last_dir = 'd';
for(i=0;i<3;i++,temp-=2)
{
snake_body[i].x=temp;
snake_body[i].y=10;
srandcolor(randcolor());
}
}
void printmark() //打印結束遊戲分數和評價
{
gotoxy(27,11);
printf("GAME OVER!");
gotoxy(26,14);
printf("最終得分:%d\n\n\n\n\n\n",l);
if(l<=5000)
{
gotoxy(24,17);
printf("評價:有待提高⊙o⊙");
}
if(l>5000&&l<=30000)
{gotoxy(24,17);
printf("評價:其實還不錯!!!");}
if(l>30000&&l<=60000)
{gotoxy(24,17);
printf("評價:閣下很厲害!");}
if(l>60000)
{
gotoxy(24,17);
printf("評價:閣下已經超神了!!!");
}
while(1)
{
gotoxy(20,20);
printf("按方向鍵繼續,M 鍵查看排行榜");
Sleep(800);
gotoxy(20,20);
printf(" ");
Sleep(800);
gotoxy(20,20);
printf("按方向鍵繼續,M 鍵查看排行榜");
Sleep(200);
if(kbhit())
break;
}
}
void foodrandom() //隨機產生食物座標
{
srand((int)time(0));
e=rand()%53+3;
h=rand()%22+2;
}
void ready_game() //進入遊戲前畫面
{
int k=20;
while(!kbhit())
{
GUI();
gotoxy(1,2);
printf("■ \n");
printf("■ \n");
printf("■ \n");
printf("■ * * \n");
printf("■ * *\n");
printf("■* * * \n");
printf("■ * * * \n");
printf("■ * * * \n");
printf("■ * * * \n");
printf("■ * * * \n");
printf("■ * * *\n");
printf("■ * * \n");
printf("■ * * \n");
printf("■ * * \n");
printf("■ \n");
printf("■ ■ ■■■ \n");
printf("■ ■ ■ ■ ■ \n");
printf("■ ■ ■ ■■⊙o⊙■ \n");
printf("■ ■ ■ ■■ ■ \n");
printf("■ ■ ■ ■ ■ \n");
printf("■ ■■■ \n");
printf("■ \n");
gotoxy(65,15);
printf("剩餘%d秒",k);
gotoxy(64,20);
printf("按任意鍵進入");
Sleep(1000);
k--;
gotoxy(14,22);
printf(" 歡 迎 來 到 我 的 貪 喫 蛇 !");
gotoxy(65,15);
printf("剩餘%d秒",k);
gotoxy(64,20);
printf(" ");
Sleep(1000);
k--;
gotoxy(65,15);
printf("剩餘%d秒",k);
if(k==0)
break;
}
}
void read_next_coord() //讀取下一個蛇座標
{
int i;
for(i=snakeleng;i>0;i--) //遍歷蛇身
{
if(i==snakeleng) //擦除蛇的尾巴
{
gotoxy(snake_body[i].x,snake_body[i].y);
printf(" ");
}
snake_body[i].x=snake_body[i-1].x; //座標給上一段蛇身
snake_body[i].y=snake_body[i-1].y;
}
srandcolor(randcolor());
gotoxy(snake_body[0].x,snake_body[0].y);
printf("■");
}
void markrank() //分數排行榜UI
{
int i;
GUI();
while(1)
{
for(i=0;i<10;i++)
{
gotoxy(4,3);
printf(" 排名 分數 長度記錄");
if(i!=9)
gotoxy(4,5+(i*2));
else
gotoxy(3,5+(i*2));
if(markmax[i][0]!=0)
{
printf(" %d %d ",i+1,markmax[i][0]);
gotoxy(40,5+(i*2));
printf(" %d",markmax[i][1]);
}
else
{
printf(" %d **** ",i+1);
gotoxy(40,5+(i*2));
printf("****");
}
}
gotoxy(62,13);
printf("按任意鍵繼續遊戲");
Sleep(1000);
gotoxy(62,13);
printf(" ");
Sleep(1000);
if(kbhit())
{
msg_init();
system("cls");
break;
}
}
}
void food_check()
{
int i,flag=1;
while(flag)
{
for(i=snakeleng;i>=0;i--) //遍歷蛇身,防止食物生成在蛇身裏
{
if((abs(snake_body[i].x-e)<2) && (abs(snake_body[i].y-h<2)))
{
e=rand()%53+3;
h=rand()%22+2;
flag = 1; //如果生成在蛇身裏就再次循環
l+=100; //運氣不錯也能加分
}
else
flag=0;
}
}
flag = 1; //下次循環再次進行判斷
}
void main()
{
HideCursor();
system("color 0a");
msg_init();
initsnake();
foodrandom();
ready_game();
system("cls");
GUI();
checking();
}
void game_opinion()
{
unsigned char set;
system("cls");
GUI();
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN );
gotoxy(3,3);
printf("【設 置】");
gotoxy(3,10);
printf("【遊 戲 說 明】");
gotoxy(3,12);
printf(" 七彩貪喫蛇小遊戲,C語言控制檯製作,VC/VS均測試通過");
gotoxy(3,14);
printf("推薦新手嘗試重構代碼,如有問題可加QQ:421736951交流,遊");
gotoxy(3,15);
printf("戲製作倉促,作者技術和精力有限,如遇BUG還請見諒!");
gotoxy(3,17);
printf("可使用右鍵點擊控制檯設置默認字體爲點陣,可設置窗口大小");
gotoxy(3,18);
printf("寬度爲83,高度爲25。");
gotoxy(3,22);
printf(" -----------coding 2018.3.7");
gotoxy(3,20);
printf("希望能給編程初學者帶來幫助,請勿將源代碼用於其他用途!");
gotoxy(60,13);
printf("方向鍵設置,回車鍵確認");
while(1)
{
if(kbhit())
set = getch();
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);
gotoxy(3,5);
printf(" 設置難度等級: %d ",n); //下面代碼都是爲設置界面顯示效果優化
gotoxy(3,7);
printf(" 設置蛇身長度: %d",snakeleng+1);
Sleep(5); //防止屏閃
if(set == 72)
{
gotoxy(3,7);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);
printf(" 設置蛇身長度: %d ",snakeleng+1);
while(1)
{
gotoxy(3,5);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN *30| FOREGROUND_GREEN*18);
printf(" 設置難度等級: %d ",n);
set = getch();
speedflag=1;
if(set==75)
{
n-=1;
set=72;
}
if(set==77)
{
n+=1;
set=72;
}
if(set==80)
{
set=80;
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);
gotoxy(3,5);
printf(" 設置難度等級: %d ",n);
break;
}
if(set==13)
{
c=77;
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE);
system("cls");
break;
}
if(n>6||n<1)
n=1;
}
}
if(set == 80)
{
while(1)
{
gotoxy(3,7);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN *30| FOREGROUND_GREEN*18);
if(snakeleng+1<10)
printf(" 設置蛇身長度: %d ",snakeleng+1);
if((snakeleng+1>9)&&(snakeleng+1<100))
printf(" 設置蛇身長度: %d ",snakeleng+1);
if((snakeleng+1>99)&&(snakeleng+1<500))
printf(" 設置蛇身長度: %d ",snakeleng+1);
set = getch();
if(set==75)
{
snakeleng-=1;
set=80;
}
if(set==77)
{
snakeleng+=1;
set=80;
}
if(set==72)
{
set=72;
break;
}
if(snakeleng>479) //可設置的長度最長爲480
snakeleng=4;
if(snakeleng<4)
snakeleng=479;
if(set==13)
break;
}
}
if(set==13)
{
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE);
system("cls");
break;
}
}
c=77;
}
void checking() //遊戲運行中核心檢測模塊
{
int i,eatflag=0,live;
unsigned char score; //接受分數按鍵
while(1)
{
read_next_coord();
keyreceive(); //在循環中沒有按鍵時也需要接收keyreceive();
if(kbhit())
keyreceive(); //非阻塞按鍵並行發生,以此改變蛇關節的外形及顏色
for(i=snakeleng;i>=2;i--) //從3蛇身開始纔可能頭碰撞到尾巴
{
if(snake_body[0].x==snake_body[i].x && snake_body[0].y==snake_body[i].y)
{
eatflag=1;
live = 0;
}
}
srandcolor(randcolor()+3);
gotoxy(e,h); //產生食物
printf("●");
if(abs(e-snake_body[0].x)<2&&abs(h-snake_body[0].y)<2)
{
snakeleng+=1;
l+=600;
gotoxy(e,h); //喫到後迅速擦除食物,並形成蛇身
printf(" ");
snakemsg();
Sleep(120); //喫到了變化顏色刷新閃爍一下分數等信息,並給一定延時減小遊戲難度
foodrandom(); //隨機升成下一個食物座標
food_check();
srandcolor(randcolor()+1);
gotoxy(e,h);
printf("●");
snake_body[snakeleng].x=snake_body[snakeleng-1].x;
snake_body[snakeleng].y=snake_body[snakeleng-1].y;
}
if((snake_body[0].x>=57||snake_body[0].x<=1||snake_body[0].y>=25||snake_body[0].y<=1||eatflag==1)) //如果撞牆或者自殺死亡
{
GUI();
live=0; //遊戲結束
marksort(); //死亡排行算法
printmark();
system("cls");
last_dir='d';
score=getch();
if((score!='m')&&(score!='M')) //如果不查看排行榜,就快速遊戲
{
system("cls"); //清屏
msg_init(); //初始化顯示信息
initsnake(); //初始化蛇身
live=1; //讓蛇處於存活狀態
speedflag=0; //默認不調速
main(); //*主函數(按方向鍵將會快速再次開始遊戲,其它鍵進入最初界面)
}
else //查看排行榜
markrank(); //排行算法
main();
}
localtime();
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN);
snakemsg();
gamespeedset(); //難度等級設定
}
}
---------------------
作者:qq_16620025
來源:CSDN
原文:https://blog.csdn.net/qq_16620025/article/details/97148223
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!