• 贪吃蛇游戏 1.0


    编译环境:Visual Studio 2019

    注:使用了Easyx 图形库。Easyx下载 Easyx官网

    Easyx 图形库安装教程:https://blog.csdn.net/weixin_43919932/article/details/102996507

    说明:此贪吃蛇游戏为第一版,使用了库中提供的简单的描线绘图功能所设计,不含资源包。可直接测试运行,贪吃蛇游戏 2.0在此基础上增加了贴图功能,界面相对部分优化。另外,为方便测试,在代码初始位置预留属性框中各属性参数均可自由调整

    直接上代码:

    #define _CRT_SECURE_NO_WARNINGS
    #define _CRT_NON_CONFORMING_SWPRINTFS
    #undef UNICODE
    #undef _UNICODE	
    #include <stdio.h>
    #include <stdlib.h>
    #include <graphics.h>
    #include <conio.h>
    #include <time.h>
    #include <windows.h>
    
    /*--------------------------------属 性---------------------------*/
    #define WIDE 1200		/* 窗口大小  WIDE * HIGH像素   	 */
    #define HIGH 700
    #define FORM 200		/*	设置文字边框宽度  */
    #define SIZE 40				//每节蛇的尺寸
    #define LEN 100				//蛇的最长长度
    #define COLOUR RGB(rand()%255,rand()%255,rand()%255)	//彩色
    
    static int speed = 100;		//速度(控制刷新的时间间隔)
    
    enum Direction { right = 77, left = 75, down = 80, up = 72, Esc = 27 };//枚举方向值
    
    
    /*---------------------------资源-------------------------------------*/
    //蛇
    typedef struct _snake
    {
    	int x[LEN];				//坐标—X
    	int y[LEN];				//坐标—Y
    	int len;				//长度
    	int count;				//分数
    	int direction;			//方向
    }Snake;
    
    //食物
    typedef struct _food
    {
    	int x;
    	int y;
    	int flg;
    }Food;
    
    
    /************************************************************/
    //变量
    Snake snake;		//蛇
    Food  food;			//食物
    //函数
    void Form();			//文字提示框
    void Init_Snake();		//初始化蛇
    void Init_Food();		//初始化食物
    void ShowSnake();		//贴图画蛇
    void ShowFood();		//贴图画食物
    void MoveSnake();		//蛇的移动
    void KeyDown();			//控制
    void EatFood();			//吃食物
    int GameOver();			//游戏结束
    
    
    
    
    void Form()
    {
    	setlinecolor(BLACK);					//画线颜色
    	setfillcolor(WHITE);
    	fillrectangle(0, 0, WIDE, HIGH - 1);	//边框
    
    	setfillcolor(RGB(254, 236, 232));		//右侧文字框背景色
    	fillrectangle(WIDE - FORM, 0, WIDE, HIGH / 3);	//上提示框,实时显示分数
    	fillrectangle(WIDE - FORM, HIGH / 3, WIDE, HIGH);	//下提示框,操作手册
    	setbkmode(TRANSPARENT);		//文字透明方式
    	settextcolor(LIGHTBLUE);	//文字颜色
    	TCHAR  str[3][50];
    	_stprintf(str[0], _T("   得分:%4d 分"), snake.count);
    	_stprintf(str[1], _T("   速度:%4d 级"), (100 - speed) / 20);
    	_stprintf(str[2], _T("   长度:%4d 节"), snake.len);
    	for (int i = 0; i < 3; ++i)
    	{
    		outtextxy(WIDE - FORM + 10, i * 20 + 20, str[i]);	//指定位置输出字符串
    	}
    
    	TCHAR  str2[10][50];
    	_stprintf(str2[0], _T("提示:一枚果实10分 "));
    	_stprintf(str2[1], _T("      撞到墙,或撞到自己"));
    	_stprintf(str2[2], _T("      游戏游戏"));
    	_stprintf(str2[3], _T("      "));
    	_stprintf(str2[4], _T("按键:Esc : 强制退出游戏"));
    	_stprintf(str2[5], _T("          1 : 加速 "));
    	_stprintf(str2[6], _T("          0 : 减速"));
    	_stprintf(str2[7], _T("      空格: 暂停"));
    	for (int i = 0; i < 8; i++)
    	{
    		outtextxy(WIDE - FORM + 10, HIGH / 3 + i * 20 + 20, str2[i]);	//指定位置输出字符串
    	}
    
    
    }
    
    int main()
    {
    
    	initgraph(WIDE, HIGH);		//初始化窗口大小
    	setbkcolor(WHITE);			//背景颜色
    
    	Init_Snake();				//初始化蛇
    	Init_Food();				//初始化食物
    
    	while (true)//强退
    	{
    		if (food.flg == 0)
    		{
    			Init_Food();		//初始化食物
    		}
    		cleardevice();			//刷新窗口
    
    		BeginBatchDraw();		//这个函数用于开始批量绘图。执行后,任何绘图操作都将暂时不输出到屏幕上,防止闪屏
    		Form();					//打印表框
    
    		if (_kbhit())
    		{
    			KeyDown();			//玩家控制蛇移动
    		}
    		ShowSnake();			//画蛇
    		ShowFood();				//画食物
    		EndBatchDraw();			// 结束批量绘制,并执行未完成的绘制任务
    
    		EatFood();
    		MoveSnake();			//蛇移动
    
    		if (GameOver() == 1)		//游戏结束条件
    		{
    			break;
    		}
    		Sleep(speed);			//控制速度
    	}
    
    	getchar();
    	closegraph();
    	return 0;
    }
    /*--------------------------蛇的功能函数--------------------------*/
    //初始化蛇
    void Init_Snake()
    {
    	//初始化前三节蛇
    	snake.x[0] = SIZE * 2;
    	snake.y[0] = 0;
    
    	snake.x[1] = SIZE;
    	snake.y[1] = 0;
    
    	snake.x[2] = 0;
    	snake.y[2] = 0;
    
    	snake.len = 3;
    	snake.count = 0;
    	snake.direction = right;	//默认向右
    }
    //初始化食物
    void Init_Food()
    {
    	srand((unsigned int)time(NULL));//随机种子
    label:
    	int x = (WIDE - FORM) / SIZE;	//预留 FORM 像素显示信息
    	int y = HIGH / SIZE;
    	food.x = rand() % x * SIZE;	// *10 保证食物地址为整数,与蛇头比较
    	food.y = rand() % y * SIZE;
    	//检查食物是否在蛇身上
    	int i = 0;
    	while (i < snake.len)
    	{
    		if (food.x == snake.x[i] && food.y == snake.y[i])
    		{
    			goto label;
    		}
    		++i;
    	}
    	food.flg = 1;
    }
    //贴图画蛇
    void ShowSnake()
    {
    	for (int i = 0; i < snake.len; ++i)
    	{
    		setlinecolor(BLACK);	//设置画线颜色
    		setfillcolor(GREEN);	//设置填充颜色
    		fillrectangle(snake.x[i], snake.y[i], snake.x[i] + SIZE, snake.y[i] + SIZE);
    		/*  左上、右下坐标*/
    	}
    
    }
    //贴图画食物
    void ShowFood()
    {
    	setfillcolor(COLOUR);	//设置填充颜色--彩色食物
    	fillrectangle(food.x, food.y, food.x + SIZE, food.y + SIZE);
    }
    //蛇的移动
    void MoveSnake()
    {
    	//把蛇的后一节坐标移动到前一节的坐标位置
    	for (int i = snake.len - 1; i > 0; --i)
    	{
    		snake.x[i] = snake.x[i - 1];
    		snake.y[i] = snake.y[i - 1];
    	}
    	//单独移动蛇头,根据蛇的方向移动
    	switch (snake.direction)
    	{
    	case right:
    		snake.x[0] += SIZE;
    		break;
    	case left:
    		snake.x[0] -= SIZE;
    		break;
    	case up:
    		snake.y[0] -= SIZE;
    		break;
    	case down:
    		snake.y[0] += SIZE;
    		break;
    	default:
    		break;
    	}
    }
    
    
    
    /*getch函数从控制台读取单个字符而不回显,函数不能去读取CTRL+C,当读取一个
    	功能键或方向键,函数必须调用两次(这就说明可以用这个函数去监控功能键
    	和方向键),第一次调用返回0或0xe0,第二次返回实际的键代码*/
    	//控制
    void KeyDown()
    {
    	char tmp = _getch();		//接受_getch()的第一个返回值
    	switch (tmp)
    	{
    	case '1':		// 1 加速
    		if (speed > 20)
    		{
    			speed -= 20;
    		}
    		return;
    		break;
    	case '0':		// 0 减速
    		if (speed < 200)
    		{
    			speed += 20;
    		}
    		return;
    		break;
    	default:
    		break;
    	}
    	char key = _getch();		//接受键盘键入的值
    	switch (key)
    	{
    	case right:
    		if (snake.direction != left)	//不能相反方向移动
    			snake.direction = right;
    		break;
    	case left:
    		if (snake.direction != right)
    			snake.direction = left;
    		break;
    	case up:
    		if (snake.direction != down)
    			snake.direction = up;
    		break;
    	case down:
    		if (snake.direction != up)
    			snake.direction = down;
    		break;
    	case Esc:	//强退
    	{
    		TCHAR s[] = _T("即将退出游戏,是(Y)/否(N)");
    		setfillcolor(LIGHTCYAN);
    		fillrectangle(0, 0, WIDE - FORM, HIGH);
    		setbkmode(TRANSPARENT);			//文字透明方式
    		settextcolor(LIGHTBLUE);		//文字颜色
    		outtextxy(WIDE * 3 / 10, HIGH / 2, s);	//指定位置输出字符串
    		char ch = getchar();
    		if (ch == 'Y' || ch == 'y')	exit(0);
    
    	}
    	break;
    	case ' ':		//暂停
    		while (true)
    		{
    			if (_kbhit())
    			{
    				char ch = _getch();
    				if (_getch() == ' ')	break;
    			}
    
    		}
    
    		break;
    
    	default:
    		break;
    
    	}
    	fflush(stdin);
    }
    
    
    
    //吃食物
    void EatFood()
    {
    	if (food.x == snake.x[0] && food.y == snake.y[0])
    	{
    		++snake.len;
    		snake.count += 10;	//一个食物十分
    		food.flg = 0;
    	}
    
    }
    
    
    
    //死亡
    int GameOver()
    {
    	for (int i = 1; i < snake.len; i++)
    	{
    		//撞自己
    		if (snake.x[i] == snake.x[0] && snake.y[i] == snake.y[0])
    		{
    			TCHAR s[100];
    			_stprintf(s, _T("咬到自己了 GameOver!
    您的分数为%d分"), snake.count);
    
    			setfillcolor(WHITE);		//背景填充颜色
    			fillrectangle(0, 0, WIDE - FORM, HIGH);
    			setbkmode(TRANSPARENT);		//文字透明方式
    			settextcolor(LIGHTBLUE);	//文字颜色
    			outtextxy(WIDE * 2 / 10, HIGH / 2, s);	//指定位置输出字符串
    
    			return 1;
    		}
    		//撞墙
    		else if (snake.x[i]<0 || snake.x[0]>WIDE - FORM - SIZE ||		//横坐标出界
    			snake.y[i]<0 || snake.y[0]>HIGH - SIZE)		//纵坐标出界
    		{
    			TCHAR s[100];
    			_stprintf(s, _T("你撞墙了 GameOver!
    您的分数为%d分"), snake.count);
    
    			setfillcolor(WHITE);		//背景填充颜色
    			fillrectangle(0, 0, WIDE - FORM, HIGH);
    			setbkmode(TRANSPARENT);		//文字透明方式
    			settextcolor(LIGHTBLUE);	//文字颜色
    			outtextxy(WIDE * 2 / 10, HIGH / 2, s);	//指定位置输出字符串
    			return 1;
    		}
    		//通关
    		else if (snake.len == LEN)		//最长长度
    		{
    			TCHAR s[100];
    			_stprintf(s, _T("恭喜 通关 GameOver!
    您的分数为%d分"), snake.count);
    
    			setfillcolor(WHITE);		//背景填充颜色
    			fillrectangle(0, 0, WIDE - FORM, HIGH);
    			setbkmode(TRANSPARENT);		//文字透明方式
    			settextcolor(LIGHTBLUE);	//文字颜色
    			outtextxy(WIDE * 2 / 10, HIGH / 2, s);	//指定位置输出字符串
    			return 1;
    		}
    	}
    	return 0;
    }
    
    

    效果如下:

  • 相关阅读:
    vue 实现返回上一页不请求数据keep-alive
    vue+webpack 实现懒加载的三种方式
    深度解析使用CSS单位px、em、rem、vh、vw、vmin、vmax实现页面布局
    vue2.0中 怎么引用less?
    vue 自定义 提示框(Toast)组件
    Flex 布局教程实例
    Vue.js经典开源项目汇总
    Vue插件编写、用法详解(附demo)
    vue 项目 使用sass以及注意事项
    vue2.0+vue-video-player实现hls播放的案例
  • 原文地址:https://www.cnblogs.com/TaoR320/p/12680179.html
Copyright © 2020-2023  润新知