⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snake.c

📁 MiniWinOuterSM MiniWinOuterSM
💻 C
字号:
#include "games.h"
#include "prmem.h"
#define IDT_SNAKEMOVE 1
#define IDT_FOOD 2
#define STEP 8
#define DIRECT_RIGHT 0
#define DIRECT_DOWN  1
#define DIRECT_LEFT  2
#define DIRECT_UP    3 
//struct snake{
	int snakeX,snakeY;
	int chessX,chessY,chessXmax,chessYmax;
	int direct;
	int len;
	int FoodNO;
	int CurrentLevel;
	int SetSnakeMoveSpeed;
	int SetFoodSpeed;
	int		m_FOOD_NO;
	int		m_SNAKE_NO;
	int		m_SNAKE_SPEED;
	int		m_SETFOOD_SPEED;
//};
#define N 100

int LevelUp_Food[]={40,30,30,30,26,24,20,20,20,18};		//
int LevelUp_Snake_Len[]={13,20,30,40,50,60,70,80,90,98};//升级点数
//
typedef struct node1{
	int x;
	int y;
}dataXY;

typedef struct node2{
	dataXY data[N];
	int front;
	int rear;
	int curr;
}SqQueue;

SqQueue* InitQueue()
{
	SqQueue *q=(SqQueue*)PrMalloc(sizeof(SqQueue));
	q->front=0;
	q->rear=0;
	q->curr=0;
	return q;
}
void EmptyQueue(SqQueue *q)
{
	q->front=0;
	q->rear=0;
	q->curr=0;
}

void InitCurr(SqQueue *q)
{
	q->curr=(q->rear-1+N)%N;
}

int EnQueue(SqQueue *q,int xx,int yy)
{
	if((q->rear+1)%N==q->front) return 0;
	q->data[q->rear].x=xx;
	q->data[q->rear].y=yy;
	q->curr=q->rear;
	q->rear=(q->rear+1)%N;
	return 1;

}

int DeQueue(SqQueue *q,int *xx,int *yy)
{
	if(q->rear==q->front) return 0;
	*xx=q->data[q->front].x;
	*yy=q->data[q->front].y;
	q->front=(q->front+1)%N;
	return 1;

}
int DeCurr(SqQueue *q,int *xx,int *yy)
{
	//if(q->curr==q->front) return 0;
	*xx=q->data[q->curr].x;
	*yy=q->data[q->curr].y;
	q->curr=(q->curr-1+N)%N;
	return 1;
}


//

typedef struct link{
	int x;
	int y;
	struct link *next;
}FoodLink;

FoodLink* CreateNode(){
	FoodLink* p=(FoodLink*)PrMalloc(sizeof(FoodLink));
	p->x=p->y=0;
	p->next=NULL;
	return p;
}

void EmptyLink(FoodLink *head){
	FoodLink *p;
	while(head->next){
		p=head->next;
		head->next=p->next;
		PrFree(p);
	}
}
void InsertNode(FoodLink *p,int x,int y){
	FoodLink *NewNode=(FoodLink*)PrMalloc(sizeof(FoodLink));
	NewNode->x=x;
	NewNode->y=y;
	NewNode->next=p->next;
	p->next=NewNode;
}

int DeleteNode(FoodLink *head,int x,int y){
	FoodLink *p=head->next;
	FoodLink *q=head;
	while(p){
	if(p->x==x && p->y==y){
		q->next=p->next;
		PrFree(p);
		return 1;
	}
	else{p=p->next;q=q->next;}
	}
	return 0;
}


int CountNode(FoodLink *head)
{
	int count=0;
	FoodLink *p=head->next;
	while(p){
		count++;
		p=p->next;
	}
	return count;
}
//

