C语言的贪吃蛇源代码

C语言的贪吃蛇源代码,第1张

 

//友情提示:如想速度快点,请改小_sleep(500)函数中参数  

#include <stdioh>  

#include <stdlibh>  

#include <conioh>  

#include <stringh>  

#include <timeh>  

const int H = 8;   //地图的高  

const int L = 16;  //地图的长  

char GameMap[H][L];   //游戏地图  

int  key;  //按键保存  

int  sum = 1, over = 0;  //蛇的长度, 游戏结束(自吃或碰墙)  

int  dx[4] = {0, 0, -1, 1};  //左、右、上、下的方向  

int  dy[4] = {-1, 1, 0, 0};  

struct Snake   //蛇的每个节点的数据类型  

{  

 int x, y;  //左边位置  

 int now;   //保存当前节点的方向, 0,1,2,3分别为左右上下  

}Snake[HL];  

const char Shead = '@';  //蛇头  

const char Sbody = '#';  //蛇身  

const char Sfood = '';  //食物  

const char Snode = '';  //''在地图上标示为空  

void Initial();  //地图的初始化  

void Create_Food(); //在地图上随机产生食物  

void Show();   //刷新显示地图  

void Button();  //取出按键,并判断方向  

void Move();   //蛇的移动  

void Check_Border();  //检查蛇头是否越界  

void Check_Head(int x, int y);   //检查蛇头移动后的位置情况  

int main()   

{  

 Initial();  

 Show();  

 return 0;  

}  

void Initial()  //地图的初始化  

{  

 int i, j;  

 int hx, hy;  

 system("title 贪吃蛇");  //控制台的标题  

 memset(GameMap, '', sizeof(GameMap));  //初始化地图全部为空''  

 system("cls");  

 srand(time(0));   //随机种子  

 hx = rand()%H;    //产生蛇头  

 hy = rand()%L;  

 GameMap[hx][hy] = Shead;  

 Snake[0]x = hx;  Snake[0]y = hy;  

 Snake[0]now = -1;  

 Create_Food();   //随机产生食物  

 for(i = 0; i < H; i++)   //地图显示  

 {   

  for(j = 0; j < L; j++)  

   printf("%c", GameMap[i][j]);  

  printf("\n");  

 }  

     

 printf("\n小小C语言贪吃蛇\n");  

 printf("按任意方向键开始游戏\n");  

    

 getch();   //先接受一个按键,使蛇开始往该方向走  

 Button();  //取出按键,并判断方向  

}  

void Create_Food()  //在地图上随机产生食物  

{  

 int fx, fy;  

 while(1)  

 {  

  fx = rand()%H;  

     fy = rand()%L;  

     

  if(GameMap[fx][fy] == '')  //不能出现在蛇所占有的位置  

  {   

   GameMap[fx][fy] = Sfood;  

      break;  

  }  

 }  

}  

void Show()  //刷新显示地图  

{  

 int i, j;  

 while(1)  

 {    

  _sleep(500); //延迟半秒(1000为1s),即每半秒刷新一次地图  

  Button();   //先判断按键在移动  

  Move();  

  if(over)  //自吃或碰墙即游戏结束  

  {   

   printf("\n游戏结束\n");  

   printf("     >_<\n");  

   getchar();  

      break;  

  }  

  system("cls");   //清空地图再显示刷新吼的地图  

  for(i = 0; i < H; i++)   

  {   

   for(j = 0; j < L; j++)  

    printf("%c", GameMap[i][j]);  

   printf("\n");  

  }  

     

  printf("\n小小C语言贪吃蛇\n");  

  printf("按任意方向键开始游戏\n");  

 }  

}  

void Button()  //取出按键,并判断方向  

{  

 if(kbhit() != 0) //检查当前是否有键盘输入,若有则返回一个非0值,否则返回0  

 {   

  while(kbhit() != 0)  //可能存在多个按键,要全部取完,以最后一个为主  

      key = getch(); //将按键从控制台中取出并保存到key中  

  switch(key)  

  {   //左  

   case 75:  Snake[0]now = 0;  

          break;  

            //右  

            case 77:  Snake[0]now = 1;       

          break;  

            //上  

   case 72:  Snake[0]now = 2;  

          break;  

            //下  

   case 80:  Snake[0]now = 3;  

          break;  

  }  

 }  

}  

void Move()   //蛇的移动  

{  

 int i, x, y;  

    int t = sum;  //保存当前蛇的长度  

 //记录当前蛇头的位置,并设置为空,蛇头先移动  

 x = Snake[0]x;  y = Snake[0]y;  GameMap[x][y] = '';  

 Snake[0]x = Snake[0]x + dx[ Snake[0]now ];  

 Snake[0]y = Snake[0]y + dy[ Snake[0]now ];  

 Check_Border();   //蛇头是否越界  

 Check_Head(x, y);  //蛇头移动后的位置情况,参数为: 蛇头的开始位置  

 if(sum == t)  //未吃到食物即蛇身移动哦  

    for(i = 1; i < sum; i++)  //要从蛇尾节点向前移动哦,前一个节点作为参照  

 {  

  if(i == 1)   //尾节点设置为空再移动  

   GameMap[ Snake[i]x ][ Snake[i]y ] = '';  

     

  if(i == sum-1)  //为蛇头后面的蛇身节点,特殊处理  

  {  

   Snake[i]x = x;  

         Snake[i]y = y;  

      Snake[i]now = Snake[0]now;  

  }  

  else   //其他蛇身即走到前一个蛇身位置  

  {  

   Snake[i]x = Snake[i+1]x;  

         Snake[i]y = Snake[i+1]y;  

      Snake[i]now = Snake[i+1]now;  

  }  

      

  GameMap[ Snake[i]x ][ Snake[i]y ] = '#'; //移动后要置为'#'蛇身   

 }  

}  

