自己做的贪吃蛇游戏,Console窗口的,大家没事的时候就玩玩吧~。
这段时间实在无聊 ,由于期末考的原因,ACM落一边了,等暑期集训再好好搞,呵呵。闲来无事,就想动手编个小游戏自己乐着玩儿。早就想编个贪吃蛇,于是就动手了。开始的时候构架出来得很清晰,各类对象敲得很快,大概3个多小时,基本的雏形就有了。然后接下来就是各种细节的处理,这里很蛋疼,耗费了不少精力,但也学到了不少的东西,对C++有了更清晰的认识。最后就是各种bug,各种修复,虽然现在还存在少许bug,但都不影响游戏的运行了,试试玩玩吧。
PS:好像这是这个月的第一篇博文呢 = =#
游戏代码:
//***************************// // SNAKE C++ // // Written by zhsl // // 2012.6.10 // //***************************// #include<iostream.h> #include<stdio.h> #include<string.h> #include<windows.h> #include<time.h> #include<stdlib.h> #include<conio.h> const int WIDTH=18,LENGTH=58,MID=41; //定义地图长和宽,MID为中间分界线 const int INIT_SNAKE_W=4,INIT_SNAKE_L=5; //蛇初始坐标 const int INIT_SCORES_W=3,INIT_SCORES_L=43; //scores显示初始位置 const int INIT_SPEED_W=8,INIT_SPEED_L=43; //speed显示初始位置 const int SPEED_CYCLE=8,SPEED_LOWER=30; //设置加速周期和最大速度 const int TIME_DWELL=1000; /**********自定义数据**********/ struct NODE_COMMON{int x,y;}; //点集 struct NODE_SNAKE{ //蛇点集 int x,y; NODE_SNAKE *next; }; int Speed_Boost[6]={0,-50,-35,-35,-25,-16},K=0; //设置加速周期和加速周期点 int Dir_x[4]={0,2,0,-2},Dir_y[4]={-1,0,1,0}; int Snake_Map[WIDTH+1][LENGTH+1]; int Has_Bean; int Speed=200,Num_Speed=1; int Scores; int Is_Gameover=0; int Is_Press; NODE_COMMON BEAN; /**********获取句柄**********/ HANDLE Output=GetStdHandle(STD_OUTPUT_HANDLE); HANDLE Input=GetStdHandle(STD_INPUT_HANDLE); /**********设置光标位置**********/ void SetCursor(int x,int y){ COORD cd={x,y}; SetConsoleCursorPosition(Output,cd); } /**********FLASH类**********/ class FLASH { public: FLASH(){ picture_width=18;picture_length=80; strcpy(character,"The direction key control movement"); character_len=strlen(character); }; void Init_Picture(); //初始化picture void Flash_Snake(); //Display picture private: char character[60],character_len; char picture[20][160],picture_dis[20][160]; int picture_width,picture_length; }; void FLASH::Init_Picture(){ //初始化Flash memset(picture,32,sizeof(picture)); memset(picture,32,sizeof(picture_dis)); strcpy(picture[0]+80, " "); strcpy(picture[1]+80, " "); strcpy(picture[2]+80, " /^\\/^\\ "); strcpy(picture[3]+80, " _|__| O| "); strcpy(picture[4]+80, " \\/ /~ \\_/ \\ "); strcpy(picture[5]+80, " \\____|__________/ \\ "); strcpy(picture[6]+80, " \\_______ \\ "); strcpy(picture[7]+80, " `\\ \\ "); strcpy(picture[8]+80, " | | "); strcpy(picture[9]+80, " / / \\ "); strcpy(picture[10]+80," / / \\\\ "); strcpy(picture[11]+80," / / \\ \\ "); strcpy(picture[12]+80," / / \\ \\ "); strcpy(picture[13]+80," / / _----_ \\ \\ "); strcpy(picture[14]+80," / / _-~ ~-_ | | "); strcpy(picture[15]+80," ( ( _-~ _--_ ~-_ _/ | "); strcpy(picture[16]+80," \\ ~-____-~ _-~ ~-_ ~-_-~ / "); strcpy(picture[17]+80," ~-_ _-~ ~-_ _-~ "); strcpy(picture[18]+80, " ~--______-~ ~-___-~ "); for(int i=0;i<=picture_width;i++) strcpy(picture_dis[i],picture[i]); } void FLASH::Flash_Snake() { int i,j,speed; speed=80; for(i=0;i<picture_length-3;i++){ SetCursor(0,0); for(j=0;j<=picture_width;j++){ picture_dis[j][79+i]='\0'; printf("%s\n",picture_dis[j]+i); picture_dis[j][79+i]=picture[j][79+i]; } Sleep(speed); speed-=1; } SetCursor(33,6); speed=66; for(i=0;i<character_len;i++){ printf("%c",character[i]); Sleep(speed); speed-=2; } } /**********MAP类**********/ class MAP { public: MAP(int w,int l,int m){ width=w; length=l; mid=m; memset(map,32,sizeof(map)); } void Init_Map(){ //初始化地图 int i; for(i=0;i<width;i++)map[i][length]='\0'; for(i=1;i<width-1;i++) map[i][0]=map[i][mid]=map[i][mid+1]=map[i][length-1]='|'; for(i=1;i<mid;i++)map[0][i]=map[width-1][i]='-'; for(i+=2;i<length-1;i++)map[0][i]=map[width-1][i]='-'; } void Display_Map(){ //输出地图到屏幕 for(int i=0;i<width;i++) printf("%s\n",map[i]); } private: int width,length,mid; //整个地图的宽和长,mid为中间分界线 char map[WIDTH+1][LENGTH+1]; }; /**********MESSAGE类**********/ class MESSAGE { public: MESSAGE(){ num_speed=0;w=2; SetCursor(46,14); printf("Written"); SetCursor(46,15); printf("by zhsl"); } void Init_Message(); //初始化消息 void Put_Message(); //Display message private: int w; int num_speed; }; void MESSAGE::Init_Message(){ SetCursor(INIT_SCORES_L,INIT_SCORES_W); printf("====Scores===="); SetCursor(INIT_SPEED_L,INIT_SPEED_W); printf("====Speed====="); } void MESSAGE::Put_Message(){ SetCursor(INIT_SCORES_L,INIT_SCORES_W+2); printf(" %3d",Scores); if(Num_Speed>num_speed && K<6){ SetCursor(INIT_SPEED_L+w,INIT_SPEED_W+2); w+=2; num_speed++; Speed+=Speed_Boost[K++]; printf(">"); } } /**********SNAKE类**********/ class SNAKE{ public: SNAKE(){ head=rear=NULL; dir=1; } static int Is_Lived(int x,int y,NODE_SNAKE *rear); //SNAKE是否能gameover void Init_Snake(); //初始化SNAKE void Move_Snake(); //SNAKE移动并display void Change_Direct(int d){dir=d;} //改变蛇的移动方向 int Get_Dir(){return dir;} NODE_SNAKE Get_Head(){return *head;} NODE_SNAKE Get_Rear(){return *rear;} private: friend void Put_Snake(); NODE_SNAKE *head,*rear; int dir; }; int SNAKE::Is_Lived(int x,int y,NODE_SNAKE *rear){ if(x>0&&x<MID && y>0&&y<WIDTH-1 && (Snake_Map[y][x]==0 || (x==rear->x && y==rear->y) )) return 1; else return 0; } void SNAKE::Init_Snake(){ int i; NODE_SNAKE *q; rear=new NODE_SNAKE; rear->x=INIT_SNAKE_L,rear->y=INIT_SNAKE_W; Snake_Map[INIT_SNAKE_W][INIT_SNAKE_L]=1; rear->next=NULL; head=rear; for(i=2;i<6;i+=2){ q=new NODE_SNAKE; q->x=INIT_SNAKE_L+i; q->y=INIT_SNAKE_W; Snake_Map[INIT_SNAKE_W][INIT_SNAKE_L+i]=1; q->next=NULL; head->next=q; head=q; } for(q=rear;q;q=q->next){ SetCursor(q->x,q->y); printf("■"); } } void SNAKE::Move_Snake(){ NODE_SNAKE *q=new NODE_SNAKE; q->x=head->x+Dir_x[dir]; q->y=head->y+Dir_y[dir]; q->next=NULL; head->next=q; head=q;q=rear; if(!SNAKE::Is_Lived(head->x,head->y,rear)){ //判断是否游戏结束 SetCursor(5,8); printf(" Game Over! \n"); SetCursor(5,9); printf(" \n"); SetCursor(5,10); printf(" Press the Enter to continue \n"); SetCursor(5,11); printf(" Press the Esc to exit \n"); SetCursor(LENGTH-1,WIDTH-1); Is_Gameover=1; return; } if(head->x!=BEAN.x || head->y!=BEAN.y){ //判断是否吃到BEAN SetCursor(rear->x,rear->y); printf(" "); Snake_Map[rear->y][rear->x]=0; rear=rear->next; delete q; } else {Has_Bean=0;Scores++;Num_Speed=Scores/SPEED_CYCLE+1;} //吃到BEAN SetCursor(head->x,head->y); printf("■"); Snake_Map[head->y][head->x]=1; } /**********BEAN函数**********/ void Put_Bean() { int x,y; while(!Has_Bean){ srand((unsigned)time(NULL)); x=rand()%(MID-2)+1; if(!(x&1))x++; y=rand()%(WIDTH-2)+1; if(!Snake_Map[y][x]){ SetCursor(x,y); printf("●"); Has_Bean=1; BEAN.x=x,BEAN.y=y; } } } /**********MAIN**********/ int main() { /**********FLASH**********/ FLASH flash; flash.Init_Picture(); flash.Flash_Snake(); Sleep(TIME_DWELL*3); //停顿 /**********INI MAP**********/ while(true) { system("cls"); MAP map(WIDTH,LENGTH,MID); map.Init_Map(); map.Display_Map(); /**********INI MESSAGE**********/ MESSAGE message; message.Init_Message(); message.Put_Message(); /**********INI SNAKE**********/ SNAKE snake; snake.Init_Snake(); /**********INI BEAN**********/ Put_Bean(); SetCursor(LENGTH-1,WIDTH-1); Sleep(TIME_DWELL*2); //停顿 while(true) { snake.Move_Snake(); if(Is_Gameover){ //游戏是否继续 Sleep(800); while(true){ if(GetAsyncKeyState(VK_ESCAPE))exit(0); if(GetAsyncKeyState(13)){ Is_Gameover=0; Has_Bean=0; Speed=200,Num_Speed=1,K=0; Scores=0; memset(Snake_Map,0,sizeof(Snake_Map)); break; } } break; } if(!Has_Bean){Put_Bean();message.Put_Message();} Sleep(Speed); /**********键位响应**********/ if(GetAsyncKeyState(VK_UP) && snake.Get_Dir()!=2 && !Is_Press)snake.Change_Direct(0),Is_Press=1; if(GetAsyncKeyState(VK_DOWN) && snake.Get_Dir()!=0 && !Is_Press)snake.Change_Direct(2),Is_Press=1; if(GetAsyncKeyState(VK_LEFT) && snake.Get_Dir()!=1 && !Is_Press)snake.Change_Direct(3),Is_Press=1; if(GetAsyncKeyState(VK_RIGHT) && snake.Get_Dir()!=3 && !Is_Press)snake.Change_Direct(1),Is_Press=1; Is_Press=0; } } return 0; }