贪吃蛇(C语言版)

    软件测试课程设计,老师让写一个贪吃蛇,Em......,快要交了,查了查网上的代码,仿照着写了一个,一个下午加一个晚上的时间,感觉还不错哈哈哈(主要是学到了一些新的函数嘿嘿嘿)

    首先我们的学会用几个函数,如下:

    1.将光标移动到指定位置

        基本方法是通过封装 windows 头文件里的 SetConsoleCursorPosition 函数实现

//转移光标到目标位置
void goTo( int x , int y , int z ) {
	HANDLE hout = GetStdHandle( STD_OUTPUT_HANDLE );
	COORD cor;
	cor.X = y;
	cor.Y = x;
	SetConsoleCursorPosition( hout,cor );
	SetColor( hout,z );
}

    2.设置字体的颜色,及上面代码中 SetColor 函数

        同样利用了 windows 头文件里面的函数 SetConsoleTextAttribute

/***************************************
 * 设置字符,背景颜色
 * SetConsoleTextAttribute( hout,0xXX )
 * 第一个X为背景色,第二个X为前景色
 * 0 = 黑    1 = 蓝    2 = 绿    3 = 浅绿
 * 4 = 红    5 = 紫    6 = 黄    7 = 白
 * 8 = 灰    9 = 淡蓝  A = 淡绿  B =  淡浅绿
 * C = 淡红  D = 淡紫  E = 淡黄  F = 亮白
 ***************************************/
#define SetColor SetConsoleTextAttribute

    3.键盘输入控制方向

		if( GetKey(VK_SPACE) ) {
			pause();
		} else if( GetKey(VK_UP) ) {
			status='L';
		} else if( GetKey(VK_DOWN) ) {
			status='R';
		} else if( GetKey(VK_LEFT) ) {
			status='U';
		} else if( GetKey(VK_RIGHT) ) {
			status='D';
		}

//游戏暂停
void pause(){
	while(1){
		goTo( 21,75,7 );
		printf( "Press SPACE to continue" );
		Sleep(sleepTime);
		if( GetKey(VK_SPACE) )
			break;
	}
} 

	//判断方向 
	switch( dir ) {
		case 'D':
			h->x = head->x;
			h->y = head->y + 1;
			break;
		case 'L':
			h->x = head->x - 1;
			h->y = head->y;
			break;
		case 'U':
			h->x = head->x;
			h->y = head->y - 1;
			break;
		case 'R':
			h->x = head->x + 1;
			h->y = head->y;
	}

    4.一些简单UI

        我觉得这个就可以略过了......

    接下来附上全部代码↓↓↓(UI建的比较丑莫怪莫怪,以后心血来潮再来个高大上的)

/*
 * Name: Doodle Snake v1.0
 * Author @Di
 * Time: june 14th , 2018
 */

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <windows.h>
#include <stdlib.h>
#include <time.h>

/***************************************
 * 设置字符,背景颜色
 * SetConsoleTextAttribute( hout,0xXX )
 * 第一个X为背景色,第二个X为前景色
 * 0 = 黑    1 = 蓝    2 = 绿    3 = 浅绿
 * 4 = 红    5 = 紫    6 = 黄    7 = 白
 * 8 = 灰    9 = 淡蓝  A = 淡绿  B =  淡浅绿
 * C = 淡红  D = 淡紫  E = 淡黄  F = 亮白
 ***************************************/
#define SetColor SetConsoleTextAttribute

//从键盘读取的值
#define GetKey GetAsyncKeyState

//地图信息
#define Width 70
#define Higth 25

typedef struct snake {
	int x;
	int y;
	struct snake *next;
} s;

bool isDead;
bool m[Higth+1][Width+1];
char dir,status;//蛇移动方向,输入方向 
int score,level,length;
int sleepTime,endStatus;//运行时间间隔
s fpos,*head;

//函数声明
void init();
void goTo( int x , int y , int z );
void map();
void start();
void food();
void initSnake();
void move();
void run();
void pause();
void help();

//初始页面
void init() {
	system( "mode con cols=110 lines=30" );
	srand( ( unsigned int )time( NULL ) );
	start();
	int value;
	scanf( "%d",&value );
//	system("cls");
	if( value==0 ) {
		system( "cls" );
		memset( m,false,sizeof(m) );
		for( int i=0 ; i<Width ; i++ )
			m[0][i] = m[Higth-1][i] = 1;
		for( int i=0 ; i<Higth ; i++ )
			m[i][0] = m[i][1] = m[i][Width-2] = m[i][Width-1] = 1;
		map();
		initSnake();
		food();
		run();
	} else if( value==1 ){
		endStatus = 4;
		return;
	} else if( value==2 ){
		help();
	} else{
		init();
	}
}

//转移光标到目标位置
void goTo( int x , int y , int z ) {
	HANDLE hout = GetStdHandle( STD_OUTPUT_HANDLE );
	COORD cor;
	cor.X = y;
	cor.Y = x;
	SetConsoleCursorPosition( hout,cor );
	SetColor( hout,z );
}

//地图
void map() {
	int k;
	for( k=0 ; k<Higth ; k++ ) {
		goTo( k,0,7 );
		printf( "■" );
		goTo( k,Width-2,7 );
		printf( "■" );
	}
	for( k=0 ; k<=Width-2 ; k+=2 ) {
		goTo( 0,k,7 );
		printf( "■" );
		goTo( Higth-1,k,7 );
		printf( "■" );
	}
}