void Check_Border()  //检查蛇头是否越界  

{  

 if(Snake[0]x < 0 || Snake[0]x >= H  

 || Snake[0]y < 0 || Snake[0]y >= L)  

     over = 1;  

}  

void Check_Head(int x, int y)  //检查蛇头移动后的位置情况  

{  

    

 if(GameMap[ Snake[0]x ][ Snake[0]y ] == '')  //为空  

  GameMap[ Snake[0]x ][ Snake[0]y ] = '@';  

 else 

  if(GameMap[ Snake[0]x ][ Snake[0]y ] == '')  //为食物  

  {  

   GameMap[ Snake[0]x ][ Snake[0]y ] = '@';    

   Snake[sum]x = x;   //新增加的蛇身为蛇头后面的那个  

      Snake[sum]y = y;  

      Snake[sum]now = Snake[0]now;  

         GameMap[ Snake[sum]x ][ Snake[sum]y ] = '#';   

   sum++;  

   Create_Food();  //食物吃完了马上再产生一个食物  

  }  

  else 

   over = 1;  

}

/

C/C++贪吃蛇游戏,zjlj,2015316

/

#define DEBUG 0 //当程序在调试阶段时 DEBUG为 1

#include<iostream>

#include<windowsh>

#include<timeh>

#include<conioh>

using namespace std;

void readini(FILE fphead, int score, char argv[]) //创建或打开一个和运行文件对应的ini文件,读取最高纪录

{

char filename[200],pfilename;

int flag=-1,i;

strcpy(filename,argv[0]);

for(i=0;filename[i]!='\0';i++)

{

if (''==filename[i])flag=1;

}

if(1==flag)

{

filename[i-1]='i';

filename[i-2]='n';

filename[i-3]='i';

}

else

{

filename[i]='';

filename[i+1]='i';

filename[i+2]='n';

filename[i+3]='i';

filename[i+4]='\0';

}

for(;filename[i]!='\\'&&i>=0;i--)pfilename=&filename[i];

if ( (fphead=fopen(pfilename, "rb+"))==NULL)

{

if ( (fphead=fopen(pfilename, "wb+"))==NULL)

{

printf("无法创建或打开\"%s\"文件\n",pfilename);

system("pause");

exit(0);

}

}

else

{

fread(score,sizeof(int),1,fphead);

}

}

void writeini(FILE fphead, int score, char argv[]) //打开一个和运行文件对应的ini文件,写入最高纪录

{

char filename[200],pfilename;

int flag=-1,i;

strcpy(filename,argv[0]);

for(i=0;filename[i]!='\0';i++)

{

if (''==filename[i])flag=1;

}

if(1==flag)

{

filename[i-1]='i';

filename[i-2]='n';

filename[i-3]='i';

}

else

{

filename[i]='';

filename[i+1]='i';

filename[i+2]='n';

filename[i+3]='i';

filename[i+4]='\0';

}

for(;filename[i]!='\\'&&i>=0;i--)pfilename=&filename[i];

if ( (fphead=fopen(pfilename, "wb+"))==NULL)

{

printf("无法写入\"%s\"文件,磁盘写保护!\n",pfilename);

system("pause");

exit(0);

}

else

{

rewind(fphead);

fwrite(score,sizeof(int),1,fphead);

fclose(fphead);

}

}

void gotoxy(int x,int y)//光标定位,光标定位函数SetConsoleCursorPosition是左上角位置是0,0然后向左向下延伸

{

COORD pos;

posX=2y;

posY=x;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);

}

void color(int a)//颜色函数

{

SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);

}

void Refresh(int q[][22], int grade, int gamespeed, int length,int score) // 输出贪吃蛇棋盘

{

int i,j;

for(i=0;i<22;i++)

{

for(j=0;j<22;j++)

{

if(q[i][j]==0)//输出棋盘空白

{

gotoxy(i,j);

color(11);

cout<<"■";

}

if(q[i][j]==1||q[i][j]==2)//输出棋盘墙壁

{

gotoxy(i,j);

color(11);

cout<<"□";

}

if(q[i][j]==3)//输出蛇头

{

gotoxy(i,j);

color(14);

cout<<"★";

}

if(q[i][j]==4)//输出蛇身

{

gotoxy(i,j);

color(12);

cout<<"◆";

}

if(q[i][j]==5)//输出果子

{

gotoxy(i,j);

color(12);

cout<<"●";

}

}

if(i==0) cout << "\t";

if(i==1) cout << "\t等级为:" << grade;//显示等级

if(i==3) cout << "\t自动前进时间";

if(i==4) cout << "\t间隔为:" << gamespeed << "ms";//显示时间

if(i==6) cout << "\t历史最高分为:" << score << "分";

if(i==7) cout << "\t你现在得分为:" << (length+(grade-1)8)10 << "分";

if(i==8) cout << "\t";

if(i==9) cout << "\t游戏说明:";

if(i==10) cout << "\t(1)用小键盘方向键控制";

if(i==11) cout << "\t蛇头运动方向;";

if(i==12) cout << "\t(2)蛇每吃一个果子蛇身";

if(i==13) cout << "\t增加一节;";

if(i==14) cout << "\t(3)蛇咬到自己或碰到墙";

if(i==15) cout << "\t壁游戏结束。";

if(i==18) cout << "\t";

if(i==19) cout << "\tC/C++语言作业:";

if(i==20) cout << "\tzjlj,20150316 ";

}

}

