我的第一個遊戲—SNAKE

           自己做的貪吃蛇遊戲,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;
}

發佈了74 篇原創文章 · 獲贊 232 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章