|
本帖最后由 小张haha 于 2012-6-11 09:53 编辑
自己做的贪吃蛇游戏,Console窗口的,大家没事的时候就玩玩吧~。
这段时间实在无聊 ,由于期末考的原因,ACM落一边了,等暑期集训再好好搞,呵呵。闲来无事,就想动手编个小游戏自己乐着玩儿。早就想编个贪吃蛇,于是就动手了。开始的时候构架出来得很清晰,各类对象敲得很快,大概3个多小时,基本的雏形就有了。然后接下来就是各种细节的处理,这里很蛋疼,耗费了不少精力,但也学到了不少的东西,对C++有了更清晰的认识。最后就是各种bug,各种修复,虽然现在还存在少许bug,但都不影响游戏的运行了,试试玩玩吧。
游戏代码:
//***************************//
// 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,picture);
}
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);
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[length]='\0';
for(i=1;i<width-1;i++)
map[0]=map[mid]=map[mid+1]=map[length-1]='|';
for(i=1;i<mid;i++)map[0]=map[width-1]='-';
for(i+=2;i<length-1;i++)map[0]=map[width-1]='-';
}
void Display_Map(){ //输出地图到屏幕
for(int i=0;i<width;i++)
printf("%s\n",map);
}
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;
}
Snake的exe文件
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|