int main(int argc, char argv[]){

int tcsQipan[22][22]; // 贪吃蛇棋盘是一个二维数组(如2222,包括墙壁)

int i,j,score,directiontemp;

FILE fpini;//fpini 信息文件

readini(&fpini, &score, argv);//读取ini文件的最高纪录

if (score<0)//最高成绩小于零设置为零,初建文件会是负数

score=0;

while(1)

{

for(i=1;i<=20;i++)

for(j=1;j<=20;j++)

tcsQipan[i][j]=0; //贪吃蛇棋盘相应坐标标上中间空白部分的标志0

for(i=0;i<=21;i++)

tcsQipan[0][i] = tcsQipan[21][i] = 1; //贪吃蛇棋盘相应坐标标上上下墙壁的标志1

for(i=1;i<=20;i++)

tcsQipan[i][0] = tcsQipan[i][21] = 2; //贪吃蛇棋盘相应坐标标上左右墙壁的标志2

int tcsZuobiao[2][500]; //蛇的坐标数组

for(i=0; i<4; i++)

{

tcsZuobiao[0][i] = 1;//蛇身和蛇头的x坐标

tcsZuobiao[1][i] = i + 1;//蛇身和蛇头的y坐标

}

int head = 3,tail = 0;//标示蛇头和蛇尾的数组偏移量

for(i=1;i<=3;i++)

tcsQipan[1][i]=4; //蛇身

tcsQipan[1][4]=3; //蛇头

int x1, y1; // 随机出果子

srand(time(0));//设置随机种子

do

{

x1=rand()%20+1;

y1=rand()%20+1;

}

while(tcsQipan[x1][y1]!=0);//如果不是在空白处重新出果子

tcsQipan[x1][y1]=5;//贪吃蛇棋盘相应坐标标上果子的标志5

color(12);

cout<<"\n\n\t\t\t\t贪吃蛇游戏即将开始 !"<<endl;//准备开始

long start,starttemp;

int grade = 1, length = 4; //设置初始等级和蛇的初始长度

int gamespeed = 500; //设置初始前进时间间隔

for(i=3;i>=0;i--)

{

start=clock();

while(clock()-start<=1000);

system("cls");

if(i>0)

cout << "\n\n\t\t\t\t进入倒计时:" << i << endl; //倒计时显示

else

Refresh(tcsQipan,grade,gamespeed,length,score); //初始棋盘显示

}

int timeover=1,otherkey=1;//初始化超时时间和按键判断参数

char direction = 77; // 设置初始情况下,向右运动

int x=tcsZuobiao[0][head],y=tcsZuobiao[1][head];//保存蛇头坐标到x,y变量

while(1)//运行一局游戏

{

start = clock();

while((timeover=((starttemp=clock())-start<=gamespeed))&&!kbhit());//如果有键按下或时间超过自动前进时间间隔则终止循环

if(direction==72||direction==80||direction==75 ||direction==77)

directiontemp=direction;//保留上一次方向按键

//starttemp=gamespeed+start-starttemp;//保留停留时间

if(timeover)

{

#if (DEBUG==1)

direction = getch();//调试代码

#else

if((direction =getch())==-32)

direction = getch();

#endif

}

#if (DEBUG==1)//调试代码

start=clock();

while(clock()-start<=2000);

gotoxy(24,4);

cout << "\t按键ASCII代码"<<(int)direction<<" "<<endl;

#endif

if(!(direction==72||direction==80||direction==75 ||direction==77))

{

otherkey=0;// 按键非方向键,otherkey设置为0

}

else

{

otherkey=1;// 按键为方向键,otherkey设置为1

}

if(direction==72 && directiontemp==80)//忽略反方向按键

{

direction=32;

otherkey=0;

//start = clock();

//while(clock()-start<=starttemp);

}

else if(direction==80 && directiontemp==72)

{

direction=32;//设置按键为非方向键

otherkey=0;// 按键为非方向键,otherkey设置为0

// start = clock();

//while(clock()-start<=starttemp);//补偿等待时间

}

else if(direction==75 && directiontemp==77)

{

direction=32;

otherkey=0;

//start = clock();

//while(clock()-start<=starttemp);

}

else if(direction==77 && directiontemp==75)

{

direction=32;

otherkey=0;

//start = clock();

//while(clock()-start<=starttemp);

}

switch(direction)//判断方向键

{

case 72: x= tcsZuobiao[0][head]-1; y= tcsZuobiao[1][head];break; // 向上

case 80: x= tcsZuobiao[0][head]+1; y= tcsZuobiao[1][head];break; // 向下

case 75: x= tcsZuobiao[0][head]; y= tcsZuobiao[1][head]-1;break; // 向左

case 77: x= tcsZuobiao[0][head]; y= tcsZuobiao[1][head]+1;break; // 向右

default: break;

}

if(x==0 || x==21 ||y==0 || y==21) // 蛇头碰到墙壁,结束本局游戏

{

gotoxy(22,12);

cout << "\t游戏已结束!" << endl;

if(score>=(length+(grade-1)8)10)//判断是否破记录

{

gotoxy(10,7);

color(12);

cout << "闯关失败 加油耶!" << endl;

fclose(fpini);//关闭ini文件

}

else

{

gotoxy(10,7);

color(12);

cout << "恭喜您打破记录" << endl;

score=(length+(grade-1)8)10;

writeini(&fpini, &score, argv);//写入ini文件的最高纪录

}

gotoxy(23,12);

cout << "按回车键重新开始,按ESC退出游戏" << endl;//显示的提示

break;//退出该局游戏

}

if(tcsQipan[x][y]!=0&&!(x==x1&&y==y1)&&tcsQipan[x][y]!=3) // 蛇头碰到蛇身,结束本局游戏

{

gotoxy(22,12);

cout << "\t游戏已结束!" << endl;

if(score>=(length+(grade-1)8)10)//判断是否破记录

{

gotoxy(10,7);

color(12);

cout << "闯关失败 加油耶!" << endl;

fclose(fpini);//关闭ini文件

}

else

{

gotoxy(10,7);

color(12);

cout << "恭喜您打破记录" << endl;

score=(length+(grade-1)8)10;

writeini(&fpini, &score, argv);//写入ini文件的最高纪录

}

gotoxy(23,12);

cout << "按回车键重新开始,按ESC退出游戏" << endl;//显示的提示

break;//退出该局游戏

}

/

游戏运行时的核心算法开始

/

if(x==x1 && y==y1) // 吃果子,长度加1

{

length ++;

if(length>=8)//长度大于等于8重新计算长度,等级加1

{

length -= 8;//重新计算长度

grade ++;//等级加1

if(gamespeed>50)//控制最快速度为50

gamespeed = 550 - grade 50; // 改变自动前进时间间隔

}

tcsQipan[x][y]= 3;//贪吃蛇棋盘相应坐标现在蛇头标志改为蛇头标志3

tcsQipan[tcsZuobiao[0][head]][tcsZuobiao[1][head]] = 4;//贪吃蛇棋盘相应坐标原来蛇头标志改为蛇身标志4

head = (head+1)%400;//防止数组越界

tcsZuobiao[0][head] = x;//蛇头的x坐标

tcsZuobiao[1][head] = y;//蛇头的y坐标

do//随机出果子

{

x1=rand()%20+1;

y1=rand()%20+1;

}

while(tcsQipan[x1][y1]!=0);//如果不是在空白处重新出果子

tcsQipan[x1][y1]=5;//贪吃蛇棋盘相应坐标标上果子的标志5

gotoxy(22,12);

cout << "\t游戏进行中!" << endl;

Refresh(tcsQipan,grade,gamespeed,length,score);

}

else // 不吃果子

{

if(otherkey)

{

tcsQipan [tcsZuobiao[0][tail]][tcsZuobiao[1][tail]]=0;

tail=(tail+1)%400;//防止数组越界

tcsQipan [tcsZuobiao[0][head]][tcsZuobiao[1][head]]=4;

head=(head+1)%400;//防止数组越界

tcsZuobiao[0][head]=x;//蛇头的x坐标

tcsZuobiao[1][head]=y;//蛇头的y坐标

tcsQipan[tcsZuobiao[0][head]][tcsZuobiao[1][head]]=3;

gotoxy(22,12);

cout << "\t游戏进行中!" << endl;

Refresh(tcsQipan,grade,gamespeed,length,score);

}

else

{

gotoxy(22,12);

cout << "\t游戏暂停中!" << endl;

}

}

/

游戏运行时的核心算法结束

/

}

while(1)

{

while(!kbhit());

if((direction =getch())==13)//按回车键开始下一局

break;

if(direction ==27)//按ESC退出游戏

exit(0);

}

system("cls");//清除屏幕重新开始

}

return 0;

}

