彩色贪吃蛇

news/2024/11/20 1:47:48/

基于EasyX库的C语言小游戏

文章目录

  • 基于EasyX库的C语言小游戏
  • 前言
  • 游戏实录
  • 需求与技术难点分析
    • 地图与蛇的生成
    • 蛇的移动
    • 游戏失败
  • 源码


前言


上一篇文章我们已经做过了见缝插针的小游戏,这次再利用EasyX库做一个贪吃蛇的游戏。

游戏实录

在这里插入图片描述

需求与技术难点分析

地图与蛇的生成

利用二维数组,这时我们就可以想到,二维数组的值的多态性,值的多态决定了地图里不止一种的表示,我们可以想到用0表示空地,>0的为蛇身。

同时,一个像素点太小了,我们可以用宏定义的方法手动设置像素块

#define BLOCK_SIZE 20 // 每个小格子的长宽大小 
#define HEIGHT 30 // 高度上一共30个小格子
#define WIDTH 40 //  宽度上一共40个小格子 

蛇的移动

我们从键盘获取蛇的移动方向,同时初始方向为右,为了防止出现因为前一步向上后一步向下而导致的自己咬自己的bug,我们除了定义moveDirection的同时,还定义moveDirection_old变量,用于避免这种现象的产生。

同时因为蛇本身会按照初始方向移动,键盘输入是在某一个时间点进行,因此我们将这两个事件封装为两个更新函数,一个与输入无关,另一个与输入有关

蛇的移动本质上是数组的更新,我们在第一步设置的蛇身的值>0,由此我们可以发挥一下,将蛇头的值设置为1,将蛇身的值设置为蛇的长度,因此,数组中值最大的元素下标就对应着蛇尾,值最小的元素下标就对应着蛇头。而蛇更新的时候本质上移动的只有头和尾(如果吃到了食物的话,就只用移动头)。

游戏失败

游戏失败分为两种情况:

  • 蛇头碰壁
    这种情况我们只需要将蛇头坐标与边界值相比较就行
  • 咬到了蛇身
    我们需要将下一步对应的蛇头坐标对应数组中的值进行检查,判断是否大于零,大于0则咬到了自身

源码

#include <graphics.h>  
#include <conio.h>
#include <stdio.h>
#define BLOCK_SIZE 20 // 每个小格子的长宽大小 
#define HEIGHT 30 // 高度上一共30个小格子
#define WIDTH 40 //  宽度上一共40个小格子 // 全局变量定义
int Blocks[HEIGHT][WIDTH] = { 0 }; //  二维数组,用于记录所有的游戏数据
char moveDirection_old, moveDirection;  //  小蛇移动方向
int food_i, food_j; //  食物的位置
int isFailure = 0; //  是否游戏失败void moveSnake() //  移动小蛇及相关处理函数
{int i, j;for (i = 0; i < HEIGHT; i++) // 对行遍历 for (j = 0; j < WIDTH; j++) // 对列遍历if (Blocks[i][j] > 0) // 大于0的为小蛇元素 Blocks[i][j]++; //  让其+1int oldTail_i, oldTail_j, oldHead_i, oldHead_j; // 定义变量,存储旧蛇尾、旧蛇头坐标  int max = 0; // 用于记录最大值 for (i = 0; i < HEIGHT; i++) //  对行列遍历{for (j = 0; j < WIDTH; j++){if (max < Blocks[i][j]) //  如果当前元素值比max大{max = Blocks[i][j]; // 更新max的值oldTail_i = i; //  记录最大值的坐标,就是旧蛇尾的位置oldTail_j = j; //  }if (Blocks[i][j] == 2) // 找到数值为2 {oldHead_i = i; //  数值为2恰好是旧蛇头的位置oldHead_j = j; //  }}}int newHead_i = oldHead_i; //  设定变量存储新蛇头的位置int newHead_j = oldHead_j;//  根据用户按键,设定新蛇头的位置if (moveDirection == 'w') // 向上移动newHead_i = oldHead_i - 1;else if (moveDirection == 's') // 向下移动newHead_i = oldHead_i + 1;else if (moveDirection == 'a') // 向左移动newHead_j = oldHead_j - 1;else if (moveDirection == 'd') // 向右移动newHead_j = oldHead_j + 1;//  如果蛇头超出边界,或者蛇头碰到蛇身,游戏失败if (newHead_i >= HEIGHT || newHead_i < 0 || newHead_j >= WIDTH || newHead_j < 0|| Blocks[newHead_i][newHead_j]>0){isFailure = 1; //  游戏失败return; // 函数返回}Blocks[newHead_i][newHead_j] = 1;  // 新蛇头位置数值为1	if (newHead_i == food_i && newHead_j == food_j) //  如果新蛇头正好碰到食物{food_i = rand() % (HEIGHT) ; //  食物重新随机位置food_j = rand() % (WIDTH ); //  // 不对旧蛇尾处理,相当于蛇的长度+1}else // 新蛇头没有碰到食物Blocks[oldTail_i][oldTail_j] = 0; // 旧蛇尾变成空白,不吃食物时保持蛇的长度不变
}void startup()  //  初始化函数
{int i;Blocks[HEIGHT / 2][WIDTH / 2] = 1; // 画面中间画蛇头,数字为1for (i = 1; i <= 4; i++) //  向左依次4个蛇身,数值依次为2,3,4,5Blocks[HEIGHT / 2][WIDTH / 2 - i] = i + 1;moveDirection = moveDirection_old= 'd';	 //  初始向右移动food_i = rand() % (HEIGHT) ; //  初始化随机食物位置food_j = rand() % (WIDTH ); //  initgraph(WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE); //  新开画面setlinecolor(RGB(200, 200, 200)); // 设置线条颜色BeginBatchDraw(); // 开始批量绘制
}void show()  // 绘制函数
{cleardevice(); // 清屏int i, j;for (i = 0; i < HEIGHT; i++) //  对二维数组所有元素遍历{for (j = 0; j < WIDTH; j++){if (Blocks[i][j] > 0) // 元素大于0表示是蛇,这里让蛇的身体颜色色调渐变setfillcolor(HSVtoRGB(Blocks[i][j] * 10, 0.9, 1));elsesetfillcolor(RGB(150, 150, 150)); // 元素为0表示为空,颜色为灰色// 在对应位置处,以对应颜色绘制小方格fillrectangle(j * BLOCK_SIZE, i * BLOCK_SIZE,(j + 1) * BLOCK_SIZE, (i + 1) * BLOCK_SIZE);}}setfillcolor(RGB(0, 255, 0)); //  食物为绿色//  绘制食物小方块fillrectangle(food_j * BLOCK_SIZE, food_i * BLOCK_SIZE,(food_j + 1) * BLOCK_SIZE, (food_i + 1) * BLOCK_SIZE);if (isFailure) //  如果游戏失败{setbkmode(TRANSPARENT); // 文字字体透明    settextcolor(RGB(255, 0, 0));// 设定文字颜色settextstyle(80, 0, _T("宋体")); //  设定文字大小、样式outtextxy(240, 220, _T("游戏失败")); //  输出文字内容}FlushBatchDraw(); // 批量绘制
}void updateWithoutInput() // 与输入无关的更新函数
{if (isFailure) //  如果游戏失败,函数返回return;static int waitIndex = 1; // 静态局部变量,初始化时为1waitIndex++; // 每一帧+1if (waitIndex == 10) // 如果等于10才执行,这样小蛇每隔10帧移动一次{moveSnake(); //  调用小蛇移动函数waitIndex = 1; // 再变成1}
}void updateWithInput()  // 和输入有关的更新函数
{if (_kbhit() && isFailure == 0)  //  如果有按键输入,并且不失败{char input = _getch(); //  获得按键输入switch (input) {     //注意防止自咬现象(即前后两次运动方向相反)case 'a':moveDirection = input;  if (moveDirection_old != 'd') {moveSnake();moveDirection_old = moveDirection;}else moveDirection = moveDirection_old;break;case 'w':moveDirection = input;  if (moveDirection_old != 's') {moveSnake();		moveDirection_old = moveDirection;}else moveDirection = moveDirection_old;break;case 's':moveDirection = input;  if (moveDirection_old != 'w') {moveSnake();moveDirection_old = moveDirection;}else moveDirection = moveDirection_old;break;case 'd':moveDirection = input;  if (moveDirection_old != 'a') {moveSnake();moveDirection_old = moveDirection;}else moveDirection = moveDirection_old;break;}}
}int main() //  主函数
{startup();  // 初始化函数,仅执行一次	while (1)   // 一直循环{show();  // 进行绘制updateWithoutInput(); // 和输入无关的更新 updateWithInput();    // 和输入有关的更新}return 0;
}

