C++控制台界面库_实例5: 贪吃蛇

代码如下:

// Snake.cpp : 定义控制台应用程序的入口点。
//

#include “stdafx.h”
#include <process.h>
#include “console.h”
#include “LinkedList_snake.h”
#include <time.h>

void jiemian0(); // 0

void ThreadTime(void *);
int EndThreadTime=1;

int game_time=180; //游戏时间
int PlayAgain();
char *Date_Time();
void SaveScore(char *,int score);

int main()
{
Screen screen;
screen.SetTitle(“贪吃蛇”);
screen.ShowOrHideCursor(0);

Event event;
event.AddMouseMode();

do
{
	jiemian0();	
}while(PlayAgain());

event.RestoreMode();
screen.SetTextColorAndTextBackgroundColor(2,14);
screen.MoveCursorTo(3,26);
screen.Pause();
screen.Close_handle();
return 0;

}

void jiemian0()
{
char *date_time=Date_Time();

Screen screen;
screen.SetSize(70,30);	
screen.Paint_screen(14);

Window window=Window(2,1,66,20);
window.window_textcolor_num=2;
window.Paint_window(0);

Window window1=Window(2,22,30,4);
window1.Attribute(4,14,14,false,false,0);
window1.DisplayStringEx_window("键盘:\nW A S D控制方向,←减速,→加速,Esc退出。");

LinkedList_snake snake;

COORD food={30,17};
screen.Character_color_num=3;
screen.DisplayCharacter(food,'*',1);
COORD poison={30,7};
screen.Character_color_num=2;
screen.DisplayCharacter(poison,'*',1);

srand((unsigned)time(0));

Button EXIT_button=Button(40,26,"退出");
EXIT_button.button_color_num=2;
EXIT_button.button_Bgcolor_num=14;
EXIT_button.Display_button();

screen.TextAttribute(2,14);
screen.DisplayText(35,22,"速度:");

Slider speed=Slider(42,22,26);
speed.Attribute(2,4,5);
speed.Display();

int time_min=100,time_max=1000;
int time1=300;
float temp=(1000-time1)/900.0;
speed.Renew_percent(temp);

int score=0;
char *over=NULL;

_beginthread(ThreadTime,0,NULL);

Event event;	

screen.SetTextColorAndTextBackgroundColor(3,14);
screen.MoveCursorTo(58,24);
printf("            ");

while(1)
{
	if(event.PeekEvent())   // 有事件输入时
	{			
		event.ReadEvent();
		if(event.Mouse_Event())
		{
			if(EXIT_button.MousePosition_At_button()
				&&event.Left_Button_Pressed())
			{
				over="选择了退出。";
				EndThreadTime=0;
				break;
			}
			
			if(speed.MousePostion_At_Slider()
				&&event.Left_Button_Pressed())
			{
				speed.Renew_mouse();					
				time1=1000-900*speed.percent;
			}				
		}
		
		if(event.Key_Event()&&event.Key_Down())
		{
			char ch=event.Get_ch(); 
			WORD vk=event.Get_vk();

			if(ch=='q'||vk==VK_ESCAPE)
			{
				over="选择了退出。";
				EndThreadTime=0;
				break; 
			}

			if(ch=='a'||ch=='A')
			{
				if(snake.direction!=D_RIGHT)snake.direction=D_LEFT;
			}
			if(ch=='w'||ch=='W')
			{
				if(snake.direction!=D_DOWN)snake.direction=D_UP;
			}
			if(ch=='d'||ch=='D')
			{
				if(snake.direction!=D_LEFT)snake.direction=D_RIGHT;
			}
			if(ch=='s'||ch=='S')
			{
				if(snake.direction!=D_UP)snake.direction=D_DOWN;
			}

			if(vk==VK_LEFT)
			{
				if(time1<time_max)time1+=900/speed.length;
				temp=(1000-time1)/900.0;
				speed.Renew_percent(temp);					
			}
			if(vk==VK_RIGHT)
			{
				if(time1>time_min)time1-=900/speed.length;
				temp=(1000-time1)/900.0;
				speed.Renew_percent(temp);					
			}
		}
	}
	
	snake.GetHeadNewtPosition();
			
	if(!window.Point_At_window(snake.HeadNewPosition))
	{			
		over="撞墙了!";			
		EndThreadTime=0;
		break;
	}
	
	// 蛇运动
	snake.UpdateSnakeBody();
	snake.DeleteTail();
	snake.AddNodeAtHead();
	snake.PrintSnakeHead();
	
	if(snake.EatFood(food))
	{			
		snake.PaintSnake(3,0);
		snake.AddNodeAtTail(5,6);

		do
		{
			food.X=window.cx0+(int)(rand()%window.wide);
			food.Y=window.cy0+(int)(rand()%window.heigh);
		}while(snake.FoodAtSnake(food));
		screen.Character_color_num=3;
		screen.DisplayCharacter(food,'*',1);

		score+=100*speed.percent;
		screen.MoveCursorTo(58,24);
		printf("加%3d 分",(int)(100*speed.percent));
	}

	if(snake.biteself())
	{			
		over="咬到自己了!";			
		EndThreadTime=0;
		break;
	}		

	if(snake.EatFood(poison))
	{
		if(snake.Length()>1)
		{
			snake.PaintSnake(2,0);
			snake.UpdateSnakeBody();
			snake.DeleteTail();
			snake.PrintSnakeHead();

			do
			{
				poison.X=window.cx0+(int)(rand()%window.wide);
				poison.Y=window.cy0+(int)(rand()%window.heigh);
			}while(snake.FoodAtSnake(poison));
			screen.Character_color_num=2;
			screen.DisplayCharacter(poison,'*',1);

			score-=(1.0-speed.percent)*100;
		    screen.MoveCursorTo(58,24);
		    printf("减%3d 分",(int)((1.0-speed.percent)*100));		
		}
		else 
		{				
			over="毒死了!";				
			EndThreadTime=0;
			break;
		}
	}

	if(game_time==0)
	{			
		over="时间到!";			
		break;
	}

	Sleep(time1);
}

window.Clear_window();
window.DisplayString_window((window.wide-strlen("Game over!"))/2,(window.heigh-1)/2,"Game over!");
char food_num[20];
sprintf_s(food_num,20,"吃到的食物数:%d",snake.Length()-1);
window.DisplayString_window((window.wide-strlen(food_num))/2,(window.heigh-1)/2+4,food_num);
window.DisplayString_window((window.wide-strlen(over))/2,(window.heigh-1)/2+2,over);	

char temp0[20];
score+=(snake.Length()-1)*10;
sprintf_s(temp0,20,"得分: %d",score);
window.DisplayString_window((window.wide-strlen(temp0))/2,(window.heigh-1)/2+6,temp0);
SaveScore(date_time,score);

snake.DeleteLb();

}