达到你说的要求,可以使用kbhit()函数,上百度搜一下它的用法,这个函数可以检测到游戏中是否有按键被按下,如果没有就使用一个死循环使蛇身一直移动,如果检测到了有按键被按下,就判断是否是方向键或者程序中设置的其他功能键(如ESC退出键,调速键等),如果不是,不做响应,如果是,就就bioskey()函数接收这个键,并根据这个键值做出相应的响应!

写游戏要注意模块化,你这样全写在main里很乱的。

使用数组解决贪吃蛇的问题有点挠头,最好是自己构造一个合适的数据类型。

还有就是学习一下<graphicsh>这个头文件,只需要里面的几个函数就可以设计贪吃蛇的图形界面。

给你个现成的贪吃蛇游戏,代码不长,仔细看一下里面的数据结构和算法思想。

/ 贪吃蛇游戏 /

#define N 200

#include <graphicsh>

#include <stdlibh>

#include <dosh>

#define LEFT 0x4b00

#define RIGHT 0x4d00

#define DOWN 0x5000

#define UP 0x4800

#define ESC 0x011b

int i,key;

int score=0;/得分/

int gamespeed=50000;/游戏速度自己调整/

struct Food

{

int x;/食物的横坐标/

int y;/食物的纵坐标/

int yes;/判断是否要出现食物的变量/

}food;/食物的结构体/

