文章目录

  • 0.参考资料
  • 1 技术难点
    • 1.1 关于光标的移动
    • 1.2 关于蛇的移动
      • 1.2.1 从键盘上读取输入
      • 1.2.2 蛇的移动
    • 1.3 食物的生成
  • 2.完整代码

0.参考资料

借鉴了这位大佬的博客及代码,在其基础上进行了修改,特此鸣谢。
https://blog.csdn.net/qq_45359344/article/details/103254166

1 技术难点

1.1 关于光标的移动

这一步需要手写一个gotoxy的函数,其中涉及到的一些知识点见下链接:
关于COORD
https://zhidao.baidu.com/question/243419995.html
关于handle
https://blog.csdn.net/qq_31967569/article/details/102726894
这里需要注意的是COORD里的x,y是指的横纵坐标,而我们(或者只有我)平常在使用二维数组时习惯按照线性代数中矩阵的表达形式,即第一维放纵坐标,第二维放横坐标。所以这里的x,y要反着赋值(这个bug d了好久qwq)

void gotoxy(int x,int y)
{COORD pos;//COORD是一种自带结构体,表示一个字符在控制台屏幕上的坐标HANDLE han=GetStdHandle(STD_OUTPUT_HANDLE); //从标准输出设备里取出一个句柄pos.X=y,pos.Y=x;SetConsoleCursorPosition(han,pos);//定位光标的函数
}

1.2 关于蛇的移动

主要有两种实现方式,一种使用指针加链表,一种使用数组。笔者选择的是数组的方式,这种方法代码量略大,且较为丑陋,但是易于理解。每次操作后只需要清空蛇尾(如果吃到食物就不用),打印蛇头,以及将蛇身的坐标顺次移动。

1.2.1 从键盘上读取输入

用kbhit()和getch()函数

1.2.2 蛇的移动

需要注意的是如果此时蛇是向上移动的话,点击向下移动是无效的。所以需要将蛇的运动状态记录下来。而在写switch,case时注意要写default,即不进行操作时,保持原运动状态。

1.3 食物的生成

一个简单的srand制造随机数就可以实现。需要注意的是,需要判断食物是否和当前蛇的位置重合,方法是暴力(枚举蛇的每一块)。可以写成一个函数来实现。

2.完整代码