void ThreadTime(void *) // 显示时间
{
Screen screen;

screen.TextAttribute(2,14);
char temp[20];

while(1)
{		
	sprintf_s(temp,20,"剩余时间: %d 秒",game_time);
	screen.DisplayText(35,24,temp);       	
    if(game_time==0||EndThreadTime==0)break;
	Sleep(1000);
	game_time--;
}

}

int PlayAgain()
{
HWND hwnd=GetConsoleWindow();
if(MessageBox(hwnd,TEXT(“Play again?”),TEXT(""),MB_YESNO)==IDYES)
{
EndThreadTime=1;game_time=180;return 1;
}
else return 0;
}

char *Date_Time()
{
time_t take_off;
struct tm timeinfo;
char *date_time=new char[20];

take_off = time(NULL);
localtime_s (&timeinfo,&take_off);
strftime(date_time,20,"%Y-%m-%d %H:%M:%S",&timeinfo);

return date_time;

}

void SaveScore(char *date_time,int score)
{
FILE *fp;
errno_t err;

err=fopen_s(&fp,"score.txt","a");
fprintf(fp,"%s  %d\n",date_time,score);
fclose(fp);

}

// LinkedList_snake.h 文件

#include <windows.h>

#define D_LEFT 0
#define D_UP 1
#define D_RIGHT 2
#define D_DOWN 3

// 蛇链表类

struct Node_snake
{
int x;
int y;
struct Node_snake *next;
};

class LinkedList_snake
{

private:

COORD  Pos;

public:

Node_snake *head;
COORD HeadNewPosition;  //蛇头的下一个位置
int direction;

LinkedList_snake(void);
	
Node_snake *FindNode(int ip);
int Length();
void PrintSnakeHead();
void UpdateSnakeBody();
void AddNodeAtTail(int x,int y);
void DeleteNode(int i);	
void DeleteTail();
void DeleteLb();	
void GetHeadNewtPosition();
void AddNodeAtHead();
int biteself();
int FoodAtSnake(COORD food);
void PaintSnake(int color_num,int Bgcolor_num);
int EatFood(COORD food);

};

// LinkedList_snake.cpp 文件

#include “StdAfx.h”
#include “console.h”
#include “LinkedList_snake.h”

LinkedList_snake::LinkedList_snake()
{
head=NULL;
AddNodeAtTail(20,4);

direction=D_RIGHT;		

}

Node_snake* LinkedList_snake::FindNode(int ip) //单链表的查找 ip为链表的查找位置
{
if(head == NULL) return NULL;

int count = 0;
Node_snake *pNext = head;
while(count < ip && pNext != NULL)
{
     pNext = pNext->next;
     count++;
}
return pNext;

}