struct Snake

{

int x[N];

int y[N];

int node;/蛇的节数/

int direction;/蛇移动方向/

int life;/ 蛇的生命,0活着,1死亡/

}snake;

void Init(void);/图形驱动/

void Close(void);/图形结束/

void DrawK(void);/开始画面/

void GameOver(void);/结束游戏/

void GamePlay(void);/玩游戏具体过程/

void PrScore(void);/输出成绩/

/主函数/

void main(void)

{

Init();/图形驱动/

DrawK();/开始画面/

GamePlay();/玩游戏具体过程/

Close();/图形结束/

}

/图形驱动/

void Init(void)

{

int gd=DETECT,gm;

/ initgraph(&gd,&gm,"c:\\tc"); /

initgraph(&gd,&gm,"c:\\JMSOFT\\DRV");

}

/开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙/

void DrawK(void)

{

/setbkcolor(LIGHTGREEN);/

setcolor(11);

setlinestyle(SOLID_LINE,0,THICK_WIDTH);/设置线型/

for(i=50;i<=600;i+=10)/画围墙/

{

rectangle(i,40,i+10,49); /上边/

rectangle(i,451,i+10,460);/下边/

}

for(i=40;i<=450;i+=10)

{

rectangle(50,i,59,i+10); /左边/

rectangle(601,i,610,i+10);/右边/

}

}

/玩游戏具体过程/

void GamePlay(void)

{

randomize();/随机数发生器/

foodyes=1;/1表示需要出现新食物,0表示已经存在食物/

snakelife=0;/活着/

snakedirection=1;/方向往右/

snakex[0]=100;snakey[0]=100;/蛇头/

snakex[1]=110;snakey[1]=100;

snakenode=2;/节数/

PrScore();/输出得分/

while(1)/可以重复玩游戏,压ESC键结束/

{

while(!kbhit())/在没有按键的情况下,蛇自己移动身体/

{

if(foodyes==1)/需要出现新食物/

{

foodx=rand()%400+60;

foody=rand()%350+60;

while(foodx%10!=0)/食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到/

foodx++;

while(foody%10!=0)

foody++;

foodyes=0;/画面上有食物了/

setcolor(GREEN);

rectangle(foodx,foody,foodx+10,foody-10);

}

for(i=snakenode-1;i>0;i--)/蛇的每个环节往前移动,也就是贪吃蛇的关键算法/

{

snakex[i]=snakex[i-1];

snakey[i]=snakey[i-1];

}

/1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头/

switch(snakedirection)

{

case 1:snakex[0]+=10;break;

case 2: snakex[0]-=10;break;

case 3: snakey[0]-=10;break;

case 4: snakey[0]+=10;break;

}

for(i=3;i<snakenode;i++)/从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来/

{

if(snakex[i]==snakex[0]&&snakey[i]==snakey[0])

{

GameOver();/显示失败/

snakelife=1;

break;

}

}

if(snakex[0]<55||snakex[0]>595||snakey[0]<55||

snakey[0]>455)/蛇是否撞到墙壁/

{

GameOver();/本次游戏结束/

snakelife=1; /蛇死/

break;

}

if(snakex[0]==foodx&&snakey[0]==foody)/吃到食物以后/

{

setcolor(0);/把画面上的食物东西去掉/

rectangle(foodx,foody,foodx+10,foody-10);

snakex[snakenode]=-20;snakey[snakenode]=-20;

/新的一节先放在看不见的位置,下次循环就取前一节的位置/

snakenode++;/蛇的身体长一节/

foodyes=1;/画面上需要出现新的食物/

score+=10;

PrScore();/输出新得分/

}

setcolor(4);/画出蛇/

for(i=0;i<snakenode;i++)

rectangle(snakex[i],snakey[i],snakex[i]+10,

snakey[i]-10);

delay(gamespeed);

setcolor(0);/用黑色去除蛇的的最后一节/

rectangle(snakex[snakenode-1],snakey[snakenode-1],

snakex[snakenode-1]+10,snakey[snakenode-1]-10);

} /endwhile(!kbhit)/

if(snakelife==1)/如果蛇死就跳出循环/

break;

key=bioskey(0);/接收按键/

if(key==ESC)/按ESC键退出/

break;

else

if(key==UP&&snakedirection!=4)

/判断是否往相反的方向移动/

snakedirection=3;

else

if(key==RIGHT&&snakedirection!=2)

snakedirection=1;

else

if(key==LEFT&&snakedirection!=1)

snakedirection=2;

else

if(key==DOWN&&snakedirection!=3)

snakedirection=4;

}/endwhile(1)/

}

/游戏结束/

void GameOver(void)

{

cleardevice();

PrScore();

setcolor(RED);

settextstyle(0,0,4);

outtextxy(200,200,"GAME OVER");

getch();

}

/输出成绩/

void PrScore(void)