#include<cstdio>
#include<iostream>
#include<ctime>
#include<stdlib.h>
#include<windows.h>
#include <conio.h>
using namespace std;
#define frame_width 50
#define frame_height 25typedef struct{int x,y;
} Food;
typedef struct{int x[100],y[100],len,state;
} Snake;void gotoxy(int x,int y);  //最重要的一个函数,控制光标的位置
void print_map();
void get_newfood();//生成新食物
bool check_foodinsnake();//检查新食物有没有在蛇身上
void move_snake();
void check_foodeating();
bool check_snakealive();//需要用到的全局变量
int score;
Snake snake;
Food food;
bool check_eaten;int main()
{system("color 0B");do{system("cls");print_map();score=0,check_eaten=0;//贪吃蛇的每回合运行控制while(1){check_foodeating();//system("pause");move_snake();Sleep(max(50,300-score));//控制速度(与长度呈反比)if(!check_snakealive())break;}printf("Game Over!\n");printf("1:Restart\t2:exit\n");char com2;cin>>com2;if(com2=='2')break;}while(1);
}void gotoxy(int x,int y)
{COORD pos;//COORD是一种自带结构体,表示一个字符在控制台屏幕上的坐标HANDLE han=GetStdHandle(STD_OUTPUT_HANDLE); //从标准输出设备里取出一个句柄pos.X=y,pos.Y=x;SetConsoleCursorPosition(han,pos);//定位光标的函数
}void print_map()
{//打印墙壁for(int i=0;i<frame_height;i++){gotoxy(i,0);printf("#");gotoxy(i,frame_width-1);//因为这个标记是长度,从零开始所以最后要减1printf("#");}for(int i=0;i<frame_width;i++){gotoxy(0,i);printf("#");gotoxy(frame_height-1,i);printf("#");}//蛇身初始化snake.len=3;snake.state='w';snake.x[1]=frame_height/2;snake.y[1]=frame_width/2;gotoxy(snake.x[1],snake.y[1]);printf("@");for(int i=2;i<=snake.len;i++){snake.x[i]=snake.x[i-1]+1;snake.y[i]=snake.y[i-1];gotoxy(snake.x[i],snake.y[i]);printf("@");}//打印初始食物get_newfood();//打印右边状态栏gotoxy(2,frame_width+3);printf("WELCOME TO THE GAME OF RETRO SNAKE");gotoxy(4,frame_width+3);printf("UP:   w");gotoxy(6,frame_width+3);printf("DOWN: s");gotoxy(8,frame_width+3);printf("LEFT: a");gotoxy(10,frame_width+3);printf("RIGHT:d");gotoxy(12,frame_width+3);printf("Your score:%d",score);gotoxy(28,frame_width+3);printf("Made by jokersio");
}bool check_foodinsnake()
{for(int i=1;i<=snake.len;i++)if(snake.x[i]==food.x&&snake.y[i]==food.y)return 1;return 0;
}void get_newfood()
{do{srand(time(0));food.x=rand()%(frame_height-2)+1;food.y=rand()%(frame_width-2)+1;}while(check_foodinsnake());gotoxy(food.x,food.y);cout<<"$";
}void move_snake()
{char com;while(kbhit())//键盘有输入com=getch();//从控制台读取一个字符,但不显示在屏幕上//没有吃到去除蛇尾if(!check_eaten){gotoxy(snake.x[snake.len],snake.y[snake.len]);printf(" ");}//将除蛇头外的其他部分向前移动for(int i=snake.len;i>1;i--)snake.x[i]=snake.x[i-1],snake.y[i]=snake.y[i-1];//移动蛇头switch(com){case 'w':{if(snake.state=='s') //如果命令与当前方向相反不起作用snake.x[1]++;elsesnake.x[1]--,snake.state='w';break;}case 's':{if(snake.state=='w')snake.x[1]--;elsesnake.x[1]++,snake.state='s';break;}case 'a':{if(snake.state=='d')snake.y[1]++;elsesnake.y[1]--,snake.state='a';break;}case 'd':{if(snake.state=='a')snake.y[1]--;elsesnake.y[1]++,snake.state='d';break;}default: //按其余键保持状态前进{if(snake.state=='s')snake.x[1]++;else if(snake.state=='w')snake.x[1]--;else if(snake.state=='d')snake.y[1]++;else if(snake.state=='a')snake.y[1]--;break;}}gotoxy(snake.x[1],snake.y[1]);printf("@");check_eaten=0;gotoxy(frame_height,0);
}void check_foodeating()
{if(snake.x[1]==food.x&&snake.y[1]==food.y){score+=10;check_eaten=1;gotoxy(12,frame_width+3);printf("Your score:%d",score);snake.len++;get_newfood();}
}bool check_snakealive()
{//检查有没有撞到墙if(snake.x[1]==0||snake.x[1]==frame_height-1||snake.y[1]==0||snake.y[1]==frame_width-1)//撞墙return 0;//检查有没有吃到自己for(int i=2;i<=snake.len;i++)if(snake.x[i]==snake.x[1]&&snake.y[i]==snake.y[1])return 0;return 1;
}

c++ 实现贪吃蛇(含技术难点解析和完整代码)相关推荐

  1. 人脸表情识别系统的设计与实现(含UI界面,有完整代码)

    人脸表情识别系统的设计与实现(含UI界面,有完整代码) 这是之前本科做的毕设,当时使用的是keras搭建了一个简单的神经网络作为入门实现了在fer2013人脸表情数据集上的表情分类,并移植到了树莓派上 ...

  2. 子弹短信背后,亿级架构IM平台的技术难点解析

    自从 8 月 20 号子弹短信在锤子发布会露面之后,关于它的讨论不绝于耳,7 天融资 1.5 亿的传闻更是将它推到了风口浪尖.同时很多技术人开始分析它的代码,挖出了它的 IM 系统其实不是自研,而是使 ...

  3. Java实现贪吃蛇大作战小游戏(完整教程+源码)额外实现积分和变速功能

    大家好,我是黄小黄同学!今天给大家带来的是小项目是 基于Java+Swing+IO流实现 的贪吃蛇大作战小游戏.实现了界面可视化.基本的吃食物功能.死亡功能.移动功能.积分功能,并额外实现了主动加速和 ...

  4. c++贪吃蛇游戏-详细解释-非单纯贴代码

    先说明下:本文来源:https://blog.csdn.net/silence1772/article/details/55005008 写在前面,这个项目,希望大家先下载下来,玩一玩.然后2天左右把 ...

  5. QQ阅读器技术框架解析之一《代码预览和分析》

    据说,腾讯的产品的三字名言是:抄.糙.超.即,先抄袭.在模仿.最终实现超越.互联网软件天下一大抄,彼此抄袭是常事,关键使我们如何超越他人,实现自我.下面我们采用最新的QQ阅读器反编译代码,并恢复源代码 ...

  6. QQ阅读器技术框架解析之三《代码预览和分析》

    本文主要介绍书架的架构 BookStandActivity extends ReaderBaseActivity implements DialogInterface.OnCancelListener ...

  7. 使用Python和OCR进行文档解析的完整代码演示(附代码)

    来源:DeepHub IMBA 本文约2300字,建议阅读5分钟本文中将使用Python演示如何解析文档(如pdf)并提取文本,图形,表格等信息. 文档解析涉及检查文档中的数据并提取有用的信息.它可以 ...

  8. OpenCV hdr成像技术的实例(附完整代码)

    OpenCV hdr成像技术的实例 OpenCV hdr成像技术的实例 OpenCV hdr成像技术的实例 #include "opencv2/photo.hpp" #includ ...

  9. 扫雷【含递归和标记的完整代码及详细讲解】

    目录 一.游戏思路 二.游戏部分设计 1.棋盘的初始化 2.棋盘的打印 3.雷场的布置 4.用户排雷 5.递归函数部分 三.完整代码 四.结语 扫雷,扫雷是一款大众类的益智小游戏,于1992年发行.游 ...

最新文章

  1. libIlmImf-2_2.so.22 :cannot open shared object file :No such file or direct
  2. 张亚勤世界互联网大会谈AI:将变革传统行业,催生新业态
  3. ansible 详解
  4. MySQL数据类型:UNSIGNED注意事项
  5. java putnextentry_Java对zip格式压缩和解压缩
  6. 存储限制_明年6月份开始,谷歌相册将终止免费无限存储服务
  7. asp.net ViewState详解
  8. 论文阅读笔记(一)【Journal of Machine Learning Research】Natural Language Processing (Almost) from Scratch(未完)
  9. 哇塞!野生海鲜竟然从渔港直送到你家!喜欢吃海鲜的有福了!
  10. mysql查询姓王的信息代码_MySQL查询语句练习题
  11. 漫步数学分析番外五(上)
  12. mysql 排序后在查询
  13. 极具设计感的专辑分类设计,给你带来不一样的灵感
  14. 为何System Idle Process 进程占用了大量有CPU资源
  15. 路由汇总之二ospf路由汇总
  16. NCH MixPad Masters for Mac - 录音和混音软件
  17. Java 连接 数据库 (idea2022 + MySQL 演示,Oracle 通用)
  18. 16行Python代码 批量采集 短视频音乐素材❤
  19. 卫星系统算法课程设计 - 第一部分:城市时间窗口、间隙等
  20. 60后文风 or 90后文风,哪一款是你的真爱?| 文末有彩蛋

热门文章

  1. SuperMap iDesktop 操作入门(一)创建文件型工作空间
  2. dhcp服务器自动分配地址思科,cisco dhcp服务器设置方法
  3. 预测模型之灰色系统预测
  4. Unity中使用Post Processing 开自发光效果
  5. 实训报告万能模板计算机专业,计算机专业实习报告模板
  6. Android利用Socket与硬件通信之智能家居APP
  7. 西门子PCS7系统NTP网络时钟同步(NTP时钟发生器)介绍
  8. 爬虫出现UnicodeEncodeError: ‘latin-1‘ codec can‘t encode character *** in position 8328: Body***问题
  9. matlab下标可变,Matlab中下标,斜体,及希腊字母的使用方法
  10. 【学习笔记之Linux】工具之gcc/g++