//开始
void start() {
	map();
	goTo( 5,19,9 );
	printf( "Welcome to Doodle Snake!" );
	goTo( 10,16,9 );
	printf( "0 Start" );
	goTo( 10,38,9 );
	printf( "1 Exit" );
	goTo( 15,24,9 );
	printf( "2 How to play" );
	goTo( 25,0,7 );
	system("pause");
}

//随机产生食物
void food() {
	fpos.x = 0;
	fpos.y = 0;

	while( m[fpos.x][fpos.y] ) {
		fpos.x = rand()%(Higth-1) + 1;
		fpos.y = rand()%(Width-2) + 2;
	}
	goTo( fpos.x,fpos.y,rand()%15+1 );
	printf( "#" );
}

//初始化贪吃蛇
void initSnake() {
	s *tail;
	tail = ( snake* )malloc( sizeof(snake) );
	tail->x = 12;
	tail->y = 31;
	tail->next = NULL;

	head = ( snake* )malloc( sizeof(snake) );
	head->next = tail;
	head->x = 12;
	head->y = 32;

	tail = head;

	while( tail != NULL ) {
		m[tail->x][tail->y] = 1;
		goTo( tail->x,tail->y,7 );
		printf( "$" );
		tail = tail->next;
	}
}

//蛇的移动
void move() {
	s pos,*h;
	h = ( snake* )malloc( sizeof(snake) );
	
	//前进方向与当前方向相反 
	if( status=='U' || status=='D' || status=='L' || status=='R' ){ 
		if( dir=='U' && status=='D' || dir=='D' && status=='U' || 
			dir=='L' && status=='R' || dir=='R' && status=='L' ){
			isDead = true;
			endStatus = 1;
			return;
		} else{
			dir = status;//更新方向 
		}
	} 
	
	//判断方向 
	switch( dir ) {
		case 'D':
			h->x = head->x;
			h->y = head->y + 1;
			break;
		case 'L':
			h->x = head->x - 1;
			h->y = head->y;
			break;
		case 'U':
			h->x = head->x;
			h->y = head->y - 1;
			break;
		case 'R':
			h->x = head->x + 1;
			h->y = head->y;
	}
	
	//撞到墙 
	if( head->x<1 || head->x>23 || head->y<2 || head->y>67 ){
		isDead = true;
		endStatus = 2;
		return;
	}
	
	//撞到自己 
	if( m[fpos.x][fpos.y] ){ 
		isDead = 1;
		endStatus = 3;
		return;
	}
	
	h->next = head;//更新头部 
	head = h;
	m[h->x][h->y] = true; 
	goTo( h->x,h->y,rand()%15+1 );
	putchar('$');
	
	//是食物
	if( fpos.x == h->x && fpos.y == h->y ) {
		score += level;
		if( level*level <= score )
			level++;
		length++;
		food();
	} else{
		while( h->next->next != NULL )
			h = h->next;
		m[h->next->x][h->next->y] = 0;
		goTo( h->next->x,h->next->y,0 );
		printf( " " );
		h->next = NULL;
		printf( " " );
	}
}

//游戏中.....
void run() {
	isDead = false;
	level = 1;
	status = -3; 
	dir = 'D';
	length = 2;
	while( !isDead ) {
		sleepTime = 550 - level * 50;
		goTo( 5,75,7 );
		printf( "You score:%d",score );
		goTo( 9,75,7 );
		printf( "Your Level:%d",level );
		goTo( 13,75,7 );
		printf( "Your Length: %d",length );
		goTo( 17,75,7 );
		printf( "The score of next Level: %d",level*level+1 );
		goTo( 21,75,7 );
		printf( "Press SPACE to pause   " );
		
		if( GetKey(VK_SPACE) ) {
			pause();
		} else if( GetKey(VK_UP) ) {
			status='L';
		} else if( GetKey(VK_DOWN) ) {
			status='R';
		} else if( GetKey(VK_LEFT) ) {
			status='U';
		} else if( GetKey(VK_RIGHT) ) {
			status='D';
		}
		Sleep( sleepTime );
		move();
	}
}

//Game Over !
void end() {
	goTo( 12,25,rand()%15+1 );
	switch( endStatus ){
		case 1: printf( "You can't move inversely !" ); break;
		case 2: printf( "You can't cross the wall !" ); break;
		case 3: printf( "You can't cross youself !" );  break;
		case 4: printf( "Game Over !" ); goTo( 25,0,rand()%15+1 ); exit(0);
	}
	goTo( 26,0,rand()%15+1 );
	system("pause");
	system( "cls" );
	init();
}

//游戏暂停
void pause(){
	while(1){
		goTo( 21,75,7 );
		printf( "Press SPACE to continue" );
		Sleep(sleepTime);
		if( GetKey(VK_SPACE) )
			break;
	}
} 

//帮助
void help(){
	system("cls");
	map();
	goTo( 5,30,rand()%15+1 );
	printf( "Tips" );
	goTo( 10,21,rand()%15+1 );
	printf( "0: Use ↑↓←→ to move" );
	goTo( 15,10,rand()%15+1 );
	printf( "1: Press SPACE to pause , press again to continue" );
} 

int main() {
	init();
	end();
	return 0;
}
    希望能对读者有所帮助,多多交流哦~~~



猜你喜欢

转载自blog.csdn.net/Revenant_Di/article/details/80699373