{

char str[10];

setfillstyle(SOLID_FILL,YELLOW);

bar(50,15,220,35);

setcolor(6);

settextstyle(0,0,2);

sprintf(str,"score:%d",score);

outtextxy(55,20,str);

}

/图形结束/

void Close(void)

{

getch();

closegraph();

}

这个程序有只有一个地方需要改,就是initgraph(&gd,&gm,"c:\\JMSOFT\\DRV");

这句代码中的第三个参数是 bgi文件的路径,你按下键盘上的alt + f 搜索一下 bgi在哪个目录下,把那个路径复制到这个地方就可以了直接运行了,不然可能提示你 初始化错误!。

程序设计及说明

1

、边墙(

Wall

该类规定游戏的范围大小。

2

、蛇类(

Snake

用该类生成一个实例蛇

snake

3

、移动(

Move

该类用于实现对蛇的 *** 作控制,即蛇头方向的上下左右的移动 *** 作。

4

、食物类(

Food

该类是游戏过程中食物随机产生的控制和显示。

5

、判断死亡(

Dead

该类是对游戏过程中判断玩家 *** 作是否导致蛇的死亡,其中包括蛇头咬食自己身体和蛇头是否触

及游戏“边墙”。

6

、蛇结点(

SnakeNode

该类是蛇吃下随机产生的食物从而增加长度的控制类,其中包括蛇长度增加和尾部的变化。

7

、计分统计(

Score

该类由于玩家的游戏成绩记录,及游戏结束时的得分输出。

部分函数及说明

1Char menu();

/

用于玩家选择的游戏速度,返回一个

char

/

2DELAY(char ch1);

/

用于控制游戏速度

/

3void drawmap();

/

绘制游戏地图函数

4

void menu()

/

游戏帮助信息的输出

部分类细节解说

1

、蛇的构建

Snake

class Snake{

public:

int x[n]

int y[n];

int node;

//

蛇身长度

int direction;//

蛇运动方向

int

life;//

蛇生命,判断死亡

2

、随机食物

Food

利用

rand(

)函数进行随机数产生,然后就行坐标定位

void Food(void){

int pos_x = 0;

int pos_y = 0;

pos_x = rand() % length;//x

坐标的确定

pos_y = rand() % (width-1);//y

坐标的确定

3

、蛇头方向确定

利用

switch

语句进行方向确定

switch(){

case VK_UP:{

OutChar2Y--;

y--;

break;

}

case VK_LEFT:{

OutChar2Y++;

y++;

break;

}

case VK_DOWN:{

OutChar2X---;

x--;

break;

}

case 'VK_RIGHT:{

OutChar2X++;

x++;

break;

}

}

代码

#include <iostream>

#include <ctime>

#include <conioh>

#include <windowsh>

#include <timeh>

using namespace std;

int score=0,t=300,f=1;//

得分与时间间隔

/ms

(控制贪吃蛇的速度)

double ss=0,tt=0;//

统计时间所用参数

class Node

{

Node(): x(0), y(0), prior(0), next(0) { }

int x;

int y;

Node prior;

Node next;

friend class Snake;

};

class Snake

{

public:

Snake();

~Snake();

void output();

void move();

void change_point(char);

private:

Node head;

Node tail;

enum p{ UP

, RIGHT, DOWN, LEFT }point; //

方向

int food_x, food_y; //

食物的坐标

static const int N = 23;

int game[N][N];

void add_head(int, int); //

添加坐标为

a,b

的结点

void delete_tail(); //

删除最后一个结点

void greate_food(); //

产生食物

void gotoxy(int, int);

};

void menu();

//

游戏 *** 作菜单

int main()

{

system("color a");

//

初始

cmd

窗口颜色为黑(背景)淡绿(文字)

cout<<"\n\n\n\n\n\n

";

for(int i=0;i<23;i++)

{char star[]={"Welcome To Snake Game!"};

cout<<star[i];

Sleep(170);}

cout<<"\n\n

祝你好运!

"<<endl;

Sleep(3000);

if(kbhit()){char kk=getch();if(kk==9)f=5;} //

如果执行,吃一颗星加

5

system("cls");

Snake s;

menu();

system("color 1a");

soutput();

while (true)

{

char keydown = getch();

if(keydown==32)getch();

if(keydown==27)return 0;

schange_point(keydown);

while (!kbhit())

{clock_t start,end;start=clock();

smove();

soutput();

Sleep(t);

end=clock();tt=(double)(end-start)/CLOCKS_PER_SEC;ss+=tt;

cout<<"

时间:

"<<(int)ss;

/

程序名称:贪食蛇

原作者:BigF

修改者:algo

说明:我以前也用C写过这个程序,现在看到BigF用Java写的这个,发现虽然作者自称是Java的初学者,

但是明显编写程序的素养不错,程序结构写得很清晰,有些细微得地方也写得很简洁,一时兴起之

下,我认真解读了这个程序,发现数据和表现分开得很好,而我近日正在学习MVC设计模式,

因此尝试把程序得结构改了一下,用MVC模式来实现,对源程序得改动不多。

我同时也为程序增加了一些自己理解得注释,希望对大家阅读有帮助。

/

package mvcTest;

/

@author WangYu

@version 10

Description:

</pre>

Create on :Date :2005-6-13 Time:15:57:16

LastModified:

History:

/

public class GreedSnake {

public static void main(String[] args) {

SnakeModel model = new SnakeModel(20,30);

SnakeControl control = new SnakeControl(model);

SnakeView view = new SnakeView(model,control);

//添加一个观察者,让view成为model的观察者

modeladdObserver(view);

(new Thread(model))start();

}

}

------------------------------------------

package mvcTest;

//SnakeControljava

import javaawteventKeyEvent;

import javaawteventKeyListener;

/

MVC中的Controler,负责接收用户的 *** 作,并把用户 *** 作通知Model

/

public class SnakeControl implements KeyListener{

SnakeModel model;

public SnakeControl(SnakeModel model){

thismodel = model;

}

public void keyPressed(KeyEvent e) {

int keyCode = egetKeyCode();

if (modelrunning){ // 运行状态下,处理的按键

switch (keyCode) {

case KeyEventVK_UP:

modelchangeDirection(SnakeModelUP);

break;

case KeyEventVK_DOWN:

modelchangeDirection(SnakeModelDOWN);

break;

case KeyEventVK_LEFT:

modelchangeDirection(SnakeModelLEFT);

break;

case KeyEventVK_RIGHT:

modelchangeDirection(SnakeModelRIGHT);

break;

case KeyEventVK_ADD:

case KeyEventVK_PAGE_UP:

modelspeedUp();

break;

case KeyEventVK_SUBTRACT:

case KeyEventVK_PAGE_DOWN:

modelspeedDown();

break;

case KeyEventVK_SPACE:

case KeyEventVK_P:

modelchangePauseState();

break;

default:

}

}

// 任何情况下处理的按键,按键导致重新启动游戏

if (keyCode == KeyEventVK_R ||

keyCode == KeyEventVK_S ||

keyCode == KeyEventVK_ENTER) {

modelreset();

}

}

public void keyReleased(KeyEvent e) {

}

public void keyTyped(KeyEvent e) {

}

}

------------------------------

/

/

package mvcTest;

/

游戏的Model类,负责所有游戏相关数据及运行

@author WangYu

@version 10

Description:

</pre>

Create on :Date :2005-6-13 Time:15:58:33

LastModified:

History:

/

//SnakeModeljava

import javaxswing;

import javautilArrays;

import javautilLinkedList;

import javautilObservable;

import javautilRandom;

/

游戏的Model类,负责所有游戏相关数据及运行

/

class SnakeModel extends Observable implements Runnable {

boolean[][] matrix; // 指示位置上有没蛇体或食物

LinkedList nodeArray = new LinkedList(); // 蛇体

Node food;

int maxX;

int maxY;

int direction = 2; // 蛇运行的方向

boolean running = false; // 运行状态

int timeInterval = 200; // 时间间隔,毫秒

double speedChangeRate = 075; // 每次得速度变化率

boolean paused = false; // 暂停标志

int score = 0; // 得分

int countMove = 0; // 吃到食物前移动的次数

// UP and DOWN should be even

// RIGHT and LEFT should be odd

public static final int UP = 2;

public static final int DOWN = 4;

public static final int LEFT = 1;

public static final int RIGHT = 3;

public SnakeModel( int maxX, int maxY) {

thismaxX = maxX;

thismaxY = maxY;

reset();

}

public void reset(){

direction = SnakeModelUP; // 蛇运行的方向

timeInterval = 200; // 时间间隔,毫秒

paused = false; // 暂停标志

score = 0; // 得分

countMove = 0; // 吃到食物前移动的次数

// initial matirx, 全部清0

matrix = new boolean[maxX][];

for (int i = 0; i < maxX; ++i) {

matrix[i] = new boolean[maxY];

Arraysfill(matrix[i], false);

}

// initial the snake

// 初始化蛇体,如果横向位置超过20个,长度为10,否则为横向位置的一半

int initArrayLength = maxX > 20 10 : maxX / 2;

nodeArrayclear();

for (int i = 0; i < initArrayLength; ++i) {

int x = maxX / 2 + i;//maxX被初始化为20

int y = maxY / 2; //maxY被初始化为30

//nodeArray[x,y]: [10,15]-[11,15]-[12,15]~~[20,15]

//默认的运行方向向上,所以游戏一开始nodeArray就变为:

// [10,14]-[10,15]-[11,15]-[12,15]~~[19,15]

nodeArrayaddLast(new Node(x, y));

matrix[x][y] = true;

}

// 创建食物

food = createFood();

matrix[foodx][foody] = true;

}

public void changeDirection(int newDirection) {

// 改变的方向不能与原来方向同向或反向

if (direction % 2 != newDirection % 2) {

direction = newDirection;

}

}

/

运行一次

@return

/

public boolean moveOn() {

Node n = (Node) nodeArraygetFirst();

int x = nx;

int y = ny;

// 根据方向增减坐标值

switch (direction) {

case UP:

y--;

break;

case DOWN:

y++;

break;

case LEFT:

x--;

break;

case RIGHT:

x++;

break;

}

// 如果新坐标落在有效范围内,则进行处理

if ((0 <= x && x < maxX) && (0 <= y && y < maxY)) {

if (matrix[x][y]) { // 如果新坐标的点上有东西(蛇体或者食物)

if (x == foodx && y == foody) { // 吃到食物,成功

nodeArrayaddFirst(food); // 从蛇头赠长

// 分数规则,与移动改变方向的次数和速度两个元素有关

int scoreGet = (10000 - 200 countMove) / timeInterval;

score += scoreGet > 0 scoreGet : 10;

countMove = 0;

food = createFood(); // 创建新的食物

matrix[foodx][foody] = true; // 设置食物所在位置

return true;

} else // 吃到蛇体自身,失败

return false;

} else { // 如果新坐标的点上没有东西(蛇体),移动蛇体

nodeArrayaddFirst(new Node(x, y));

matrix[x][y] = true;

n = (Node) nodeArrayremoveLast();

matrix[nx][ny] = false;

countMove++;

return true;

}

}

return false; // 触到边线,失败

}

public void run() {

running = true;

while (running) {

try {

Threadsleep(timeInterval);

} catch (Exception e) {

break;

}

if (!paused) {

if (moveOn()) {

setChanged(); // Model通知View数据已经更新

notifyObservers();

} else {

JOptionPaneshowMessageDialog(null,

"you failed",

"Game Over",

JOptionPaneINFORMATION_MESSAGE);

break;

}

}

}

running = false;

}

private Node createFood() {

int x = 0;

int y = 0;

// 随机获取一个有效区域内的与蛇体和食物不重叠的位置

do {

Random r = new Random();

x = rnextInt(maxX);

y = rnextInt(maxY);

} while (matrix[x][y]);

return new Node(x, y);

}

public void speedUp() {

timeInterval = speedChangeRate;

}

public void speedDown() {

timeInterval /= speedChangeRate;

}

public void changePauseState() {

paused = !paused;

}

public String toString() {

String result = "";

for (int i = 0; i < nodeArraysize(); ++i) {

Node n = (Node) nodeArrayget(i);

result += "[" + nx + "," + ny + "]";

}

return result;

}

}

class Node {

int x;

int y;

Node(int x, int y) {

thisx = x;

thisy = y;

}

}

---------------------------------------

package mvcTest;

//SnakeViewjava

import javaxswing;

import javaawt;

import javautilIterator;

import javautilLinkedList;

import javautilObservable;

import javautilObserver;

/

MVC模式中得Viewer,只负责对数据的显示,而不用理会游戏的控制逻辑

/

public class SnakeView implements Observer {

SnakeControl control = null;

SnakeModel model = null;

JFrame mainFrame;

Canvas paintCanvas;

JLabel labelScore;

public static final int canvasWidth = 200;

public static final int canvasHeight = 300;

public static final int nodeWidth = 10;

public static final int nodeHeight = 10;

public SnakeView(SnakeModel model, SnakeControl control) {

thismodel = model;

thiscontrol = control;

mainFrame = new JFrame("GreedSnake");

Container cp = mainFramegetContentPane();

// 创建顶部的分数显示

labelScore = new JLabel("Score:");

cpadd(labelScore, BorderLayoutNORTH);

// 创建中间的游戏显示区域

paintCanvas = new Canvas();

paintCanvassetSize(canvasWidth + 1, canvasHeight + 1);

paintCanvasaddKeyListener(control);

cpadd(paintCanvas, BorderLayoutCENTER);

// 创建底下的帮助栏

JPanel panelButtom = new JPanel();

panelButtomsetLayout(new BorderLayout());

JLabel labelHelp;

labelHelp = new JLabel("PageUp, PageDown for speed;", JLabelCENTER);

panelButtomadd(labelHelp, BorderLayoutNORTH);

labelHelp = new JLabel("ENTER or R or S for start;", JLabelCENTER);

panelButtomadd(labelHelp, BorderLayoutCENTER);

labelHelp = new JLabel("SPACE or P for pause", JLabelCENTER);

panelButtomadd(labelHelp, BorderLayoutSOUTH);

cpadd(panelButtom, BorderLayoutSOUTH);

mainFrameaddKeyListener(control);

mainFramepack();

mainFramesetResizable(false);

mainFramesetDefaultCloseOperation(JFrameEXIT_ON_CLOSE);

mainFramesetVisible(true);

}

void repaint() {

Graphics g = paintCanvasgetGraphics();

//draw background

gsetColor(ColorWHITE);

gfillRect(0, 0, canvasWidth, canvasHeight);

// draw the snake

gsetColor(ColorBLACK);

LinkedList na = modelnodeArray;

Iterator it = naiterator();

while (ithasNext()) {

Node n = (Node) itnext();

drawNode(g, n);

}

// draw the food

gsetColor(ColorRED);

Node n = modelfood;

drawNode(g, n);

updateScore();

}

private void drawNode(Graphics g, Node n) {

gfillRect(nx nodeWidth,

ny nodeHeight,

nodeWidth - 1,

nodeHeight - 1);

}

public void updateScore() {

String s = "Score: " + modelscore;

labelScoresetText(s);

}

public void update(Observable o, Object arg) {

repaint();

}

}

以上就是关于C语言的贪吃蛇源代码全部的内容,包括:C语言的贪吃蛇源代码、谁有用c语言制作贪吃蛇的代码,及使用方法,用VC打、c语言简易版贪吃蛇怎么写用一个方块形状代表蛇的一个关节(如:printf("%c",4)是一个方块图样)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/9797734.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-02
下一篇 2023-05-02

发表评论

登录后才能评论

评论列表(0条)

保存