博客
关于我
贪吃蛇游戏 1.0
阅读量:287 次
发布时间:2019-03-01

本文共 6548 字,大约阅读时间需要 21 分钟。

编译环境:Visual Studio 2019

注:使用了Easyx 图形库。 

Easyx 图形库安装教程:

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

 

直接上代码:

#define _CRT_SECURE_NO_WARNINGS#define _CRT_NON_CONFORMING_SWPRINTFS#undef UNICODE#undef _UNICODE	#include 
#include
#include
#include
#include
#include
/*--------------------------------属 性---------------------------*/#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!\n您的分数为%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!\n您的分数为%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!\n您的分数为%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;}

效果如下:

 

转载地址:http://yzso.baihongyu.com/

你可能感兴趣的文章
MySQL SQL 优化指南:主键、ORDER BY、GROUP BY 和 UPDATE 优化详解
查看>>
MYSQL sql语句针对数据记录时间范围查询的效率对比
查看>>
mysql sum 没返回,如果没有找到任何值,我如何在MySQL中获得SUM函数以返回'0'?
查看>>
mysql Timestamp时间隔了8小时
查看>>
Mysql tinyint(1)与tinyint(4)的区别
查看>>
mysql union orderby 无效
查看>>
mysql v$session_Oracle 进程查看v$session
查看>>
mysql where中如何判断不为空
查看>>
MySQL Workbench 使用手册:从入门到精通
查看>>
mysql workbench6.3.5_MySQL Workbench
查看>>
MySQL Workbench安装教程以及菜单汉化
查看>>
MySQL Xtrabackup 安装、备份、恢复
查看>>
mysql [Err] 1436 - Thread stack overrun: 129464 bytes used of a 286720 byte stack, and 160000 bytes
查看>>
MySQL _ MySQL常用操作
查看>>
MySQL – 导出数据成csv
查看>>
MySQL —— 在CentOS9下安装MySQL
查看>>
MySQL —— 视图
查看>>
mysql 不区分大小写
查看>>
mysql 两列互转
查看>>
MySQL 中开启二进制日志(Binlog)
查看>>