伪代码:

地图为二位数组
int main(){
死循环
刷新地图
生成水果
获取键盘
移动头部
判定死亡、吃到水果
if(没有吃到水果)
{移动尾部
}
等待指定秒数
清屏
}

首先,我们因该可以把大框架写出来了。地图是一个二维数组,这里叫做snmap。

我们需要一个函数来创建地图,地图由边缘(killword)和空白(mapword)组成

killword是边缘,snword是蛇的字母,mapword是空白处的字母
mapx,mapy分别对应地图尺寸
int map_cz()//初始化地图数据
{for(int i = 1;i < mapy;i++)//填充地图{for(int j = 0;j < mapx;j++){snmap[i][j] = mapword;//}}for(int j = 0;j < mapx;j++) snmap[0][j] = killword;//这四行是设置地图边缘for(int j = 0;j < mapx;j++) snmap[mapy-1][j] = killword;for(int i = 0;i < mapy;i++) snmap[i][0] = killword;for(int i = 0;i < mapy;i++) snmap[i][mapx-1] = killword;}

然后需要一个函数来重构地图,也就是在每次循环之后重新输出一遍

killword是边缘,snword是蛇的字母,mapword是空白处的字母
mapx,mapy分别对应地图尺寸
int map_cz()//初始化地图数据
{for(int i = 1;i < mapy;i++)//填充地图{for(int j = 0;j < mapx;j++){snmap[i][j] = mapword;//}}for(int j = 0;j < mapx;j++) snmap[0][j] = killword;//这四行是设置地图边缘for(int j = 0;j < mapx;j++) snmap[mapy-1][j] = killword;for(int i = 0;i < mapy;i++) snmap[i][0] = killword;for(int i = 0;i < mapy;i++) snmap[i][mapx-1] = killword;}

我们需要绘制一个初始蛇,这里需要用到一些变量:头的位置(headx,heady),尾部的位置(tallx,tally)和蛇的长度(snlong)

for(int i = 0;i < snlong;i++)//绘制初始蛇{snmap[head_y][head_x+i] = snword;snnum[head_y][head_x+i] = i+1;}

现在地图有了,贪吃蛇有了,接下来就要让他动起来。我们需要获取键盘数据来控制他的头部移动,把他的头部坐标放在下一个位置,然后把头部坐标的那个点换成蛇的字母(snword)

int jd = 65,jdnum = 0;
if (jd = _kbhit()){jd = _getch();}//更新头部方向if(jd == 97) jdnum = 0;if(jd == 119) jdnum = 1;if(jd == 100) jdnum = 2;if(jd == 115) jdnum = 3;if(jd == 113) zt();//暂停//更新头部if(jdnum == 0) head_x--;if(jdnum == 1) head_y--;if(jdnum == 2) head_x++;if(jdnum == 3) head_y++;//中间还要加上死亡判定再更新snmap[head_y][head_x] = snword;

头的部分会增加,尾巴也需要消失,蛇才能动起来。所以我们就需要更新尾部。更新尾部要复杂的多,第一步要先把再尾部位置(tellx,telly)的字母换成空的(mapword),第二步找到新的尾部位置并更新这两个变量(tellx,telly)。第一步好说,问题就出在第二步上,新的位置难以确定。所以我们就需要一个新的二维数组来存放蛇走过的顺序(nummap)。这个数组和snmap是一一对应恶的。每次头部跟新时都在nummap上留下一个数字,这个数字是递增的。

这个是snmap
蛇头
蛇尾
这个是nummap
9 8 7 6 5
4
1 2 3

这样我们在更新尾部的时候就是需要找出除当前尾部之外最小的那个数的坐标作为新的尾部就可以了,因为这两个数组是同步的,坐标都相通。

int main()
int num = 0;snnum[head_y][head_x] = num;//这两行夹在哪里都行
num++;if(snlong == snlong_old)//长度没有增加,更新尾部{snmap[tall_y][tall_x] = mapword;snnum[tall_y][tall_x] = 0;int min = 2137384637,minx,miny;for(int y = tall_y-1;y < tall_y+2;y++)//寻找新的尾部{for(int x = tall_x-1;x < tall_x+2;x++){if(snnum[y][x] < min&&snnum[y][x] != 0){min = snnum[y][x];minx = x,miny = y;}}}tall_y = miny;tall_x = minx;}

最后再用时间种子随机数生成水果

这是更新苹果的

//更新苹果xy坐标if(appleflag == 0)//如果苹果不存在,更新苹果{if(snmap[apy][apx] != snword){snmap[apy][apx] = apple;Sleep(10);if(snmap[apy][apx] == apple)appleflag = 1;//设置苹果状态为存在}}

这是用随机数生成苹果xy坐标的

int apple_xy()//随机生成苹果位置
{srand((int)time(0));apx = rand()%(mapx-2);apy2 = apx;apy = (apy*apy2)%(mapy-2);apx2 = apy;//cout<<apx<<" "<<apy;if(apx*apy==0){apx++;apy++;}}

再加上死亡判定和吃水果的判定

if(snmap[head_y][head_x] == apple)//水果判定{appleflag = 0;snlong++;}//死亡判定if(snmap[head_y][head_x] == snword||snmap[head_y][head_x] == killword){Sleep(1000);return 0;}

这个小游戏就初步完成了,注意!是初步!

为什么是初步呢?因为你发现完成后的这个代码会闪瞎你的眼。(下面)

#include<bits/stdc++.h>
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include <conio.h>
#include "stdio.h"
#include "stdlib.h"
using namespace std;//初始数据部分
const int mapy = 20,mapx = 40;//地图尺寸
int snlong =3,sd = 200;//初始长度
const char snword = 'O',mapword = ' ',apple = '@',killword = '#';//地图元素
//变量部分
int head_y = 5,head_x = 10,tall_y = head_y,tall_x = head_x+snlong;//头尾坐标
int snnum[mapy][mapx],num = 4;//snmap地图数组
char snmap[mapy+1][mapx];
int apx = 6,apy = 3,appleflag = 0;//关于苹果的变量
int apx2 = 4,apy2 = 9;
int showflag = 0;int map_cz()//初始化地图数据
{for(int i = 1;i < mapy;i++)//填充地图{for(int j = 0;j < mapx;j++){snmap[i][j] = mapword;//}}for(int j = 0;j < mapx;j++) snmap[0][j] = killword;//这四行是设置地图边缘for(int j = 0;j < mapx;j++) snmap[mapy-1][j] = killword;for(int i = 0;i < mapy;i++) snmap[i][0] = killword;for(int i = 0;i < mapy;i++) snmap[i][mapx-1] = killword;}
int map_output()//更新地图显示
{for(int i = 0;i < mapy;i++){for(int j = 0;j < mapx;j++){printf( "%c",snmap[i][j]);}printf("\n");}
Sleep(sd);
}
int num_output()//调试nummap数组
{for(int i = 0;i < mapy;i++){for(int j = 0;j < mapx;j++){printf( "%d",snnum[i][j]);}printf("\n");}
}
int apple_xy()//随机生成苹果位置
{srand((int)time(0));apx = rand()%(mapx-2);apy2 = apx;apy = (apy*apy2)%(mapy-2);apx2 = apy;//cout<<apx<<" "<<apy;if(apx*apy==0){apx++;apy++;}}
int zt()//暂停
{int p;while(1){if (p = _kbhit()){p = _getch();}if(p == 113){return 0;}Sleep(100);}
}
//____________________________________________________________________________int snlong_old = snlong;//snlong记录蛇长
int main()
{//_______________________________________________________________________map_cz();//加载地图for(int i = 0;i < snlong;i++)//绘制初始蛇{snmap[head_y][head_x+i] = snword;snnum[head_y][head_x+i] = i+1;}int jd = 65,jdnum = 0;//________________________________________________________________while(1)//主循环{apple_xy();//更新苹果xy坐标if(appleflag == 0)//如果苹果不存在,更新苹果{if(snmap[apy][apx] != snword){snmap[apy][apx] = apple;Sleep(10);if(snmap[apy][apx] == apple)appleflag = 1;//设置苹果状态为存在}}snnum[head_y][head_x] = num;num++;snlong_old = snlong;map_output();if (jd = _kbhit()){jd = _getch();}//更新头部方向if(jd == 97) jdnum = 0;if(jd == 119) jdnum = 1;if(jd == 100) jdnum = 2;if(jd == 115) jdnum = 3;if(jd == 113) zt();//暂停//更新头部if(jdnum == 0) head_x--;if(jdnum == 1) head_y--;if(jdnum == 2) head_x++;if(jdnum == 3) head_y++;//更新头部snmap[head_y][head_x] = snword;if(snmap[head_y][head_x] == apple){appleflag = 0;snlong++;}//死亡判定if(snmap[head_y][head_x] == snword||snmap[head_y][head_x] == killword){Sleep(1000);return 0;}if(snlong == snlong_old)//长度没有增加,更新尾部{snmap[tall_y][tall_x] = mapword;snnum[tall_y][tall_x] = 0;int min = 2137384637,minx,miny;for(int y = tall_y-1;y < tall_y+2;y++)//寻找新的尾部{for(int x = tall_x-1;x < tall_x+2;x++){if(snnum[y][x] < min&&snnum[y][x] != 0){min = snnum[y][x];minx = x,miny = y;}}}tall_y = miny;tall_x = minx;}system("cls");}return 0;
}

这是反复清屏导致的,我们可以加入双缓冲技术。(懂得都懂)


//这是开头
HANDLE hOutput, hOutBuf;//控制台屏幕缓冲区句柄
COORD coord = { 0,0 };
//双缓冲处理显示
DWORD bytes = 0;int main()
{
//创建新的控制台缓冲区hOutBuf = CreateConsoleScreenBuffer(GENERIC_WRITE,//定义进程可以往缓冲区写数据FILE_SHARE_WRITE,//定义缓冲区可共享写权限NULL,CONSOLE_TEXTMODE_BUFFER,NULL);hOutput = CreateConsoleScreenBuffer(GENERIC_WRITE,//定义进程可以往缓冲区写数据FILE_SHARE_WRITE,//定义缓冲区可共享写权限NULL,CONSOLE_TEXTMODE_BUFFER,NULL);//隐藏两个缓冲区的光标CONSOLE_CURSOR_INFO cci;cci.bVisible = 0;cci.dwSize = 1;SetConsoleCursorInfo(hOutput, &cci);SetConsoleCursorInfo(hOutBuf, &cci);int map_output()//更新地图显示的函数也该改一改
{/*for(int i = 0;i < mapy;i++){for(int j = 0;j < mapx;j++){printf( "%c",snmap[i][j]);}printf("\n");}*/
if(showflag == 0)
{for (int i = 0; i <= mapy; i++){coord.Y = i;WriteConsoleOutputCharacterA(hOutBuf, snmap[i],mapx, coord, &bytes);}showflag = 1;SetConsoleActiveScreenBuffer(hOutBuf);
}
else
{for (int i = 0; i <= mapy; i++){coord.Y = i;WriteConsoleOutputCharacterA(hOutput, snmap[i],mapx, coord, &bytes);}//设置新的缓冲区为活动显示缓冲SetConsoleActiveScreenBuffer(hOutput);showflag = 0;
}
Sleep(sd);
}

最后就完成了

#include<bits/stdc++.h>
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include <conio.h>
#include "stdio.h"
#include "stdlib.h"
using namespace std;
HANDLE hOutput, hOutBuf;//控制台屏幕缓冲区句柄
COORD coord = { 0,0 };
//双缓冲处理显示
DWORD bytes = 0;//初始数据部分
const int mapy = 20,mapx = 40;//地图尺寸
int snlong =3,sd = 200;//初始长度
const char snword = 'O',mapword = ' ',apple = '@',killword = '#';//地图元素
//变量部分
int head_y = 5,head_x = 10,tall_y = head_y,tall_x = head_x+snlong;//头尾坐标
int snnum[mapy][mapx],num = 4;//snmap地图数组
char snmap[mapy+1][mapx];
int apx = 6,apy = 3,appleflag = 0;//关于苹果的变量
int apx2 = 4,apy2 = 9;
int showflag = 0;int map_cz()//初始化地图数据
{for(int i = 1;i < mapy;i++)//填充地图{for(int j = 0;j < mapx;j++){snmap[i][j] = mapword;//}}for(int j = 0;j < mapx;j++) snmap[0][j] = killword;//这四行是设置地图边缘for(int j = 0;j < mapx;j++) snmap[mapy-1][j] = killword;for(int i = 0;i < mapy;i++) snmap[i][0] = killword;for(int i = 0;i < mapy;i++) snmap[i][mapx-1] = killword;}
int map_output()//更新地图显示
{/*for(int i = 0;i < mapy;i++){for(int j = 0;j < mapx;j++){printf( "%c",snmap[i][j]);}printf("\n");}*/
if(showflag == 0)
{for (int i = 0; i <= mapy; i++){coord.Y = i;WriteConsoleOutputCharacterA(hOutBuf, snmap[i],mapx, coord, &bytes);}showflag = 1;SetConsoleActiveScreenBuffer(hOutBuf);
}
else
{for (int i = 0; i <= mapy; i++){coord.Y = i;WriteConsoleOutputCharacterA(hOutput, snmap[i],mapx, coord, &bytes);}//设置新的缓冲区为活动显示缓冲SetConsoleActiveScreenBuffer(hOutput);showflag = 0;
}
Sleep(sd);
}
int num_output()//调试nummap数组
{for(int i = 0;i < mapy;i++){for(int j = 0;j < mapx;j++){printf( "%d",snnum[i][j]);}printf("\n");}
}
int apple_xy()//随机生成苹果位置
{srand((int)time(0));apx = rand()%(mapx-2);apy2 = apx;apy = (apy*apy2)%(mapy-2);apx2 = apy;//cout<<apx<<" "<<apy;if(apx*apy==0){apx++;apy++;}}
int zt()//暂停
{int p;while(1){if (p = _kbhit()){p = _getch();}if(p == 113){return 0;}Sleep(100);}
}
//____________________________________________________________________________int snlong_old = snlong;//snlong记录蛇长
int main()
{
//创建新的控制台缓冲区hOutBuf = CreateConsoleScreenBuffer(GENERIC_WRITE,//定义进程可以往缓冲区写数据FILE_SHARE_WRITE,//定义缓冲区可共享写权限NULL,CONSOLE_TEXTMODE_BUFFER,NULL);hOutput = CreateConsoleScreenBuffer(GENERIC_WRITE,//定义进程可以往缓冲区写数据FILE_SHARE_WRITE,//定义缓冲区可共享写权限NULL,CONSOLE_TEXTMODE_BUFFER,NULL);//隐藏两个缓冲区的光标CONSOLE_CURSOR_INFO cci;cci.bVisible = 0;cci.dwSize = 1;SetConsoleCursorInfo(hOutput, &cci);SetConsoleCursorInfo(hOutBuf, &cci);//_______________________________________________________________________map_cz();//加载地图for(int i = 0;i < snlong;i++)//绘制初始蛇{snmap[head_y][head_x+i] = snword;snnum[head_y][head_x+i] = i+1;}int jd = 65,jdnum = 0;//________________________________________________________________while(1)//主循环{apple_xy();//更新苹果xy坐标if(appleflag == 0)//如果苹果不存在,更新苹果{if(snmap[apy][apx] != snword){snmap[apy][apx] = apple;Sleep(10);if(snmap[apy][apx] == apple)appleflag = 1;//设置苹果状态为存在}}snnum[head_y][head_x] = num;num++;snlong_old = snlong;map_output();if (jd = _kbhit()){jd = _getch();}//更新头部方向if(jd == 97) jdnum = 0;if(jd == 119) jdnum = 1;if(jd == 100) jdnum = 2;if(jd == 115) jdnum = 3;if(jd == 113) zt();//暂停//更新头部if(jdnum == 0) head_x--;if(jdnum == 1) head_y--;if(jdnum == 2) head_x++;if(jdnum == 3) head_y++;if(snmap[head_y][head_x] == apple){appleflag = 0;snlong++;}//死亡判定if(snmap[head_y][head_x] == snword||snmap[head_y][head_x] == killword){Sleep(1000);return 0;}//更新头部snmap[head_y][head_x] = snword;if(snlong == snlong_old)//长度没有增加,更新尾部{snmap[tall_y][tall_x] = mapword;snnum[tall_y][tall_x] = 0;int min = 2137384637,minx,miny;for(int y = tall_y-1;y < tall_y+2;y++)//寻找新的尾部{for(int x = tall_x-1;x < tall_x+2;x++){if(snnum[y][x] < min&&snnum[y][x] != 0){min = snnum[y][x];minx = x,miny = y;}}}tall_y = miny;tall_x = minx;}}return 0;
}

代码比较简陋,有什么不足欢迎指正。

在家用c++实现贪吃蛇——c++小游戏相关推荐

  1. 用前端技术实现贪吃蛇的小游戏

    用前端技术实现贪吃蛇的小游戏 前言 游戏功能 游戏设计 游戏主页代码 游戏中的js代码(snake.js) 游戏运行界面 前言 周末大热天窝在家里无聊,想温习一下前端开发,所以用javascript ...

  2. 贪食蛇php,贪吃蛇网页小游戏的代码

    贪吃蛇网页小游戏的代码 ::selection { color:#FFFFFF; background:transparent; } ::-moz-selection { color:#FFFFFF; ...

  3. 隐藏窗口 java swing_Java简单实现贪吃蛇经典小游戏(附源代码)

    在我们学习java的时候,为了提高我们的兴趣,我们经常会使用所学到的知识去做一些小游戏,这篇blog就介绍了一个经典而且好理解的小游戏-贪吃蛇. 一.使用知识 Jframe GUI 双向链表 线程 二 ...

  4. 贪吃蛇html网页小游戏,网页贪吃蛇HTML5小游戏制作

    贪吃蛇是以前我们经常在手机里玩的一个小游戏,现在要是把它搬到网页上也会让人更回味.这是一款非常有趣的HTML5响应式网页贪吃蛇小游戏.在游戏中你可以使用键盘的上下左右来控制蛇的运动方向.现在要列出的是 ...

  5. 最终幻想游戏java_Java简单实现贪吃蛇经典小游戏(附源代码)

    在我们学习java的时候,为了提高我们的兴趣,我们经常会使用所学到的知识去做一些小游戏,这篇blog就介绍了一个经典而且好理解的小游戏-贪吃蛇. 一.使用知识Jframe GUI 双向链表 线程 二. ...

  6. 100行实现《贪吃蛇》小游戏详解(Qt)

    目录 游戏说明 游戏效果展示 游戏代码详解 ​关键数据结构 初始化游戏界面 游戏部分 提示部分 蛇逻辑 小蛇的初始化 边界判断 蛇吃食物判断 随机生成食物 是否撞到自己 小蛇的移动 游戏主体逻辑 定时 ...

  7. javaswing 贪吃蛇双人小游戏

    游戏截图 代码 Java14写的哦低版本会报错 文件列表 package Sys;import javax.swing.*; import java.awt.*; import java.awt.ev ...

  8. html5小游戏 typescript,使用TypeScript和Canvas编写移动端贪吃蛇大作战游戏

    基本介绍 一款移动端贪吃蛇大作战游戏.(只支持移动端) 这是一个临近 deadline 的课设项目,为了方便地使用TS,我直接使用angular-cli生成了TypeScript的项目结构.如果你有好 ...

  9. 贪吃蛇c语言 游戏中会出现障碍物,贪吃蛇C语言游戏代码.doc

    贪吃蛇C语言游戏代码 //开始编写游戏需要的类 #include //EasyX_2011惊蛰版(绘图库) #include #include #include #define UP1 #define ...

最新文章

  1. controller接收json数据_答疑 | 前后端分离,如何接收json数据?
  2. 网站HTML删除数据库中数据语句,如何以编程方式删除WebSQL中的数据库?
  3. 结合案例深入解析:抽象工厂模式
  4. matlab句柄函数@和C++ 中的引用 很像
  5. 轻松学PHP编程 源代码
  6. leetcode1277. 统计全为 1 的正方形子矩阵(dp)
  7. 挑战10个最难的Java面试题(附答案)【上】
  8. 电信5g网络apn接入点_华为就5G网络设备禁令起诉瑞典邮政和电信管理局
  9. ‘mvn‘ 不是内部或外部命令,也不是可运行的程序
  10. 62 岁的比尔·盖茨当选外籍院士,但却与微软无关
  11. #敏捷个人# 每日认识101(15):成为一个有执行力的人
  12. JAVA Useful Program(1)
  13. GDP代码学习——GUX
  14. Navicat Premium15安装与激活(完整激活版)
  15. 趣味记忆5大经典的软件架构风格
  16. 【人工智能项目】LSTM实现数据预测分类实验
  17. vue操作easyui中的DataGrid
  18. 杰伦的《不能说的秘密》の细节 (详解)
  19. python io多路复用_【python】-- IO多路复用(select、poll、epoll)介绍及实现
  20. uniapp swiper 添加视频

热门文章

  1. edge查看浏览器保存密码
  2. vscode透明背景以及背景图片设置
  3. Mann-Whitney非参数多组比较R计算方法
  4. 纯PHP获取微信用户OPENID
  5. php设置curl gzip,curl配置CURLOPT_ENCODING选项解压缩gzip文件响应
  6. MSChart使用之动态生成多个多行ChartArea
  7. 达梦数据库喜中国家电网公司信息化软件框架采购竞争性谈判项目
  8. SystemUI 悬浮通知
  9. 神经网络的持续终身学习综述论文
  10. 目前人流量检测遇到的难点