int LinkedList_snake::Length()
{
int n=0;
Node_snake *temp;
temp = head;
while(temp != NULL)
{
n++;
temp = temp->next;
}
return n;
}

void LinkedList_snake::PrintSnakeHead()
{
Screen screen;

screen.SetTextColorAndTextBackgroundColor(3,0);
screen.MoveCursorTo(head->x,head->y);
switch(direction)
{
case D_UP:
	screen.Write("↑");
	break;
case D_DOWN:
	screen.Write("↓");
	break;
case D_LEFT:
	screen.Write("←");
	break;
case D_RIGHT:
	screen.Write("→");
	break;
}

return; 

}

void LinkedList_snake::UpdateSnakeBody()
{
Node_snake* temp;
Screen screen;

screen.SetTextColorAndTextBackgroundColor(7,0);
screen.MoveCursorTo(head->x,head->y);
screen.Write("●");

temp=head;
while(temp->next!=NULL)
{
	temp=temp->next;     
}
screen.MoveCursorTo(temp->x,temp->y);
screen.Write("  ");
return; 

}

void LinkedList_snake::AddNodeAtTail(int x,int y)
{
Node_snake *temp,*newnode;

newnode=new Node_snake;
newnode->x=x;
newnode->y=y;

if(head==NULL)
{
   head= newnode;       
}            
else
{
   temp=head;
   while(temp->next!=NULL)
   {
    temp=temp->next;
   }

   temp->next= newnode;       
}
newnode->next=NULL;    

}

void LinkedList_snake::DeleteTail()
{
DeleteNode(Length()-1);
}

void LinkedList_snake::DeleteNode(int i ) //删除位置i的节点
{
Node_snake* p = NULL;
Node_snake* p1 = NULL;
Node_snake* p2 = NULL;

if( head == NULL )  return ;
if( i == 0)
{
	p=head;
	head = head->next;
	delete p;
}
else
{
	p1 = FindNode(i-1);         //上一个节点
	p  = FindNode(i);
	p2 = FindNode(i+1);         //下一个节点
	delete p;
	p1->next = p2;                      
}	

}

void LinkedList_snake::DeleteLb()
{
Node_snake* temp;

while(head!=NULL)
{
	temp=head->next;		
	delete head;
	head=temp;
}	

}

void LinkedList_snake::GetHeadNewtPosition()
{
if(directionD_LEFT)
{
HeadNewPosition.X=head->x-2;
HeadNewPosition.Y=head->y;
}
if(direction
D_UP)
{
HeadNewPosition.X=head->x;
HeadNewPosition.Y=head->y-1;
}
if(directionD_RIGHT)
{
HeadNewPosition.X=head->x+2;
HeadNewPosition.Y=head->y;
}
if(direction
D_DOWN)
{
HeadNewPosition.X=head->x;
HeadNewPosition.Y=head->y+1;
}
}

void LinkedList_snake::AddNodeAtHead()
{
Node_snake *newnode;

newnode=new Node_snake;
newnode->x=HeadNewPosition.X;
newnode->y=HeadNewPosition.Y;

newnode->next=head;
head=newnode;

}

int LinkedList_snake::biteself()//判断是否咬到了自己
{
Node_snake *self;
self=head->next;
while(self!=NULL)
{
if(self->xhead->x && self->yhead->y)
{
return 1;
}
self=self->next;
}
return 0;
}

int LinkedList_snake::FoodAtSnake(COORD food)
{
Node_snake *self;

self=head;
while(self!=NULL)
{
	if((self->x==food.X||self->x+1==food.X) && self->y==food.Y)
	{
		return 1;
	}
	self=self->next;
}
return 0;

}

void LinkedList_snake::PaintSnake(int color_num,int Bgcolor_num)
{
Node_snake* temp;
Screen screen;

temp=head;
while(temp!=NULL)
{
	Pos.X=temp->x;
	Pos.Y=temp->y;		
	screen.PaintCharacter(Pos,color_num,Bgcolor_num,2);
	Sleep(20);
	temp=temp->next;     
}

Sleep(150);
	
temp=head;
while(temp!=NULL)
{
	Pos.X=temp->x;
	Pos.Y=temp->y;		
	if(temp==head)screen.PaintCharacter(Pos,3,0,2);
	else screen.PaintCharacter(Pos,7,0,2);
	temp=temp->next;     
}
return; 

}

int LinkedList_snake::EatFood(COORD food)
{
if((head->xfood.X||head->x+1food.X)&&head->y==food.Y)return 1;
else return 0;
}

运行效果:

在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/aier_wl/article/details/107695192