c++贪吃蛇源代码 完整版

c++ 实现贪吃蛇, 完整源码

0.非常重要的注意事项

请注意:
1.这是c++代码,请建立.cpp文件而不是.c文件,然后将代码拷贝进去,再使用c++编译器进行编译运行。

2.因为使用了一些c++11标准当中的语法,所以c++编译器的编译标准至少需要设置到c++11以上,不然会报错。编译标准可以在你的IDE里设置,或者使用命令行编译时附加-std=c++11选项。

3.代码中使用了getch()函数,用于无回显的接收用户输入;使用了kbhit()函数用于判断用户是否按下键盘。但是如果你在visual studio中直接运行本代码可能会报错,你可以将上述两个函数替换为_getch()函数和_kbhit()函数就可以了。

1.数据结构分析:

这里我采用双向队列的数据结构存储蛇身节点,目的是:方便,减少屏闪。并且双向队列也能更好的体现贪吃蛇本身的特点。有利于实现,且效率也较高。

2.程序运行分析

程序开始用户随机按下w,a,s,d中任意按键开始游戏并且作为蛇运动的初始方向(如果刚开始觉得蛇的运动速度太慢可以键入’v’使变为当前运行素的1.25倍速,键入’b’则会使之变为当前速度的2/3倍速),然后进入循环持续游戏直到游戏结束,显示分数之后用户输入任意按键退出游戏。

3.难点分析

1.蛇移动怎么显示?

这也就是我采用双向队列的原因,蛇每运动一步,就从双向队列中弹出队尾,然后将新的队首(即蛇头)压入队列首部,然后再清除蛇尾打印蛇身即可,不需要对贪吃蛇全部进行清楚以及打印,可以极大的减少程序运行过程中出现的闪烁现象。如果吃到食物那么本次运动就会在将蛇尾变为蛇头的同时再加入一个蛇身达到使蛇身长度加一的目的(我认为双向队列更能从本质上体现贪吃蛇本来的特点,而每次弹出队尾,加入队首而不对中间的蛇身进行改变也使程序变得更加简洁,运行更流畅)

2.怎么控制吃到食物后蛇的速度的变化?

最开始我设置初始速度为1000(即:Sleep()函数的参数为1000)每次吃到食物就将速度乘以0.8以此达到加速的目的。但我发现到后面速度越来越快没有上限,根本无法控制。
解法:设置一个上限为MaxSpeed,则速度为 MaxSpeed + Index,MaxSpeed 保持不变且较小作为蛇速度的渐进上限,每次乘以0.8(可自定义)则乘到Index上面,这样的话速度就不会无限制的上升。

3.怎么解决屏幕闪烁?

解:不要使用system(“cls”);清屏函数,使用函数SetConsoleCursorPosition控制光标填充空格进行覆盖能大大减少屏闪问题!!这一点要注意了!

4.一些废话

1.首先肯定是存储蛇身的数据结构方面,有很多种选择:链表,双向队列,循环队列,vector甚至数组都可以用来存储蛇身。
2.最开始以为这个比较简单…上手就开始写写废了一次,提醒大家在写程序(特别是这种结构比较复杂且步骤较多的程序)时一定要先进行规划,想清楚要使用的数据结构以及构建方式,想清楚再写,避免浪费时间。

5.源代码

下面是源代码,还需要什么功能大家可以在此基础上进行改动。

#include<iostream>
#include<windows.h>
#include<conio.h>
#include<deque>
#include<ctime>
#include<stdexcept>
using namespace std;

struct Snake {
    //蛇类结构体
    char image;
    short x, y; //坐标
};

class snakeGame {
   