SqQueue *Qsnake;//=InitQueue();
FoodLink *Lfood;//=CreateNode();
static void InitSnake()
{
	chessX=chessY=8;
	chessXmax=chessYmax=400;
	snakeX=chessX+STEP*2;snakeY=chessY+STEP*2;
	direct=0;
	len=3;
	FoodNO=0;
	CurrentLevel=0;
	SetSnakeMoveSpeed=550;	//550 ms
	SetFoodSpeed=2000;	//2000 ms
}
static int isLevelUp(HWND hWnd,int LevelSetp)
{
	FoodNO=CountNode(Lfood);
	if(FoodNO<=LevelUp_Food[LevelSetp] && len>=LevelUp_Snake_Len[LevelSetp]){
		//sndPlaySound(".\\res\\schoolbonus.wav",SND_ASYNC);
		PrDbgPrintf("You win Level %d ,now Enter Level %d",LevelSetp,LevelSetp+1);
		SetFoodSpeed-=50;
		SetSnakeMoveSpeed-=50;
		KillTimer(hWnd,IDT_SNAKEMOVE);
		KillTimer(hWnd,IDT_FOOD);
		SetTimer(hWnd,IDT_SNAKEMOVE,SetSnakeMoveSpeed,NULL);
		SetTimer(hWnd,IDT_FOOD,SetFoodSpeed,NULL);
		len-=(STEP+LevelSetp*STEP);
		return ++LevelSetp;
	}
	return LevelSetp;
}
static void isFaile(HWND hWnd)
{
	int curr_x,curr_y,Queue_len;
	if(snakeX>chessXmax||snakeY>chessYmax||snakeX<chessX||snakeY<chessY){
		KillTimer(hWnd,IDT_SNAKEMOVE);
		KillTimer(hWnd,IDT_FOOD);
		//MessageBox("Sorry!You Loss!!");
		return;
	}
	Queue_len=(Qsnake->rear-Qsnake->front+N)%N;
	if(Queue_len>98){
		KillTimer(hWnd,IDT_SNAKEMOVE);
		KillTimer(hWnd,IDT_FOOD);
		//MessageBox("Sorry!You Loss!!");
		return;
	}
	while(Queue_len--){
		DeCurr(Qsnake,&curr_x,&curr_y);
		if(snakeX==curr_x && snakeY==curr_y){
			KillTimer(hWnd,IDT_SNAKEMOVE);
			KillTimer(hWnd,IDT_FOOD);
			//sndPlaySound(".\\res\\die.wav",SND_ASYNC);
			//MessageBox("Sorry!You Loss!!");
			return;
		}
	}
	if(DeleteNode(Lfood,snakeX,snakeY)){
		//sndPlaySound(".\\res\\playereat.wav",SND_ASYNC);
		len++;
		CurrentLevel=isLevelUp(hWnd,CurrentLevel);
		if(CurrentLevel==9){
			//sndPlaySound(".\\res\\oysterbite.wav",SND_ASYNC);
			PrDbgPrintf("congratulate!You win!!\n");
		}
		//
		m_SNAKE_SPEED=SetSnakeMoveSpeed;
		m_SETFOOD_SPEED=SetFoodSpeed;
		//UpdateData(0);
	}
}
static void OnPaint(HWND hwnd,unsigned int msgID,unsigned int wParam,unsigned int lParam)
{
	HDC hdc=GetDC(hwnd);
	RECT rc;
	FoodLink *p=Lfood->next;
	int Queue_len;
	int curr_x,curr_y;
	int setp;
	HBRUSH hbr,oldhbr;
	SetRect(&rc,chessX,chessY,chessXmax,chessYmax);
	InflateRect(&rc,(STEP+1)/2,(STEP+1)/2);
	FillRect(hdc,&rc,(HBRUSH)(COLOR_BTNFACE+1));
	hbr=CreateSolidBrush(RGB(0,0,255));
	oldhbr=(HBRUSH)SelectObject(hdc,(HGDIOBJ)hbr);
	while(p){
		Ellipse(hdc,p->x-5,p->y-5,p->x+5,p->y+5);
		p=p->next;
	}
	SelectObject(hdc,(HGDIOBJ)oldhbr);
	DeleteObject((HGDIOBJ)hbr);
	PrFree(p);
	
	switch(direct){
	case DIRECT_RIGHT:	//d
		snakeX+=STEP;		isFaile(hwnd);		EnQueue(Qsnake,snakeX,snakeY);
		break;
	case DIRECT_DOWN:	//s
		snakeY+=STEP;		isFaile(hwnd);		EnQueue(Qsnake,snakeX,snakeY);
		break;
	case DIRECT_LEFT:	//a
		snakeX-=STEP;		isFaile(hwnd);		EnQueue(Qsnake,snakeX,snakeY);
		break;
	case DIRECT_UP:	//w
		snakeY-=STEP;		isFaile(hwnd);		EnQueue(Qsnake,snakeX,snakeY);
		break;
	}
	Queue_len=(Qsnake->rear-Qsnake->front+N)%N;  //循环队列元属总数
	m_SNAKE_NO=Queue_len;
	setp=Queue_len;
	while(setp--){
		DeCurr(Qsnake,&curr_x,&curr_y);
		Ellipse(hdc,curr_x-5,curr_y-5,curr_x+5,curr_y+5);
	}
	InitCurr(Qsnake);
	while(Queue_len>len?1:0){
		DeQueue(Qsnake,&curr_x,&curr_y);
		Queue_len=(Qsnake->rear-Qsnake->front+N)%N;
	}
}
static LRESULT SnakeProc(HWND hwnd,unsigned int msgID,WPARAM wParam,LPARAM lParam)
{
	switch(msgID){
	case WM_PAINT:
		{
		HDC hdc;
		PAINTSTRUCT ps;
		//DefaultWndProc(hwnd,msgID,wParam,lParam);
		hdc=BeginPaint(hwnd,&ps);
		OnPaint(hwnd,msgID,wParam,lParam);
		EndPaint(hwnd,&ps);
		}break;
	case WM_TIMER:
		if(wParam==IDT_SNAKEMOVE){
			//OnPaint(hwnd,WM_PAINT,0,0);
			InvalidateRect(hwnd,NULL,FALSE);
			//InvalidateRect(CRect(chessX,chessY,chessXmax,chessYmax));
		}else if(wParam==IDT_FOOD){
			int tempX,tempY;
			srand( (unsigned)time( NULL ) );
			tempX=rand()%(chessXmax-chessX)+chessX;	tempX-=tempX%STEP;
			tempY=rand()%(chessXmax-chessX)+chessY; tempY-=tempY%STEP;
			InsertNode(Lfood,tempX,tempY);
			m_FOOD_NO=CountNode(Lfood);
		}
		break;
	case WM_KEYDOWN:
		if((wParam==VK_RIGHT)&&(direct!=DIRECT_LEFT)){
			direct=DIRECT_RIGHT;
		}
		if((wParam==VK_DOWN)&&(direct!=DIRECT_UP)){
			direct=DIRECT_DOWN;
		}
		if((wParam==VK_LEFT)&&(direct!=DIRECT_RIGHT)){
			direct=DIRECT_LEFT;
		}
		if((wParam==VK_UP)&&(direct!=DIRECT_DOWN)){
			direct=DIRECT_UP;
		}
		return DefWindowProc(hwnd,msgID,wParam,lParam);
	default:return DefWindowProc(hwnd,msgID,wParam,lParam);
	}
	return 0;
}
HWND CreateSnake(void)
{
	HWND hwnd=CreateMainWindow("Snake",WS_VISIBLE|WS_BORDER|WS_CAPTION|WS_SYSMENU,50,50,400,400,SnakeProc);
	Qsnake=InitQueue();
	Lfood=CreateNode();
	InitSnake();
	SetTimer(hwnd,IDT_SNAKEMOVE,SetSnakeMoveSpeed,NULL);
	SetTimer(hwnd,IDT_FOOD,SetFoodSpeed,NULL);
	ShowWindow(hwnd,SW_SHOWNORMAL);
	return hwnd;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -