贪吃蛇作为我童年第一个接触的手机游戏,在学c语言的时候就一直在想什么时候可以自己实现。经过一年的学习也是终于写出来了,在这期间我看了很多其它博客上的文章,我也很感谢那些愿意把自己的知识在网上和大家分享的人。虽然看了很多他人的想法,但最后我还是自己想出了解决问题的方法(数据保存)。在接下来我将详细介绍我的思路和实现方法。

前言:在本次的设计中由于数据较少我并未用到指针,自然也未用到那些经典的数据结构。个人认为并不是用的东西越多,越难懂一个程序越好,不同的情况下有不同的最好方案。我的老师说用指针访问数据效率比变量访问数据名更高。我在知乎上问,又有大佬说变量名访问数据比通过指针访问数据效率更高......

思路:

蛇的运动通过快速的打印和消除来实现,食物通过随机数和打印生成,比较蛇头的数据大小判断蛇是否超出边界。

蛇吃食物增加长度(控制蛇的长度),让食物不会刷到蛇身上,消除蛇的尾部,怎么判断蛇有没有吃到自己。这四个问题我采用了两个数组去保存蛇的运动轨迹,通过这两个数组中的数据获取尾部位置消除蛇尾,通过改变蛇的尾部的位置来控制蛇的长度,遍历蛇身数据与蛇头位置对比判断蛇有没有吃到自己,遍历蛇身数据与食物位置对比控制食物不会刷到蛇身上并吃到一个生成一个。

其余的数据保存,怎么控制主循环等问题参考之前写的ATM机。一个道理,没什么差别。在此就不过多赘述了。

实现:

我只会介绍核心问题,即那4个我标了红的问题的具体实现过程。你如果能解决这4个问题我相信其它剩余问题对你而言就是有手就行。在最后我也会把整个代码分享出来。

1.消除蛇尾

for(e=1;e;e++)                                    //用for语句构造死循环{SetPos(snakehead_x,snakehead_y);              //每次打印Sleep(100-speed);                             //控制蛇的运动速度printf("*");                       if(kbhit())                                 {move=getch();}switch(move)                                 //接受从键盘上输入的字符{case 'a':snakehead_x=snakehead_x-1; break;case 'd':snakehead_x=snakehead_x+1; break;case 'w':snakehead_y=snakehead_y-1;break;case 's':snakehead_y=snakehead_y+1; break;default:break;}snakedata_x[e]=snakehead_x;                  //将蛇每次打印的数据保存在两个数组中snakedata_y[e]=snakehead_y;if(e>=7)                                //蛇初始化形成后打印的同时开始消除{SetPos(snakedata_x[e-length],snakedata_y[e-length]);   printf(" ");snakedata_x[e-length]=0;snakedata_y[e-length]=0;SetPos(80,15);printf("你当前的分数为%d",socore[gamer]);}

每次循环都会打印*实现蛇的动态,kbhit()接受键盘信号会改变蛇头snake_head的位置用于下次打印,snake_data用于保存蛇头每次改变的数据用于之后的操作。当循环次数大于等于7次后开始消除蛇尾并开始记分。

2.控制蛇的长度

    if(snakehead_x==snakefood_x&&snakehead_y==snakefood_y)   //当蛇头的坐标与食物坐标相同{length++;                        //蛇吃到食物增加蛇的长度speed=speed+2;                   //蛇吃到食物增加蛇的速度   socore[gamer]=socore[gamer]+1;   //蛇吃到食物增加分数}if(e>=7)                                //蛇初始化形成后打印的同时开始消除{SetPos(snakedata_x[e-length],snakedata_y[e-length]); //通过length控制消去位置printf(" ");snakedata_x[e-length]=0;snakedata_y[e-length]=0;SetPos(80,15);printf("你当前的分数为%d",socore[gamer]);}

在这length的初始长度为6,也就是说当蛇头打印第7次使就会消去第一次打印的位置,这中间蛇尾的位置也就是6次打印之前。当蛇吃到食物length增加,蛇尾的位置改变变为7次打印之前,通过这种方法改变蛇的长度。

3,判断蛇有没有吃到自己

for(i=e-length;i<=e-1;i++)                    //遍历蛇身判断是否吃到自己{if(snakehead_x==snakedata_x[i]&&snakehead_y==snakedata_y[i]){judge=0;}}if(judge==0){break;}}

snakedata[e-length]为蛇尾的位置,snakehead[e]为蛇头的位置。这两者中间的便为蛇身的位置,将蛇身位置与蛇头位置比较就可以判断出是否吃到自己了。

4,控制食物不会刷到蛇身上并吃到一个食物生成一个

if(e==7)                                        //初始化完成生成一个食物{srand((int)time(NULL));snakefood_x = rand() % (70 -5 + 1) + 5;snakefood_y = rand() % (20 -5 + 1) + 5;for(i=e-length;i<=e-1;i++){if((snakefood_x==snakedata_x[i]&&snakefood_y==snakedata_y[i])){snakefood_x = rand() % (70 -5 + 1) + 5;snakefood_y = rand() % (20 -5 + 1) + 5;}SetPos(snakefood_x,snakefood_y);printf("@");}SetPos(10,12);printf(" ");}if(snakehead_x==snakefood_x&&snakehead_y==snakefood_y) //当蛇头与食物坐标相等{srand((int)time(NULL));snakefood_x = rand() % (70 -5 + 1) + 5;snakefood_y = rand() % (20 -5 + 1) + 5;for(i=e-length;i<=e-1;i++)                          //遍历蛇身{if((snakefood_x==snakedata_x[i]&&snakefood_y==snakedata_y[i])){snakefood_x = rand() % (70 -5 + 1) + 5;snakefood_y = rand() % (20 -5 + 1) + 5;}SetPos(snakefood_x,snakefood_y);printf("@");}length++;}

蛇完成初始化后自动生成一个食物,当吃到食物时生成新的食物,遍历的操作与3相同,判断时只要食物坐标与蛇身的其中一个完全相等则重新生成。

完整代码:

#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>void SetPos( int  x ,  int  y );  //光标移动控制
void gotopf(int x,int y);         //控制光标打印
void HideCursor();                //隐藏光标
void stop();                      //界面停止
void printf_frame();              //打印主体框架
void printf_menu();               //打印菜单界面
void playgame();                  //游戏主体
void history();                   //历史记录int socore[1000],gamer=1;//定义全局记分变量socore[1000],和控制用户顺序变量gamerint main()
{int i,control=1;              //定义循环控制变量i,控制主循环变量control;for(i=1;i<=999;i++){socore[i]=0;                  //对所有分数进行初始化;}while(control!=3){system("cls");printf_frame();printf_menu();       scanf("%d",&control);switch(control){case 1:playgame();break;case 2:history(); break;case 3:control=3; break;default:break;}}}void  SetPos( int  x ,  int  y )
{COORD  point = {  x ,  y  }; HANDLE  HOutput = GetStdHandle( STD_OUTPUT_HANDLE ); SetConsoleCursorPosition(HOutput, point);
}void gotopf(int x,int y)
{SetPos(x,y);printf("*");
}void HideCursor()
{CONSOLE_CURSOR_INFO cursor;    cursor.bVisible = FALSE;    cursor.dwSize = sizeof(cursor);    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);    SetConsoleCursorInfo(handle, &cursor);
}void stop(){char ch;ch=getch();
}void printf_frame()
{int i,j;system("color 75");for(i=0;i<=100;i++){gotopf(i,0);gotopf(i,25);}for(j=1;j<=25;j++){gotopf(0,j);gotopf(75,j);gotopf(100,j);}SetPos(80,5);printf("Welcome Play the");SetPos(83,7);printf("快乐憨憨蛇");SetPos(78,10);printf("操作控制:(英文输入下)");SetPos(80,11);printf("w:向上 s:向下");SetPos(80,12);printf("a:向左 d:向右");SetPos(80,20);printf("the game made by:");SetPos(85,21);printf("TLE");
}void printf_menu()
{SetPos(25,5);printf("1:开始游戏");SetPos(25,7);printf("2:查看历史记录");SetPos(25,9);printf("3:退出游戏");SetPos(25,15);printf("请选择你的操作:");
}void playgame()
{system("cls");                                  //清屏printf_frame();HideCursor();                                   //隐藏光标int snakehead_x=10,snakehead_y=12;              //定义:蛇头的位置,初始位置在(10,12)int snakedata_x[10000],snakedata_y[10000];      //定义:数据数组 保存蛇之前的数据int snakefood_x=0,snakefood_y=0;                //定义:食物int judge=1,length=6,speed=0,e,i;               //定义:判断游戏是否结束的变量judge,控制蛇长度的变量long,控制速度的变量speed,控制循环的变量e.i;char move='d';                                  //定义:控制蛇移动的变量for(e=1;e;e++){SetPos(snakehead_x,snakehead_y);Sleep(100-speed);printf("*");if(kbhit())             //捕获鼠标信号{move=getch();}switch(move){case 'a':snakehead_x=snakehead_x-1; break;case 'd':snakehead_x=snakehead_x+1; break;case 'w':snakehead_y=snakehead_y-1;break;case 's':snakehead_y=snakehead_y+1; break;default:break;}snakedata_x[e]=snakehead_x;snakedata_y[e]=snakehead_y;if(snakehead_x==snakefood_x&&snakehead_y==snakefood_y) //当蛇头与食物坐标相等{srand((int)time(NULL));snakefood_x = rand() % (70 -5 + 1) + 5;snakefood_y = rand() % (20 -5 + 1) + 5;for(i=e-length;i<=e-1;i++)                          //遍历蛇身{if((snakefood_x==snakedata_x[i]&&snakefood_y==snakedata_y[i])){snakefood_x = rand() % (70 -5 + 1) + 5;snakefood_y = rand() % (20 -5 + 1) + 5;}SetPos(snakefood_x,snakefood_y);printf("@");}length++;speed=speed+2;socore[gamer]=socore[gamer]+1;}if(e==7)                                        //初始化完成生成一个食物{srand((int)time(NULL));snakefood_x = rand() % (70 -5 + 1) + 5;snakefood_y = rand() % (20 -5 + 1) + 5;for(i=e-length;i<=e-1;i++){if((snakefood_x==snakedata_x[i]&&snakefood_y==snakedata_y[i])){snakefood_x = rand() % (70 -5 + 1) + 5;snakefood_y = rand() % (20 -5 + 1) + 5;}SetPos(snakefood_x,snakefood_y);printf("@");}SetPos(10,12);printf(" ");}if(e>=7)                                                   //开始消除{SetPos(snakedata_x[e-length],snakedata_y[e-length]);printf(" ");snakedata_x[e-length]=0;snakedata_y[e-length]=0;SetPos(80,15);printf("你当前的分数为%d",socore[gamer]);}if(snakehead_x>=75||snakehead_y>=25||snakehead_x<=0||snakehead_y<=0){judge=0;}for(i=e-length;i<=e-1;i++){if(snakehead_x==snakedata_x[i]&&snakehead_y==snakedata_y[i]){judge=0;}}if(judge==0){gamer++;SetPos(80,16);printf("按任意键返回菜单");stop();break;}}}void history()
{system("cls");int i=1;printf_frame();SetPos(10,5);for(i=1;socore[i];i++){printf("the snake %d  socore is %d\n",i,socore[i]);printf("          ");}printf("    ");printf("按任意键返回菜单");stop();
}

c语言:数据保存的方法实现简易贪吃蛇相关推荐

  1. JAVA简易贪吃蛇游戏实现

    JAVA简易贪吃蛇游戏实现 自学java不久,最近看了些GUI编程,就拿贪吃蛇练个手,很基础 刚学的 也是最简易的版本.纯粹就想通过博客记录来巩固自己的学习效果. 游戏介绍 玩家通过按键控制蛇身的移动 ...

  2. 基于C语言Ncurse库和链表的简单贪吃蛇小游戏

    参考:基于C语言Ncurse库和链表的简单贪吃蛇小游戏 作者:三速何时sub20 发布时间:2020-09-29 10:23:51 网址:https://blog.csdn.net/weixin_44 ...

  3. Luat Inside | 致敬经典,使用Air724UG制作简易贪吃蛇

    作者简介: 打盹的消防车--活跃于Luat社群的新生代全能开发者,东北小伙儿爽朗幽默.好学敏思,更是实力行动派.幼年曾手握火红炽铁而后全然无恙,堪称魔幻经历:如今热衷于各类嵌入式软硬件研究,快意物联江 ...

  4. python 贪吃蛇_python简易贪吃蛇

    python简易贪吃蛇 前言 开始 献上代码 from tkinter.messagebox import showinfo as msg from random import randint as ...

  5. JavaGUI 简易贪吃蛇代码详解+图片素材

    简易贪吃蛇 运行截图 图片素材 代码详解 package com.du.snake; import javax.swing.*; import java.awt.*; import java.awt. ...

  6. C语言实现简易贪吃蛇

    一.前言: 本人C语言并不好(大一新生),只是刚好学到链表时发现它很符合贪吃蛇的设定,所以突发奇想写了这个贪吃蛇.代码有点呆,发这篇文章仅仅是因为第一次写了一个算是有点可玩性的游戏很高兴想分享给大家而 ...

  7. python简易贪吃蛇小游戏任务书含代码

    目  录 第一章 绪论 1.1 开发的背景 1.2 开发的目的 1.3 开发的意义 1.4 开发工具简介 第二章 需求分析 (1) 利用方向键来改变蛇的运行方向. (2) 在随机的地方产生食物. (3 ...

  8. 简易贪吃蛇小游戏java版_用GUI实现java版贪吃蛇小游戏

    本文实例为大家分享了java版贪吃蛇小游戏的具体代码,供大家参考,具体内容如下 项目结构 新建一个JFrame窗口,作为程序入口 public class GameStart{ public stat ...

  9. 【使用java swing制作简易贪吃蛇游戏】软件实习项目二

    一.项目准备 需求分析: 实现贪吃蛇游戏基本功能,屏幕上随机出现一个"食物",称为豆子,上下左右控制"蛇"的移动,吃到"豆子"以后" ...

最新文章

  1. matplotlib画图
  2. LeetCode-链表-面试题 02.07. 链表相交
  3. 快速排除故障命令除了ping还有tracert
  4. csrf-token
  5. vi/vim常用命令总结参考图
  6. HDFS概述和设计目标
  7. MySQL5.6优化了Order by排序limit
  8. 记录拷贝:centos安装jdk
  9. 创建者模式 --- 单例模式
  10. 1月 23 surface pro 3. windows ubuntu 双系统安装
  11. NI CompactRIO嵌入式系统开发流程总结
  12. demo VelocityTracker
  13. PAT a1125
  14. Python学习:使用pycharm运行py文件报错系统找不到指定的路径
  15. 方舟非专用服务器稳定吗,方舟非专用服务器
  16. 计算机与神经网络,通过计算机与神经网络分析太阳系的历史
  17. Ubuntu 搭建opengrok 流程
  18. Xshell快速命令集解放生产力
  19. 「Photoshop2021入门教程」新功能——快速操作
  20. 电脑开机后,显示屏无信号怎么处理?

热门文章

  1. 解决Unknown column ‘xxx‘ in ‘where clause‘问题!!(泪的教训!!)
  2. [数学公式]等差数列求和
  3. 阿里云服务器绑定域名,阿里云esc绑定域名,阿里云域名备案相关完整情况
  4. 618闭着眼睛买都不会错的三款好物!当贝投影最推荐?!
  5. 【AD小知识】PCB之自动布线及快速布局技巧
  6. 华大HC32F460的BOOT和IAP说明
  7. 介绍MySQL数据库与应用场景
  8. python符号计算 漂亮地打印出来_让Python输出更漂亮:PrettyPrinter
  9. 跟涛哥一起学嵌入式 27:一个小故事,让你明白进程、线程和协程的区别
  10. ARM中流水线分析——以三级流水线进行分析