	public:
	snakeGame();
	void printMap();
	// 控制光标移动
	void gotoxy(short x, short y) {
   
		hOut = GetStdHandle(STD_OUTPUT_HANDLE); //获取句柄
		pos = {
   x, y};
		SetConsoleCursorPosition(hOut, pos); //移动光标
	}
	//隐藏光标
	void HideCursor()
	{
   
		HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
		CONSOLE_CURSOR_INFO CursorInfo;
		GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息
		CursorInfo.bVisible = false; //隐藏控制台光标
		SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态
	}
	// 初始化蛇身,可根据需要更改初始长度
	void initSnake() {
   
		snake.push_front({
   '@', width / 2, height / 2});
		for (int i=0; i<2;++i)
			snake.push_back({
   '+', width/2,static_cast<short>
以下是C++贪吃蛇撞墙代码的实现: 引用中的p_wall()函数可以用来绘制墙壁,可以在主函数中调用该函数来绘制墙壁。在move()函数中,可以通过判断蛇头的位置是否超出边界来判断是否撞墙,如果超出边界则游戏结束。 具体实现代码如下: ``` const int COLS = 30; // 游戏区域列数 const int ROWS = 20; // 游戏区域行数 const char WALL = '#'; // 墙壁字符 const char S_HEAD = '@'; // 蛇头字符 const char S_BODY = '*'; // 蛇身字符 void p_wall() // 绘制墙壁 { for (int i = 0; i < COLS + 2; i++) { cout << WALL; } cout << endl; for (int i = 0; i < ROWS; i++) { cout << WALL; for (int j = 0; j < COLS; j++) { cout << ' '; } cout << WALL << endl; } for (int i = 0; i < COLS + 2; i++) { cout << WALL; } cout << endl; } bool isPosInSnake(int x, int y, int snake[COLS * ROWS][2], int len) // 判断坐标是否在蛇身上 { for (int i = 0; i < len; i++) { if (snake[i][0] == x && snake[i][1] == y) { return true; } } return false; } void p_snake(int snake[COLS * ROWS][2], int len) // 绘制蛇 { for (int i = 0; i < len; i++) { if (i == 0) // 绘制蛇头 { locate(snake[i][0], snake[i][1]); cout << S_HEAD; } else // 绘制蛇身 { locate(snake[i][0], snake[i][1]); cout << S_BODY; } } } void p_food(int x, int y) // 绘制食物 { locate(x, y); cout << '$'; } int move(int snake[COLS * ROWS][2], char ch, int len) // 移动蛇 { int dx = 0, dy = 0; switch (ch) { case 'w': // 上 dy = -1; break; case 's': // 下 dy = 1; break; case 'a': // 左 dx = -1; break; case 'd': // 右 dx = 1; break; } int hx = snake[0][0] + dx; int hy = snake[0][1] + dy; if (hx < 1 || hx > COLS || hy < 1 || hy > ROWS || isPosInSnake(hx, hy, snake, len)) // 判断是否撞墙或撞到自己 { return -1; // 游戏结束 } for (int i = len - 1; i > 0; i--) // 移动蛇身 { snake[i][0] = snake[i - 1][0]; snake[i][1] = snake[i - 1][1]; } snake[0][0] = hx; snake[0][1] = hy; return 0; // 游戏继续 } int main() { int snake[COLS * ROWS][2]; // 蛇身坐标数组 int len = 3; // 蛇身长度 snake[0][0] = COLS / 2; // 蛇头初始位置 snake[0][1] = ROWS / 2; snake[1][0] = snake[0][0] - 1; // 蛇身初始位置 snake[1][1] = snake[0][1]; snake[2][0] = snake[1][0] - 1; snake[2][1] = snake[1][1]; char ch = 'd'; // 蛇头初始方向 p_wall(); // 绘制墙壁 p_snake(snake, len); // 绘制蛇 while (true) { if (_kbhit()) // 检测键盘输入 { ch = _getch(); } int ret = move(snake, ch, len); // 移动蛇 if (ret == -1) // 游戏结束 { break; } Sleep(100); // 延时 } return 0; } --相关问题--:
评论 78
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值