http://www.ppmy.cn/news/471072.html

相关文章

蛇岛狂蟒出没

在一夜月黑风高的杀人夜 有一对小情侣正在湖边露营 就在俩人在帐篷里浓情蜜意时 突然发现有东西在拉帐篷的拉链 在这鸟不拉屎的地方怎么会有别人 男人拔出刀 出去查看情况 但是环顾四周 什么都没有 这时 不远处传来一声猴叫 男人觉得是猴子在恶作剧 就没太放在心上 随…

基于OpenVINOTM2022.2和蝰蛇峡谷优化并部署YOLOv5模型

文章作者 英特尔物联网行业创新大使 杨雪锋 博士 中国矿业大学机电工程学院副教授&#xff1b; 发表学术论文30余篇&#xff0c;获国家专利授权20多件&#xff08;其中发明专利8件&#xff09; 目录 1.1 OpenVINOTM 2022.2简介 1.2 YOLOv5简介 1.3 蝰蛇峡谷简介 1.4 准…

机器蛇?蛇 ?

导读 近日&#xff0c;日本东京电子通信大学研制出一种蛇形铰接式移动机器人&#xff0c;并找出了控制它进行三维转向、爬楼梯和操纵物体的方法&#xff0c;极大地提高了其机动性和灵巧性&#xff0c;可应用于检查狭窄空间和灾区救援等工作。 作者&#xff1a;pumpkin酱 貌丑心…

Python:蟒蛇大战C语言(一)

并非特意比较&#xff0c;也没有贵贱之嫌&#xff0c;对比着学和互相借鉴总之是有好处的吧我觉得 目录 1.命名空间 2.结构体 3.模板与泛型 4. 为类型取别名&#xff08;创建同义词&#xff09;&#xff1a;typedef 5.只读变量 6.lambda表达式的应用 7.宏定义 8…

mysql 将date字段默认值设置为CURRENT_DATE

我们是否可以在mysql中&#xff0c;将Date字段的默认值设置为CURRENT_DATE&#xff08;当前日期&#xff09;&#xff1f; 答案是8.0之前不可以&#xff0c;8.0.13之后可以。 比如在5.7版本中使用如下sql创建表&#xff0c;将会提示语法错误: CREATE TABLE t_order (id bigi…

运动蓝牙耳机什么牌子好,骑行运动耳机

你有没有发现热爱运动的人经常喜欢音乐&#xff0c;因为动态的旋律和优美的歌声会让运动更有趣!现在生活节奏很快&#xff0c;似乎人们所有人都很忙&#xff0c;忙着这个&#xff0c;最好让一首音乐放松紧张的精神&#xff0c;放松心情&#xff0c;快乐的运动&#xff0c;健康的…

运动蓝牙耳机哪个品牌比较好?佩戴牢固的运动蓝牙耳机推荐

对于当前的蓝牙耳机市场来说&#xff0c;蓝牙耳机已经到了真正遍地开花全面普及的地步了&#xff0c;可以说从几十元到几百元价位的耳机可以说已经到了琳琅满目、眼花缭乱的地步。因此大家在挑选蓝牙耳机上&#xff0c;难免不知道下手。接下来的四款耳机每一款都有着自己的独特…

健身运动用什么蓝牙耳机比较好?盘点几款专业运动蓝牙耳机

目前真无线蓝牙耳机十分火热&#xff0c;成为许多人出行、娱乐的必要工具&#xff0c;但同时许多厂商也看到了这一块的市场&#xff0c;大小品牌、各种形态的耳机产品应有尽有&#xff0c;网上随便一搜索&#xff0c;就会出现几十款产品。那面对这种情况&#xff0c;怎样才能挑…